ELF: Have __rela_iplt_{start,end} surround .rela.iplt with --pack-dyn-relocs=android.
[llvm-project.git] / llvm / test / Transforms / InstCombine / fpclass-from-dom-cond.ll
blob141b44cbbb7a1f862ee698859aa600cc94f37d71
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
4 define i1 @test1(float %x) {
5 ; CHECK-LABEL: define i1 @test1(
6 ; CHECK-SAME: float [[X:%.*]]) {
7 ; CHECK-NEXT:  entry:
8 ; CHECK-NEXT:    [[COND:%.*]] = fcmp ueq float [[X]], 0.000000e+00
9 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
10 ; CHECK:       if.then:
11 ; CHECK-NEXT:    ret i1 false
12 ; CHECK:       if.else:
13 ; CHECK-NEXT:    [[RET:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 780)
14 ; CHECK-NEXT:    ret i1 [[RET]]
16 entry:
17   %cond = fcmp ueq float %x, 0.000000e+00
18   br i1 %cond, label %if.then, label %if.else
20 if.then:
21   ret i1 false
23 if.else:
24   %ret = call i1 @llvm.is.fpclass.f32(float %x, i32 783)
25   ret i1 %ret
28 define i1 @test2(double %x) {
29 ; CHECK-LABEL: define i1 @test2(
30 ; CHECK-SAME: double [[X:%.*]]) {
31 ; CHECK-NEXT:  entry:
32 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt double [[X]], 0x3EB0C6F7A0000000
33 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
34 ; CHECK:       if.then:
35 ; CHECK-NEXT:    ret i1 false
36 ; CHECK:       if.end:
37 ; CHECK-NEXT:    ret i1 false
39 entry:
40   %cmp = fcmp olt double %x, 0x3EB0C6F7A0000000
41   br i1 %cmp, label %if.then, label %if.end
42 if.then:
43   ret i1 false
44 if.end:
45   %cmp.i = fcmp oeq double %x, 0.000000e+00
46   ret i1 %cmp.i
49 define i1 @test2_or(double %x, i1 %cond) {
50 ; CHECK-LABEL: define i1 @test2_or(
51 ; CHECK-SAME: double [[X:%.*]], i1 [[COND:%.*]]) {
52 ; CHECK-NEXT:  entry:
53 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt double [[X]], 0x3EB0C6F7A0000000
54 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP]], [[COND]]
55 ; CHECK-NEXT:    br i1 [[OR]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
56 ; CHECK:       if.then:
57 ; CHECK-NEXT:    ret i1 false
58 ; CHECK:       if.end:
59 ; CHECK-NEXT:    ret i1 false
61 entry:
62   %cmp = fcmp olt double %x, 0x3EB0C6F7A0000000
63   %or = or i1 %cmp, %cond
64   br i1 %or, label %if.then, label %if.end
66 if.then:
67   ret i1 false
69 if.end:
70   %cmp.i = fcmp oeq double %x, 0.000000e+00
71   ret i1 %cmp.i
74 define i1 @test3(float %x) {
75 ; CHECK-LABEL: define i1 @test3(
76 ; CHECK-SAME: float [[X:%.*]]) {
77 ; CHECK-NEXT:  entry:
78 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[X]], 3.000000e+00
79 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
80 ; CHECK:       if.then:
81 ; CHECK-NEXT:    [[RET:%.*]] = fcmp oeq float [[X]], 0x7FF0000000000000
82 ; CHECK-NEXT:    ret i1 [[RET]]
83 ; CHECK:       if.else:
84 ; CHECK-NEXT:    ret i1 false
86 entry:
87   %cmp = fcmp ogt float %x, 3.000000e+00
88   br i1 %cmp, label %if.then, label %if.else
89 if.then:
90   %abs = call float @llvm.fabs.f32(float %x)
91   %ret = fcmp oeq float %abs, 0x7FF0000000000000
92   ret i1 %ret
93 if.else:
94   ret i1 false
97 define float @test4(float %x) {
98 ; CHECK-LABEL: define float @test4(
99 ; CHECK-SAME: float [[X:%.*]]) {
100 ; CHECK-NEXT:  entry:
101 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[X]], 0x3EB0C6F7A0000000
102 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
103 ; CHECK:       if.then:
104 ; CHECK-NEXT:    ret float 1.000000e+00
105 ; CHECK:       if.end:
106 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[X]]
107 ; CHECK-NEXT:    ret float [[DIV]]
109 entry:
110   %cmp = fcmp olt float %x, 0x3EB0C6F7A0000000
111   br i1 %cmp, label %if.then, label %if.end
113 if.then:
114   ret float 1.0
116 if.end:
117   %cmp.i = fcmp oeq float %x, 0.000000e+00
118   %div = fdiv float 1.000000e+00, %x
119   %ret = select i1 %cmp.i, float 1.000000e+00, float %div
120   ret float %ret
123 define i1 @test5(double %x, i1 %cond) {
124 ; CHECK-LABEL: define i1 @test5(
125 ; CHECK-SAME: double [[X:%.*]], i1 [[COND:%.*]]) {
126 ; CHECK-NEXT:  entry:
127 ; CHECK-NEXT:    br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
128 ; CHECK:       if:
129 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno double [[X]], 0.000000e+00
130 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
131 ; CHECK:       if.then:
132 ; CHECK-NEXT:    ret i1 false
133 ; CHECK:       if.end:
134 ; CHECK-NEXT:    br label [[EXIT]]
135 ; CHECK:       exit:
136 ; CHECK-NEXT:    [[Y:%.*]] = phi double [ -1.000000e+00, [[ENTRY:%.*]] ], [ [[X]], [[IF_END]] ]
137 ; CHECK-NEXT:    [[RET:%.*]] = tail call i1 @llvm.is.fpclass.f64(double [[Y]], i32 408)
138 ; CHECK-NEXT:    ret i1 [[RET]]
140 entry:
141   br i1 %cond, label %if, label %exit
143   %cmp = fcmp uno double %x, 0.000000e+00
144   br i1 %cmp, label %if.then, label %if.end
145 if.then:
146   ret i1 false
147 if.end:
148   br label %exit
149 exit:
150   %y = phi double [ -1.000000e+00, %entry ], [ %x, %if.end ]
151   %ret = tail call i1 @llvm.is.fpclass.f64(double %y, i32 411)
152   ret i1 %ret
155 define i1 @test6(double %x) {
156 ; CHECK-LABEL: define i1 @test6(
157 ; CHECK-SAME: double [[X:%.*]]) {
158 ; CHECK-NEXT:  entry:
159 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[X]], 0.000000e+00
160 ; CHECK-NEXT:    br i1 [[CMP]], label [[LAND_RHS:%.*]], label [[LAND_END:%.*]]
161 ; CHECK:       land.rhs:
162 ; CHECK-NEXT:    [[CMP_I:%.*]] = fcmp oeq double [[X]], 0x7FF0000000000000
163 ; CHECK-NEXT:    br label [[LAND_END]]
164 ; CHECK:       land.end:
165 ; CHECK-NEXT:    [[RET:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP_I]], [[LAND_RHS]] ]
166 ; CHECK-NEXT:    ret i1 [[RET]]
168 entry:
169   %cmp = fcmp ogt double %x, 0.000000e+00
170   br i1 %cmp, label %land.rhs, label %land.end
172 land.rhs:
173   %abs = tail call double @llvm.fabs.f64(double %x)
174   %and.i = bitcast double %abs to i64
175   %cmp.i = icmp eq i64 %and.i, 9218868437227405312
176   br label %land.end
178 land.end:
179   %ret = phi i1 [ false, %entry ], [ %cmp.i, %land.rhs ]
180   ret i1 %ret
183 define i1 @test7(float %x) {
184 ; CHECK-LABEL: define i1 @test7(
185 ; CHECK-SAME: float [[X:%.*]]) {
186 ; CHECK-NEXT:    [[COND:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 345)
187 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
188 ; CHECK:       if.then:
189 ; CHECK-NEXT:    [[RET1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 328)
190 ; CHECK-NEXT:    ret i1 [[RET1]]
191 ; CHECK:       if.else:
192 ; CHECK-NEXT:    [[RET2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 128)
193 ; CHECK-NEXT:    ret i1 [[RET2]]
195   %cond = call i1 @llvm.is.fpclass.f32(float %x, i32 345)
196   br i1 %cond, label %if.then, label %if.else
197 if.then:
198   %ret1 = call i1 @llvm.is.fpclass.f32(float %x, i32 456)
199   ret i1 %ret1
200 if.else:
201   %ret2 = call i1 @llvm.is.fpclass.f32(float %x, i32 456)
202   ret i1 %ret2
205 ; TODO: These two is.fpclass can be simplified.
206 define i1 @test8(float %x) {
207 ; CHECK-LABEL: define i1 @test8(
208 ; CHECK-SAME: float [[X:%.*]]) {
209 ; CHECK-NEXT:    [[ABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
210 ; CHECK-NEXT:    [[COND:%.*]] = fcmp oeq float [[ABS]], 0x7FF0000000000000
211 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
212 ; CHECK:       if.then:
213 ; CHECK-NEXT:    ret i1 true
214 ; CHECK:       if.else:
215 ; CHECK-NEXT:    [[RET2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 59)
216 ; CHECK-NEXT:    ret i1 [[RET2]]
218   %abs = call float @llvm.fabs.f32(float %x)
219   %cond = fcmp oeq float %abs, 0x7FF0000000000000
220   br i1 %cond, label %if.then, label %if.else
221 if.then:
222   %ret1 = call i1 @llvm.is.fpclass.f32(float %x, i32 575)
223   ret i1 %ret1
224 if.else:
225   %ret2 = call i1 @llvm.is.fpclass.f32(float %x, i32 575)
226   ret i1 %ret2
229 define i1 @test9(float %x) {
230 ; CHECK-LABEL: define i1 @test9(
231 ; CHECK-SAME: float [[X:%.*]]) {
232 ; CHECK-NEXT:    [[COND:%.*]] = fcmp olt float [[X]], -1.000000e+00
233 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
234 ; CHECK:       if.then:
235 ; CHECK-NEXT:    ret i1 false
236 ; CHECK:       if.else:
237 ; CHECK-NEXT:    ret i1 false
239   %cond = fcmp olt float %x, -1.0
240   br i1 %cond, label %if.then, label %if.else
241 if.then:
242   %ret1 = fcmp oeq float %x, 0x7FF0000000000000
243   ret i1 %ret1
244 if.else:
245   ret i1 false
248 define i1 @test10(float %x) {
249 ; CHECK-LABEL: define i1 @test10(
250 ; CHECK-SAME: float [[X:%.*]]) {
251 ; CHECK-NEXT:    [[COND:%.*]] = fcmp olt float [[X]], -1.000000e+00
252 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
253 ; CHECK:       if.then:
254 ; CHECK-NEXT:    ret i1 false
255 ; CHECK:       if.else:
256 ; CHECK-NEXT:    ret i1 false
258   %cond = fcmp olt float %x, -1.0
259   %neg = fneg float %x
260   br i1 %cond, label %if.then, label %if.else
261 if.then:
262   %ret1 = fcmp oeq float %neg, 0xFFF0000000000000
263   ret i1 %ret1
264 if.else:
265   ret i1 false
268 define i1 @test11_and(float %x, i1 %cond2) {
269 ; CHECK-LABEL: define i1 @test11_and(
270 ; CHECK-SAME: float [[X:%.*]], i1 [[COND2:%.*]]) {
271 ; CHECK-NEXT:    [[COND:%.*]] = fcmp olt float [[X]], -1.000000e+00
272 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[COND]], [[COND2]]
273 ; CHECK-NEXT:    br i1 [[AND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
274 ; CHECK:       if.then:
275 ; CHECK-NEXT:    ret i1 false
276 ; CHECK:       if.else:
277 ; CHECK-NEXT:    ret i1 false
279   %cond = fcmp olt float %x, -1.0
280   %neg = fneg float %x
281   %and = and i1 %cond, %cond2
282   br i1 %and, label %if.then, label %if.else
283 if.then:
284   %ret1 = fcmp oeq float %neg, 0xFFF0000000000000
285   ret i1 %ret1
286 if.else:
287   ret i1 false
290 define i1 @test12_or(float %x, i1 %cond2) {
291 ; CHECK-LABEL: define i1 @test12_or(
292 ; CHECK-SAME: float [[X:%.*]], i1 [[COND2:%.*]]) {
293 ; CHECK-NEXT:  entry:
294 ; CHECK-NEXT:    [[COND:%.*]] = fcmp ueq float [[X]], 0.000000e+00
295 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[COND]], [[COND2]]
296 ; CHECK-NEXT:    br i1 [[OR]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
297 ; CHECK:       if.then:
298 ; CHECK-NEXT:    ret i1 false
299 ; CHECK:       if.else:
300 ; CHECK-NEXT:    [[RET:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 780)
301 ; CHECK-NEXT:    ret i1 [[RET]]
303 entry:
304   %cond = fcmp ueq float %x, 0.000000e+00
305   %or = or i1 %cond, %cond2
306   br i1 %or, label %if.then, label %if.else
308 if.then:
309   ret i1 false
311 if.else:
312   %ret = call i1 @llvm.is.fpclass.f32(float %x, i32 783)
313   ret i1 %ret
316 define i1 @test1_no_dominating(float %x, i1 %c) {
317 ; CHECK-LABEL: define i1 @test1_no_dominating(
318 ; CHECK-SAME: float [[X:%.*]], i1 [[C:%.*]]) {
319 ; CHECK-NEXT:  entry0:
320 ; CHECK-NEXT:    br i1 [[C]], label [[ENTRY:%.*]], label [[IF_ELSE:%.*]]
321 ; CHECK:       entry:
322 ; CHECK-NEXT:    [[COND:%.*]] = fcmp ueq float [[X]], 0.000000e+00
323 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE]]
324 ; CHECK:       if.then:
325 ; CHECK-NEXT:    ret i1 false
326 ; CHECK:       if.else:
327 ; CHECK-NEXT:    [[RET:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 783)
328 ; CHECK-NEXT:    ret i1 [[RET]]
330 entry0:
331   br i1 %c, label %entry, label %if.else
333 entry:
334   %cond = fcmp ueq float %x, 0.000000e+00
335   br i1 %cond, label %if.then, label %if.else
337 if.then:
338   ret i1 false
340 if.else:
341   %ret = call i1 @llvm.is.fpclass.f32(float %x, i32 783)
342   ret i1 %ret
345 define float @test_signbit_check(float %x, i1 %cond) {
346 ; CHECK-LABEL: define float @test_signbit_check(
347 ; CHECK-SAME: float [[X:%.*]], i1 [[COND:%.*]]) {
348 ; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[X]] to i32
349 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I32]], 0
350 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_ELSE:%.*]]
351 ; CHECK:       if.then1:
352 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
353 ; CHECK-NEXT:    br label [[IF_END:%.*]]
354 ; CHECK:       if.else:
355 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN2:%.*]], label [[IF_END]]
356 ; CHECK:       if.then2:
357 ; CHECK-NEXT:    br label [[IF_END]]
358 ; CHECK:       if.end:
359 ; CHECK-NEXT:    [[VALUE:%.*]] = phi float [ [[FNEG]], [[IF_THEN1]] ], [ [[X]], [[IF_THEN2]] ], [ [[X]], [[IF_ELSE]] ]
360 ; CHECK-NEXT:    ret float [[VALUE]]
362   %i32 = bitcast float %x to i32
363   %cmp = icmp slt i32 %i32, 0
364   br i1 %cmp, label %if.then1, label %if.else
366 if.then1:
367   %fneg = fneg float %x
368   br label %if.end
370 if.else:
371   br i1 %cond, label %if.then2, label %if.end
373 if.then2:
374   br label %if.end
376 if.end:
377   %value = phi float [ %fneg, %if.then1 ], [ %x, %if.then2 ], [ %x, %if.else ]
378   %ret = call float @llvm.fabs.f32(float %value)
379   ret float %ret
382 define float @test_signbit_check_fail(float %x, i1 %cond) {
383 ; CHECK-LABEL: define float @test_signbit_check_fail(
384 ; CHECK-SAME: float [[X:%.*]], i1 [[COND:%.*]]) {
385 ; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[X]] to i32
386 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I32]], 0
387 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_ELSE:%.*]]
388 ; CHECK:       if.then1:
389 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
390 ; CHECK-NEXT:    br label [[IF_END:%.*]]
391 ; CHECK:       if.else:
392 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN2:%.*]], label [[IF_END]]
393 ; CHECK:       if.then2:
394 ; CHECK-NEXT:    [[FNEG2:%.*]] = fneg float [[X]]
395 ; CHECK-NEXT:    br label [[IF_END]]
396 ; CHECK:       if.end:
397 ; CHECK-NEXT:    [[VALUE:%.*]] = phi float [ [[FNEG]], [[IF_THEN1]] ], [ [[FNEG2]], [[IF_THEN2]] ], [ [[X]], [[IF_ELSE]] ]
398 ; CHECK-NEXT:    [[RET:%.*]] = call float @llvm.fabs.f32(float [[VALUE]])
399 ; CHECK-NEXT:    ret float [[RET]]
401   %i32 = bitcast float %x to i32
402   %cmp = icmp slt i32 %i32, 0
403   br i1 %cmp, label %if.then1, label %if.else
405 if.then1:
406   %fneg = fneg float %x
407   br label %if.end
409 if.else:
410   br i1 %cond, label %if.then2, label %if.end
412 if.then2:
413   %fneg2 = fneg float %x
414   br label %if.end
416 if.end:
417   %value = phi float [ %fneg, %if.then1 ], [ %fneg2, %if.then2 ], [ %x, %if.else ]
418   %ret = call float @llvm.fabs.f32(float %value)
419   ret float %ret
422 define <2 x float> @test_signbit_check_wrong_type(<2 x float> %x, i1 %cond) {
423 ; CHECK-LABEL: define <2 x float> @test_signbit_check_wrong_type(
424 ; CHECK-SAME: <2 x float> [[X:%.*]], i1 [[COND:%.*]]) {
425 ; CHECK-NEXT:    [[I32:%.*]] = bitcast <2 x float> [[X]] to i64
426 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[I32]], 0
427 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_ELSE:%.*]]
428 ; CHECK:       if.then1:
429 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg <2 x float> [[X]]
430 ; CHECK-NEXT:    br label [[IF_END:%.*]]
431 ; CHECK:       if.else:
432 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN2:%.*]], label [[IF_END]]
433 ; CHECK:       if.then2:
434 ; CHECK-NEXT:    br label [[IF_END]]
435 ; CHECK:       if.end:
436 ; CHECK-NEXT:    [[VALUE:%.*]] = phi <2 x float> [ [[FNEG]], [[IF_THEN1]] ], [ [[X]], [[IF_THEN2]] ], [ [[X]], [[IF_ELSE]] ]
437 ; CHECK-NEXT:    [[RET:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[VALUE]])
438 ; CHECK-NEXT:    ret <2 x float> [[RET]]
440   %i32 = bitcast <2 x float> %x to i64
441   %cmp = icmp slt i64 %i32, 0
442   br i1 %cmp, label %if.then1, label %if.else
444 if.then1:
445   %fneg = fneg <2 x float> %x
446   br label %if.end
448 if.else:
449   br i1 %cond, label %if.then2, label %if.end
451 if.then2:
452   br label %if.end
454 if.end:
455   %value = phi <2 x float> [ %fneg, %if.then1 ], [ %x, %if.then2 ], [ %x, %if.else ]
456   %ret = call <2 x float> @llvm.fabs.v2f32(<2 x float> %value)
457   ret <2 x float> %ret