Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstCombine / fpclass-from-dom-cond.ll
blobd6706d76056eeae5c8ba66a5c599b0ee3800f1c6
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 @test3(float %x) {
50 ; CHECK-LABEL: define i1 @test3(
51 ; CHECK-SAME: float [[X:%.*]]) {
52 ; CHECK-NEXT:  entry:
53 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[X]], 3.000000e+00
54 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
55 ; CHECK:       if.then:
56 ; CHECK-NEXT:    [[RET:%.*]] = fcmp oeq float [[X]], 0x7FF0000000000000
57 ; CHECK-NEXT:    ret i1 [[RET]]
58 ; CHECK:       if.else:
59 ; CHECK-NEXT:    ret i1 false
61 entry:
62   %cmp = fcmp ogt float %x, 3.000000e+00
63   br i1 %cmp, label %if.then, label %if.else
64 if.then:
65   %abs = call float @llvm.fabs.f32(float %x)
66   %ret = fcmp oeq float %abs, 0x7FF0000000000000
67   ret i1 %ret
68 if.else:
69   ret i1 false
72 define float @test4(float %x) {
73 ; CHECK-LABEL: define float @test4(
74 ; CHECK-SAME: float [[X:%.*]]) {
75 ; CHECK-NEXT:  entry:
76 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[X]], 0x3EB0C6F7A0000000
77 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
78 ; CHECK:       if.then:
79 ; CHECK-NEXT:    ret float 1.000000e+00
80 ; CHECK:       if.end:
81 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 1.000000e+00, [[X]]
82 ; CHECK-NEXT:    ret float [[DIV]]
84 entry:
85   %cmp = fcmp olt float %x, 0x3EB0C6F7A0000000
86   br i1 %cmp, label %if.then, label %if.end
88 if.then:
89   ret float 1.0
91 if.end:
92   %cmp.i = fcmp oeq float %x, 0.000000e+00
93   %div = fdiv float 1.000000e+00, %x
94   %ret = select i1 %cmp.i, float 1.000000e+00, float %div
95   ret float %ret
98 define i1 @test5(double %x, i1 %cond) {
99 ; CHECK-LABEL: define i1 @test5(
100 ; CHECK-SAME: double [[X:%.*]], i1 [[COND:%.*]]) {
101 ; CHECK-NEXT:  entry:
102 ; CHECK-NEXT:    br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
103 ; CHECK:       if:
104 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno double [[X]], 0.000000e+00
105 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
106 ; CHECK:       if.then:
107 ; CHECK-NEXT:    ret i1 false
108 ; CHECK:       if.end:
109 ; CHECK-NEXT:    br label [[EXIT]]
110 ; CHECK:       exit:
111 ; CHECK-NEXT:    [[Y:%.*]] = phi double [ -1.000000e+00, [[ENTRY:%.*]] ], [ [[X]], [[IF_END]] ]
112 ; CHECK-NEXT:    [[RET:%.*]] = tail call i1 @llvm.is.fpclass.f64(double [[Y]], i32 408)
113 ; CHECK-NEXT:    ret i1 [[RET]]
115 entry:
116   br i1 %cond, label %if, label %exit
118   %cmp = fcmp uno double %x, 0.000000e+00
119   br i1 %cmp, label %if.then, label %if.end
120 if.then:
121   ret i1 false
122 if.end:
123   br label %exit
124 exit:
125   %y = phi double [ -1.000000e+00, %entry ], [ %x, %if.end ]
126   %ret = tail call i1 @llvm.is.fpclass.f64(double %y, i32 411)
127   ret i1 %ret
130 define i1 @test6(double %x) {
131 ; CHECK-LABEL: define i1 @test6(
132 ; CHECK-SAME: double [[X:%.*]]) {
133 ; CHECK-NEXT:  entry:
134 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[X]], 0.000000e+00
135 ; CHECK-NEXT:    br i1 [[CMP]], label [[LAND_RHS:%.*]], label [[LAND_END:%.*]]
136 ; CHECK:       land.rhs:
137 ; CHECK-NEXT:    [[CMP_I:%.*]] = fcmp oeq double [[X]], 0x7FF0000000000000
138 ; CHECK-NEXT:    br label [[LAND_END]]
139 ; CHECK:       land.end:
140 ; CHECK-NEXT:    [[RET:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP_I]], [[LAND_RHS]] ]
141 ; CHECK-NEXT:    ret i1 [[RET]]
143 entry:
144   %cmp = fcmp ogt double %x, 0.000000e+00
145   br i1 %cmp, label %land.rhs, label %land.end
147 land.rhs:
148   %abs = tail call double @llvm.fabs.f64(double %x)
149   %and.i = bitcast double %abs to i64
150   %cmp.i = icmp eq i64 %and.i, 9218868437227405312
151   br label %land.end
153 land.end:
154   %ret = phi i1 [ false, %entry ], [ %cmp.i, %land.rhs ]
155   ret i1 %ret
158 define i1 @test7(float %x) {
159 ; CHECK-LABEL: define i1 @test7(
160 ; CHECK-SAME: float [[X:%.*]]) {
161 ; CHECK-NEXT:    [[COND:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 345)
162 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
163 ; CHECK:       if.then:
164 ; CHECK-NEXT:    [[RET1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 328)
165 ; CHECK-NEXT:    ret i1 [[RET1]]
166 ; CHECK:       if.else:
167 ; CHECK-NEXT:    [[RET2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 128)
168 ; CHECK-NEXT:    ret i1 [[RET2]]
170   %cond = call i1 @llvm.is.fpclass.f32(float %x, i32 345)
171   br i1 %cond, label %if.then, label %if.else
172 if.then:
173   %ret1 = call i1 @llvm.is.fpclass.f32(float %x, i32 456)
174   ret i1 %ret1
175 if.else:
176   %ret2 = call i1 @llvm.is.fpclass.f32(float %x, i32 456)
177   ret i1 %ret2
180 ; TODO: These two is.fpclass can be simplified.
181 define i1 @test8(float %x) {
182 ; CHECK-LABEL: define i1 @test8(
183 ; CHECK-SAME: float [[X:%.*]]) {
184 ; CHECK-NEXT:    [[ABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
185 ; CHECK-NEXT:    [[COND:%.*]] = fcmp oeq float [[ABS]], 0x7FF0000000000000
186 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
187 ; CHECK:       if.then:
188 ; CHECK-NEXT:    ret i1 true
189 ; CHECK:       if.else:
190 ; CHECK-NEXT:    [[RET2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 59)
191 ; CHECK-NEXT:    ret i1 [[RET2]]
193   %abs = call float @llvm.fabs.f32(float %x)
194   %cond = fcmp oeq float %abs, 0x7FF0000000000000
195   br i1 %cond, label %if.then, label %if.else
196 if.then:
197   %ret1 = call i1 @llvm.is.fpclass.f32(float %x, i32 575)
198   ret i1 %ret1
199 if.else:
200   %ret2 = call i1 @llvm.is.fpclass.f32(float %x, i32 575)
201   ret i1 %ret2
204 define i1 @test9(float %x) {
205 ; CHECK-LABEL: define i1 @test9(
206 ; CHECK-SAME: float [[X:%.*]]) {
207 ; CHECK-NEXT:    [[COND:%.*]] = fcmp olt float [[X]], -1.000000e+00
208 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
209 ; CHECK:       if.then:
210 ; CHECK-NEXT:    ret i1 false
211 ; CHECK:       if.else:
212 ; CHECK-NEXT:    ret i1 false
214   %cond = fcmp olt float %x, -1.0
215   br i1 %cond, label %if.then, label %if.else
216 if.then:
217   %ret1 = fcmp oeq float %x, 0x7FF0000000000000
218   ret i1 %ret1
219 if.else:
220   ret i1 false
223 define i1 @test10(float %x) {
224 ; CHECK-LABEL: define i1 @test10(
225 ; CHECK-SAME: float [[X:%.*]]) {
226 ; CHECK-NEXT:    [[COND:%.*]] = fcmp olt float [[X]], -1.000000e+00
227 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
228 ; CHECK:       if.then:
229 ; CHECK-NEXT:    ret i1 false
230 ; CHECK:       if.else:
231 ; CHECK-NEXT:    ret i1 false
233   %cond = fcmp olt float %x, -1.0
234   %neg = fneg float %x
235   br i1 %cond, label %if.then, label %if.else
236 if.then:
237   %ret1 = fcmp oeq float %neg, 0xFFF0000000000000
238   ret i1 %ret1
239 if.else:
240   ret i1 false
243 ; TODO: handle and/or conditions
244 define i1 @test11_and(float %x, i1 %cond2) {
245 ; CHECK-LABEL: define i1 @test11_and(
246 ; CHECK-SAME: float [[X:%.*]], i1 [[COND2:%.*]]) {
247 ; CHECK-NEXT:    [[COND:%.*]] = fcmp olt float [[X]], -1.000000e+00
248 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[COND]], [[COND2]]
249 ; CHECK-NEXT:    br i1 [[AND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
250 ; CHECK:       if.then:
251 ; CHECK-NEXT:    [[RET1:%.*]] = fcmp oeq float [[X]], 0x7FF0000000000000
252 ; CHECK-NEXT:    ret i1 [[RET1]]
253 ; CHECK:       if.else:
254 ; CHECK-NEXT:    ret i1 false
256   %cond = fcmp olt float %x, -1.0
257   %neg = fneg float %x
258   %and = and i1 %cond, %cond2
259   br i1 %and, label %if.then, label %if.else
260 if.then:
261   %ret1 = fcmp oeq float %neg, 0xFFF0000000000000
262   ret i1 %ret1
263 if.else:
264   ret i1 false
267 ; TODO: handle and/or conditions
268 define i1 @test12_or(float %x, i1 %cond2) {
269 ; CHECK-LABEL: define i1 @test12_or(
270 ; CHECK-SAME: float [[X:%.*]], i1 [[COND2:%.*]]) {
271 ; CHECK-NEXT:  entry:
272 ; CHECK-NEXT:    [[COND:%.*]] = fcmp ueq float [[X]], 0.000000e+00
273 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[COND]], [[COND2]]
274 ; CHECK-NEXT:    br i1 [[OR]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
275 ; CHECK:       if.then:
276 ; CHECK-NEXT:    ret i1 false
277 ; CHECK:       if.else:
278 ; CHECK-NEXT:    [[RET:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 783)
279 ; CHECK-NEXT:    ret i1 [[RET]]
281 entry:
282   %cond = fcmp ueq float %x, 0.000000e+00
283   %or = or i1 %cond, %cond2
284   br i1 %or, label %if.then, label %if.else
286 if.then:
287   ret i1 false
289 if.else:
290   %ret = call i1 @llvm.is.fpclass.f32(float %x, i32 783)
291   ret i1 %ret
294 define i1 @test1_no_dominating(float %x, i1 %c) {
295 ; CHECK-LABEL: define i1 @test1_no_dominating(
296 ; CHECK-SAME: float [[X:%.*]], i1 [[C:%.*]]) {
297 ; CHECK-NEXT:  entry0:
298 ; CHECK-NEXT:    br i1 [[C]], label [[ENTRY:%.*]], label [[IF_ELSE:%.*]]
299 ; CHECK:       entry:
300 ; CHECK-NEXT:    [[COND:%.*]] = fcmp ueq float [[X]], 0.000000e+00
301 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE]]
302 ; CHECK:       if.then:
303 ; CHECK-NEXT:    ret i1 false
304 ; CHECK:       if.else:
305 ; CHECK-NEXT:    [[RET:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 783)
306 ; CHECK-NEXT:    ret i1 [[RET]]
308 entry0:
309   br i1 %c, label %entry, label %if.else
311 entry:
312   %cond = fcmp ueq float %x, 0.000000e+00
313   br i1 %cond, label %if.then, label %if.else
315 if.then:
316   ret i1 false
318 if.else:
319   %ret = call i1 @llvm.is.fpclass.f32(float %x, i32 783)
320   ret i1 %ret
323 define float @test_signbit_check(float %x, i1 %cond) {
324 ; CHECK-LABEL: define float @test_signbit_check(
325 ; CHECK-SAME: float [[X:%.*]], i1 [[COND:%.*]]) {
326 ; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[X]] to i32
327 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I32]], 0
328 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_ELSE:%.*]]
329 ; CHECK:       if.then1:
330 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
331 ; CHECK-NEXT:    br label [[IF_END:%.*]]
332 ; CHECK:       if.else:
333 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN2:%.*]], label [[IF_END]]
334 ; CHECK:       if.then2:
335 ; CHECK-NEXT:    br label [[IF_END]]
336 ; CHECK:       if.end:
337 ; CHECK-NEXT:    [[VALUE:%.*]] = phi float [ [[FNEG]], [[IF_THEN1]] ], [ [[X]], [[IF_THEN2]] ], [ [[X]], [[IF_ELSE]] ]
338 ; CHECK-NEXT:    ret float [[VALUE]]
340   %i32 = bitcast float %x to i32
341   %cmp = icmp slt i32 %i32, 0
342   br i1 %cmp, label %if.then1, label %if.else
344 if.then1:
345   %fneg = fneg float %x
346   br label %if.end
348 if.else:
349   br i1 %cond, label %if.then2, label %if.end
351 if.then2:
352   br label %if.end
354 if.end:
355   %value = phi float [ %fneg, %if.then1 ], [ %x, %if.then2 ], [ %x, %if.else ]
356   %ret = call float @llvm.fabs.f32(float %value)
357   ret float %ret
360 define float @test_signbit_check_fail(float %x, i1 %cond) {
361 ; CHECK-LABEL: define float @test_signbit_check_fail(
362 ; CHECK-SAME: float [[X:%.*]], i1 [[COND:%.*]]) {
363 ; CHECK-NEXT:    [[I32:%.*]] = bitcast float [[X]] to i32
364 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I32]], 0
365 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_ELSE:%.*]]
366 ; CHECK:       if.then1:
367 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
368 ; CHECK-NEXT:    br label [[IF_END:%.*]]
369 ; CHECK:       if.else:
370 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN2:%.*]], label [[IF_END]]
371 ; CHECK:       if.then2:
372 ; CHECK-NEXT:    [[FNEG2:%.*]] = fneg float [[X]]
373 ; CHECK-NEXT:    br label [[IF_END]]
374 ; CHECK:       if.end:
375 ; CHECK-NEXT:    [[VALUE:%.*]] = phi float [ [[FNEG]], [[IF_THEN1]] ], [ [[FNEG2]], [[IF_THEN2]] ], [ [[X]], [[IF_ELSE]] ]
376 ; CHECK-NEXT:    [[RET:%.*]] = call float @llvm.fabs.f32(float [[VALUE]])
377 ; CHECK-NEXT:    ret float [[RET]]
379   %i32 = bitcast float %x to i32
380   %cmp = icmp slt i32 %i32, 0
381   br i1 %cmp, label %if.then1, label %if.else
383 if.then1:
384   %fneg = fneg float %x
385   br label %if.end
387 if.else:
388   br i1 %cond, label %if.then2, label %if.end
390 if.then2:
391   %fneg2 = fneg float %x
392   br label %if.end
394 if.end:
395   %value = phi float [ %fneg, %if.then1 ], [ %fneg2, %if.then2 ], [ %x, %if.else ]
396   %ret = call float @llvm.fabs.f32(float %value)
397   ret float %ret
400 define <2 x float> @test_signbit_check_wrong_type(<2 x float> %x, i1 %cond) {
401 ; CHECK-LABEL: define <2 x float> @test_signbit_check_wrong_type(
402 ; CHECK-SAME: <2 x float> [[X:%.*]], i1 [[COND:%.*]]) {
403 ; CHECK-NEXT:    [[I32:%.*]] = bitcast <2 x float> [[X]] to i64
404 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[I32]], 0
405 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_ELSE:%.*]]
406 ; CHECK:       if.then1:
407 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg <2 x float> [[X]]
408 ; CHECK-NEXT:    br label [[IF_END:%.*]]
409 ; CHECK:       if.else:
410 ; CHECK-NEXT:    br i1 [[COND]], label [[IF_THEN2:%.*]], label [[IF_END]]
411 ; CHECK:       if.then2:
412 ; CHECK-NEXT:    br label [[IF_END]]
413 ; CHECK:       if.end:
414 ; CHECK-NEXT:    [[VALUE:%.*]] = phi <2 x float> [ [[FNEG]], [[IF_THEN1]] ], [ [[X]], [[IF_THEN2]] ], [ [[X]], [[IF_ELSE]] ]
415 ; CHECK-NEXT:    [[RET:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[VALUE]])
416 ; CHECK-NEXT:    ret <2 x float> [[RET]]
418   %i32 = bitcast <2 x float> %x to i64
419   %cmp = icmp slt i64 %i32, 0
420   br i1 %cmp, label %if.then1, label %if.else
422 if.then1:
423   %fneg = fneg <2 x float> %x
424   br label %if.end
426 if.else:
427   br i1 %cond, label %if.then2, label %if.end
429 if.then2:
430   br label %if.end
432 if.end:
433   %value = phi <2 x float> [ %fneg, %if.then1 ], [ %x, %if.then2 ], [ %x, %if.else ]
434   %ret = call <2 x float> @llvm.fabs.v2f32(<2 x float> %value)
435   ret <2 x float> %ret