1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
4 declare half @llvm.fabs.f16(half)
5 declare double @llvm.fabs.f64(double)
6 declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
7 declare double @llvm.copysign.f64(double, double)
8 declare <2 x double> @llvm.copysign.v2f64(<2 x double>, <2 x double>)
10 define i1 @fpext_fpext(float %x, float %y) {
11 ; CHECK-LABEL: @fpext_fpext(
12 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
13 ; CHECK-NEXT: ret i1 [[CMP]]
15 %ext1 = fpext float %x to double
16 %ext2 = fpext float %y to double
17 %cmp = fcmp nnan ogt double %ext1, %ext2
21 define i1 @fpext_constant(float %a) {
22 ; CHECK-LABEL: @fpext_constant(
23 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt float [[A:%.*]], 1.000000e+00
24 ; CHECK-NEXT: ret i1 [[CMP]]
26 %ext = fpext float %a to double
27 %cmp = fcmp ninf ogt double %ext, 1.000000e+00
31 define <2 x i1> @fpext_constant_vec_splat(<2 x half> %a) {
32 ; CHECK-LABEL: @fpext_constant_vec_splat(
33 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ole <2 x half> [[A:%.*]], <half 0xH5140, half 0xH5140>
34 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
36 %ext = fpext <2 x half> %a to <2 x double>
37 %cmp = fcmp nnan ole <2 x double> %ext, <double 42.0, double 42.0>
41 define i1 @fpext_constant_lossy(float %a) {
42 ; CHECK-LABEL: @fpext_constant_lossy(
43 ; CHECK-NEXT: [[EXT:%.*]] = fpext float [[A:%.*]] to double
44 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x3FF0000000000001
45 ; CHECK-NEXT: ret i1 [[CMP]]
47 %ext = fpext float %a to double
48 %cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float.
52 define i1 @fpext_constant_denorm(float %a) {
53 ; CHECK-LABEL: @fpext_constant_denorm(
54 ; CHECK-NEXT: [[EXT:%.*]] = fpext float [[A:%.*]] to double
55 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x36A0000000000000
56 ; CHECK-NEXT: ret i1 [[CMP]]
58 %ext = fpext float %a to double
59 %cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float.
63 define i1 @fneg_constant_swap_pred(float %x) {
64 ; CHECK-LABEL: @fneg_constant_swap_pred(
65 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], -1.000000e+00
66 ; CHECK-NEXT: ret i1 [[CMP]]
68 %neg = fsub float -0.0, %x
69 %cmp = fcmp ogt float %neg, 1.0
73 define i1 @unary_fneg_constant_swap_pred(float %x) {
74 ; CHECK-LABEL: @unary_fneg_constant_swap_pred(
75 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], -1.000000e+00
76 ; CHECK-NEXT: ret i1 [[CMP]]
79 %cmp = fcmp ogt float %neg, 1.0
83 define <2 x i1> @fneg_constant_swap_pred_vec(<2 x float> %x) {
84 ; CHECK-LABEL: @fneg_constant_swap_pred_vec(
85 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00>
86 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
88 %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
89 %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>
93 define <2 x i1> @unary_fneg_constant_swap_pred_vec(<2 x float> %x) {
94 ; CHECK-LABEL: @unary_fneg_constant_swap_pred_vec(
95 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00>
96 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
98 %neg = fneg <2 x float> %x
99 %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>
103 define <2 x i1> @fneg_constant_swap_pred_vec_undef(<2 x float> %x) {
104 ; CHECK-LABEL: @fneg_constant_swap_pred_vec_undef(
105 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00>
106 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
108 %neg = fsub <2 x float> <float undef, float -0.0>, %x
109 %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>
113 ; The new fcmp should have the same FMF as the original.
115 define i1 @fneg_fmf(float %x) {
116 ; CHECK-LABEL: @fneg_fmf(
117 ; CHECK-NEXT: [[R:%.*]] = fcmp fast oeq float [[X:%.*]], -4.200000e+01
118 ; CHECK-NEXT: ret i1 [[R]]
120 %n = fsub fast float -0.0, %x
121 %r = fcmp fast oeq float %n, 42.0
125 define i1 @unary_fneg_fmf(float %x) {
126 ; CHECK-LABEL: @unary_fneg_fmf(
127 ; CHECK-NEXT: [[R:%.*]] = fcmp fast oeq float [[X:%.*]], -4.200000e+01
128 ; CHECK-NEXT: ret i1 [[R]]
130 %n = fneg fast float %x
131 %r = fcmp fast oeq float %n, 42.0
135 ; The new fcmp should have the same FMF as the original, vector edition.
137 define <2 x i1> @fcmp_fneg_fmf_vec(<2 x float> %x) {
138 ; CHECK-LABEL: @fcmp_fneg_fmf_vec(
139 ; CHECK-NEXT: [[R:%.*]] = fcmp reassoc nnan ule <2 x float> [[X:%.*]], <float -4.200000e+01, float 1.900000e+01>
140 ; CHECK-NEXT: ret <2 x i1> [[R]]
142 %n = fsub nsz <2 x float> zeroinitializer, %x
143 %r = fcmp nnan reassoc uge <2 x float> %n, <float 42.0, float -19.0>
147 define i1 @fneg_fneg_swap_pred(float %x, float %y) {
148 ; CHECK-LABEL: @fneg_fneg_swap_pred(
149 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
150 ; CHECK-NEXT: ret i1 [[CMP]]
152 %neg1 = fsub float -0.0, %x
153 %neg2 = fsub float -0.0, %y
154 %cmp = fcmp nnan olt float %neg1, %neg2
158 define i1 @unary_fneg_unary_fneg_swap_pred(float %x, float %y) {
159 ; CHECK-LABEL: @unary_fneg_unary_fneg_swap_pred(
160 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
161 ; CHECK-NEXT: ret i1 [[CMP]]
163 %neg1 = fneg float %x
164 %neg2 = fneg float %y
165 %cmp = fcmp nnan olt float %neg1, %neg2
169 define i1 @unary_fneg_fneg_swap_pred(float %x, float %y) {
170 ; CHECK-LABEL: @unary_fneg_fneg_swap_pred(
171 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
172 ; CHECK-NEXT: ret i1 [[CMP]]
174 %neg1 = fneg float %x
175 %neg2 = fsub float -0.0, %y
176 %cmp = fcmp nnan olt float %neg1, %neg2
180 define i1 @fneg_unary_fneg_swap_pred(float %x, float %y) {
181 ; CHECK-LABEL: @fneg_unary_fneg_swap_pred(
182 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
183 ; CHECK-NEXT: ret i1 [[CMP]]
185 %neg1 = fsub float -0.0, %x
186 %neg2 = fneg float %y
187 %cmp = fcmp nnan olt float %neg1, %neg2
191 define <2 x i1> @fneg_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
192 ; CHECK-LABEL: @fneg_fneg_swap_pred_vec(
193 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]]
194 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
196 %neg1 = fsub <2 x float> <float -0.0, float -0.0>, %x
197 %neg2 = fsub <2 x float> <float -0.0, float -0.0>, %y
198 %cmp = fcmp ninf olt <2 x float> %neg1, %neg2
202 define <2 x i1> @unary_fneg_unary_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
203 ; CHECK-LABEL: @unary_fneg_unary_fneg_swap_pred_vec(
204 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]]
205 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
207 %neg1 = fneg <2 x float> %x
208 %neg2 = fneg <2 x float> %y
209 %cmp = fcmp ninf olt <2 x float> %neg1, %neg2
213 define <2 x i1> @unary_fneg_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
214 ; CHECK-LABEL: @unary_fneg_fneg_swap_pred_vec(
215 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]]
216 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
218 %neg1 = fneg <2 x float> %x
219 %neg2 = fsub <2 x float> <float -0.0, float -0.0>, %y
220 %cmp = fcmp ninf olt <2 x float> %neg1, %neg2
224 define <2 x i1> @fneg_unary_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
225 ; CHECK-LABEL: @fneg_unary_fneg_swap_pred_vec(
226 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]]
227 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
229 %neg1 = fsub <2 x float> <float -0.0, float -0.0>, %x
230 %neg2 = fneg <2 x float> %y
231 %cmp = fcmp ninf olt <2 x float> %neg1, %neg2
235 define <2 x i1> @fneg_fneg_swap_pred_vec_undef(<2 x float> %x, <2 x float> %y) {
236 ; CHECK-LABEL: @fneg_fneg_swap_pred_vec_undef(
237 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]]
238 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
240 %neg1 = fsub <2 x float> <float -0.0, float undef>, %x
241 %neg2 = fsub <2 x float> <float undef, float -0.0>, %y
242 %cmp = fcmp olt <2 x float> %neg1, %neg2
246 define <2 x i1> @unary_fneg_fneg_swap_pred_vec_undef(<2 x float> %x, <2 x float> %y) {
247 ; CHECK-LABEL: @unary_fneg_fneg_swap_pred_vec_undef(
248 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]]
249 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
251 %neg1 = fneg <2 x float> %x
252 %neg2 = fsub <2 x float> <float undef, float -0.0>, %y
253 %cmp = fcmp olt <2 x float> %neg1, %neg2
257 define <2 x i1> @fneg_unary_fneg_swap_pred_vec_undef(<2 x float> %x, <2 x float> %y) {
258 ; CHECK-LABEL: @fneg_unary_fneg_swap_pred_vec_undef(
259 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]]
260 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
262 %neg1 = fsub <2 x float> <float -0.0, float undef>, %x
263 %neg2 = fneg <2 x float> %y
264 %cmp = fcmp olt <2 x float> %neg1, %neg2
268 define i1 @test7(float %x) {
269 ; CHECK-LABEL: @test7(
270 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X:%.*]], 0.000000e+00
271 ; CHECK-NEXT: ret i1 [[CMP]]
273 %ext = fpext float %x to ppc_fp128
274 %cmp = fcmp ogt ppc_fp128 %ext, 0xM00000000000000000000000000000000
278 define float @test8(float %x) {
279 ; CHECK-LABEL: @test8(
280 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
281 ; CHECK-NEXT: [[CONV2:%.*]] = uitofp i1 [[CMP]] to float
282 ; CHECK-NEXT: ret float [[CONV2]]
284 %conv = fpext float %x to double
285 %cmp = fcmp olt double %conv, 0.000000e+00
286 %conv1 = zext i1 %cmp to i32
287 %conv2 = sitofp i32 %conv1 to float
289 ; Float comparison to zero shouldn't cast to double.
292 define i1 @fabs_uge(double %a) {
293 ; CHECK-LABEL: @fabs_uge(
294 ; CHECK-NEXT: ret i1 true
296 %call = call double @llvm.fabs.f64(double %a)
297 %cmp = fcmp uge double %call, 0.0
301 define i1 @fabs_olt(half %a) {
302 ; CHECK-LABEL: @fabs_olt(
303 ; CHECK-NEXT: ret i1 false
305 %call = call half @llvm.fabs.f16(half %a)
306 %cmp = fcmp olt half %call, 0.0
310 define <2 x i1> @fabs_ole(<2 x float> %a) {
311 ; CHECK-LABEL: @fabs_ole(
312 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf oeq <2 x float> [[A:%.*]], zeroinitializer
313 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
315 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
316 %cmp = fcmp ninf ole <2 x float> %call, zeroinitializer
320 define <2 x i1> @fabs_ule(<2 x float> %a) {
321 ; CHECK-LABEL: @fabs_ule(
322 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf arcp ueq <2 x float> [[A:%.*]], zeroinitializer
323 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
325 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
326 %cmp = fcmp ninf arcp ule <2 x float> %call, zeroinitializer
330 define i1 @fabs_ogt(double %a) {
331 ; CHECK-LABEL: @fabs_ogt(
332 ; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc one double [[A:%.*]], 0.000000e+00
333 ; CHECK-NEXT: ret i1 [[CMP]]
335 %call = call double @llvm.fabs.f64(double %a)
336 %cmp = fcmp reassoc ogt double %call, 0.0
340 define i1 @fabs_ugt(double %a) {
341 ; CHECK-LABEL: @fabs_ugt(
342 ; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc ninf une double [[A:%.*]], 0.000000e+00
343 ; CHECK-NEXT: ret i1 [[CMP]]
345 %call = call double @llvm.fabs.f64(double %a)
346 %cmp = fcmp ninf reassoc ugt double %call, 0.0
350 define i1 @fabs_oge(double %a) {
351 ; CHECK-LABEL: @fabs_oge(
352 ; CHECK-NEXT: [[CMP:%.*]] = fcmp afn ord double [[A:%.*]], 0.000000e+00
353 ; CHECK-NEXT: ret i1 [[CMP]]
355 %call = call double @llvm.fabs.f64(double %a)
356 %cmp = fcmp afn oge double %call, 0.0
360 define i1 @fabs_ult(double %a) {
361 ; CHECK-LABEL: @fabs_ult(
362 ; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc arcp uno double [[A:%.*]], 0.000000e+00
363 ; CHECK-NEXT: ret i1 [[CMP]]
365 %call = call double @llvm.fabs.f64(double %a)
366 %cmp = fcmp reassoc arcp ult double %call, 0.0
370 define <2 x i1> @fabs_ult_nnan(<2 x float> %a) {
371 ; CHECK-LABEL: @fabs_ult_nnan(
372 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
374 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
375 %cmp = fcmp nnan reassoc arcp ult <2 x float> %call, zeroinitializer
379 define i1 @fabs_une(half %a) {
380 ; CHECK-LABEL: @fabs_une(
381 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf une half [[A:%.*]], 0xH0000
382 ; CHECK-NEXT: ret i1 [[CMP]]
384 %call = call half @llvm.fabs.f16(half %a)
385 %cmp = fcmp ninf une half %call, 0.0
389 define i1 @fabs_oeq(double %a) {
390 ; CHECK-LABEL: @fabs_oeq(
391 ; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc ninf oeq double [[A:%.*]], 0.000000e+00
392 ; CHECK-NEXT: ret i1 [[CMP]]
394 %call = call double @llvm.fabs.f64(double %a)
395 %cmp = fcmp ninf reassoc oeq double %call, 0.0
399 define i1 @fabs_one(double %a) {
400 ; CHECK-LABEL: @fabs_one(
401 ; CHECK-NEXT: [[CMP:%.*]] = fcmp fast one double [[A:%.*]], 0.000000e+00
402 ; CHECK-NEXT: ret i1 [[CMP]]
404 %call = call double @llvm.fabs.f64(double %a)
405 %cmp = fcmp fast one double %call, 0.0
409 define <2 x i1> @fabs_ueq(<2 x float> %a) {
410 ; CHECK-LABEL: @fabs_ueq(
411 ; CHECK-NEXT: [[CMP:%.*]] = fcmp arcp ueq <2 x float> [[A:%.*]], zeroinitializer
412 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
414 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
415 %cmp = fcmp arcp ueq <2 x float> %call, zeroinitializer
419 define <2 x i1> @fabs_ord(<2 x float> %a) {
420 ; CHECK-LABEL: @fabs_ord(
421 ; CHECK-NEXT: [[CMP:%.*]] = fcmp arcp ord <2 x float> [[A:%.*]], zeroinitializer
422 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
424 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
425 %cmp = fcmp arcp ord <2 x float> %call, zeroinitializer
429 define <2 x i1> @fabs_uno(<2 x float> %a) {
430 ; CHECK-LABEL: @fabs_uno(
431 ; CHECK-NEXT: [[CMP:%.*]] = fcmp arcp uno <2 x float> [[A:%.*]], zeroinitializer
432 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
434 %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
435 %cmp = fcmp arcp uno <2 x float> %call, zeroinitializer
440 define i32 @test17(double %a, double (double)* %p) {
441 ; CHECK-LABEL: @test17(
442 ; CHECK-NEXT: [[CALL:%.*]] = tail call double [[P:%.*]](double [[A:%.*]])
443 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq double [[CALL]], 0.000000e+00
444 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
445 ; CHECK-NEXT: ret i32 [[CONV]]
447 %call = tail call double %p(double %a)
448 %cmp = fcmp ueq double %call, 0.000000e+00
449 %conv = zext i1 %cmp to i32
453 ; Can fold fcmp with undef on one side by choosing NaN for the undef
454 define i32 @test18_undef_unordered(float %a) {
455 ; CHECK-LABEL: @test18_undef_unordered(
456 ; CHECK-NEXT: ret i32 1
458 %cmp = fcmp ueq float %a, undef
459 %conv = zext i1 %cmp to i32
462 ; Can fold fcmp with undef on one side by choosing NaN for the undef
463 define i32 @test18_undef_ordered(float %a) {
464 ; CHECK-LABEL: @test18_undef_ordered(
465 ; CHECK-NEXT: ret i32 0
467 %cmp = fcmp oeq float %a, undef
468 %conv = zext i1 %cmp to i32
472 ; Can fold fcmp with undef on both side
473 ; fcmp u_pred undef, undef -> true
474 ; fcmp o_pred undef, undef -> false
475 ; because whatever you choose for the first undef
476 ; you can choose NaN for the other undef
477 define i1 @test19_undef_unordered() {
478 ; CHECK-LABEL: @test19_undef_unordered(
479 ; CHECK-NEXT: ret i1 true
481 %cmp = fcmp ueq float undef, undef
485 define i1 @test19_undef_ordered() {
486 ; CHECK-LABEL: @test19_undef_ordered(
487 ; CHECK-NEXT: ret i1 false
489 %cmp = fcmp oeq float undef, undef
493 ; Can fold 1.0 / X < 0.0 --> X < 0 with ninf
494 define i1 @test20_recipX_olt_0(float %X) {
495 ; CHECK-LABEL: @test20_recipX_olt_0(
496 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf olt float [[X:%.*]], 0.000000e+00
497 ; CHECK-NEXT: ret i1 [[CMP]]
499 %div = fdiv ninf float 1.0, %X
500 %cmp = fcmp ninf olt float %div, 0.0
504 ; Can fold -2.0 / X <= 0.0 --> X >= 0 with ninf
505 define i1 @test21_recipX_ole_0(float %X) {
506 ; CHECK-LABEL: @test21_recipX_ole_0(
507 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf oge float [[X:%.*]], 0.000000e+00
508 ; CHECK-NEXT: ret i1 [[CMP]]
510 %div = fdiv ninf float -2.0, %X
511 %cmp = fcmp ninf ole float %div, 0.0
515 ; Can fold 2.0 / X > 0.0 --> X > 0 with ninf
516 define i1 @test22_recipX_ogt_0(float %X) {
517 ; CHECK-LABEL: @test22_recipX_ogt_0(
518 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt float [[X:%.*]], 0.000000e+00
519 ; CHECK-NEXT: ret i1 [[CMP]]
521 %div = fdiv ninf float 2.0, %X
522 %cmp = fcmp ninf ogt float %div, 0.0
526 ; Can fold -1.0 / X >= 0.0 --> X <= 0 with ninf
527 define i1 @test23_recipX_oge_0(float %X) {
528 ; CHECK-LABEL: @test23_recipX_oge_0(
529 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ole float [[X:%.*]], 0.000000e+00
530 ; CHECK-NEXT: ret i1 [[CMP]]
532 %div = fdiv ninf float -1.0, %X
533 %cmp = fcmp ninf oge float %div, 0.0
537 ; Do not fold 1.0 / X > 0.0 when ninf is missing
538 define i1 @test24_recipX_noninf_cmp(float %X) {
539 ; CHECK-LABEL: @test24_recipX_noninf_cmp(
540 ; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf float 2.000000e+00, [[X:%.*]]
541 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[DIV]], 0.000000e+00
542 ; CHECK-NEXT: ret i1 [[CMP]]
544 %div = fdiv ninf float 2.0, %X
545 %cmp = fcmp ogt float %div, 0.0
549 ; Do not fold 1.0 / X > 0.0 when ninf is missing
550 define i1 @test25_recipX_noninf_div(float %X) {
551 ; CHECK-LABEL: @test25_recipX_noninf_div(
552 ; CHECK-NEXT: [[DIV:%.*]] = fdiv float 2.000000e+00, [[X:%.*]]
553 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ogt float [[DIV]], 0.000000e+00
554 ; CHECK-NEXT: ret i1 [[CMP]]
556 %div = fdiv float 2.0, %X
557 %cmp = fcmp ninf ogt float %div, 0.0
561 ; Do not fold 1.0 / X > 0.0 with unordered predicates
562 define i1 @test26_recipX_unorderd(float %X) {
563 ; CHECK-LABEL: @test26_recipX_unorderd(
564 ; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf float 2.000000e+00, [[X:%.*]]
565 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ugt float [[DIV]], 0.000000e+00
566 ; CHECK-NEXT: ret i1 [[CMP]]
568 %div = fdiv ninf float 2.0, %X
569 %cmp = fcmp ninf ugt float %div, 0.0
573 ; Fold <-1.0, -1.0> / X > <-0.0, -0.0>
574 define <2 x i1> @test27_recipX_gt_vecsplat(<2 x float> %X) {
575 ; CHECK-LABEL: @test27_recipX_gt_vecsplat(
576 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf olt <2 x float> [[X:%.*]], zeroinitializer
577 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
579 %div = fdiv ninf <2 x float> <float -1.0, float -1.0>, %X
580 %cmp = fcmp ninf ogt <2 x float> %div, <float -0.0, float -0.0>
584 define i1 @is_signbit_set(double %x) {
585 ; CHECK-LABEL: @is_signbit_set(
586 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64
587 ; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[TMP1]], 0
588 ; CHECK-NEXT: ret i1 [[R]]
590 %s = call double @llvm.copysign.f64(double 1.0, double %x)
591 %r = fcmp olt double %s, 0.0
595 define i1 @is_signbit_set_1(double %x) {
596 ; CHECK-LABEL: @is_signbit_set_1(
597 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]])
598 ; CHECK-NEXT: [[R:%.*]] = fcmp ult double [[S]], 0.000000e+00
599 ; CHECK-NEXT: ret i1 [[R]]
601 %s = call double @llvm.copysign.f64(double 1.0, double %x)
602 %r = fcmp ult double %s, 0.0
606 define i1 @is_signbit_set_2(double %x) {
607 ; CHECK-LABEL: @is_signbit_set_2(
608 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]])
609 ; CHECK-NEXT: [[R:%.*]] = fcmp ole double [[S]], 0.000000e+00
610 ; CHECK-NEXT: ret i1 [[R]]
612 %s = call double @llvm.copysign.f64(double 1.0, double %x)
613 %r = fcmp ole double %s, 0.0
617 define i1 @is_signbit_set_3(double %x) {
618 ; CHECK-LABEL: @is_signbit_set_3(
619 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]])
620 ; CHECK-NEXT: [[R:%.*]] = fcmp ule double [[S]], 0.000000e+00
621 ; CHECK-NEXT: ret i1 [[R]]
623 %s = call double @llvm.copysign.f64(double 1.0, double %x)
624 %r = fcmp ule double %s, 0.0
628 ; Vectors are ok; the sign of zero in the compare doesn't matter; the copysign constant can be any non-zero number.
630 define <2 x i1> @is_signbit_set_anyzero(<2 x double> %x) {
631 ; CHECK-LABEL: @is_signbit_set_anyzero(
632 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[X:%.*]] to <2 x i64>
633 ; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i64> [[TMP1]], zeroinitializer
634 ; CHECK-NEXT: ret <2 x i1> [[R]]
636 %s = call <2 x double> @llvm.copysign.v2f64(<2 x double> <double 42.0, double 42.0>, <2 x double> %x)
637 %r = fcmp olt <2 x double> %s, <double -0.0, double 0.0>
641 ; TODO: Handle different predicates.
643 define i1 @is_signbit_clear(double %x) {
644 ; CHECK-LABEL: @is_signbit_clear(
645 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]])
646 ; CHECK-NEXT: [[R:%.*]] = fcmp ogt double [[S]], 0.000000e+00
647 ; CHECK-NEXT: ret i1 [[R]]
649 %s = call double @llvm.copysign.f64(double -42.0, double %x)
650 %r = fcmp ogt double %s, 0.0
654 define i1 @is_signbit_clear_1(double %x) {
655 ; CHECK-LABEL: @is_signbit_clear_1(
656 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]])
657 ; CHECK-NEXT: [[R:%.*]] = fcmp ugt double [[S]], 0.000000e+00
658 ; CHECK-NEXT: ret i1 [[R]]
660 %s = call double @llvm.copysign.f64(double -42.0, double %x)
661 %r = fcmp ugt double %s, 0.0
665 define i1 @is_signbit_clear_2(double %x) {
666 ; CHECK-LABEL: @is_signbit_clear_2(
667 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]])
668 ; CHECK-NEXT: [[R:%.*]] = fcmp oge double [[S]], 0.000000e+00
669 ; CHECK-NEXT: ret i1 [[R]]
671 %s = call double @llvm.copysign.f64(double -42.0, double %x)
672 %r = fcmp oge double %s, 0.0
676 define i1 @is_signbit_clear_3(double %x) {
677 ; CHECK-LABEL: @is_signbit_clear_3(
678 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]])
679 ; CHECK-NEXT: [[R:%.*]] = fcmp uge double [[S]], 0.000000e+00
680 ; CHECK-NEXT: ret i1 [[R]]
682 %s = call double @llvm.copysign.f64(double -42.0, double %x)
683 %r = fcmp uge double %s, 0.0
687 ; Negative test - uses
689 define i1 @is_signbit_set_extra_use(double %x, double* %p) {
690 ; CHECK-LABEL: @is_signbit_set_extra_use(
691 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]])
692 ; CHECK-NEXT: store double [[S]], double* [[P:%.*]], align 8
693 ; CHECK-NEXT: [[R:%.*]] = fcmp olt double [[S]], 0.000000e+00
694 ; CHECK-NEXT: ret i1 [[R]]
696 %s = call double @llvm.copysign.f64(double 1.0, double %x)
697 store double %s, double* %p
698 %r = fcmp olt double %s, 0.0
702 ; TODO: Handle non-zero compare constant.
704 define i1 @is_signbit_clear_nonzero(double %x) {
705 ; CHECK-LABEL: @is_signbit_clear_nonzero(
706 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double -4.200000e+01, double [[X:%.*]])
707 ; CHECK-NEXT: [[R:%.*]] = fcmp ogt double [[S]], 1.000000e+00
708 ; CHECK-NEXT: ret i1 [[R]]
710 %s = call double @llvm.copysign.f64(double -42.0, double %x)
711 %r = fcmp ogt double %s, 1.0
715 ; TODO: Handle zero copysign constant.
717 define i1 @is_signbit_set_simplify_zero(double %x) {
718 ; CHECK-LABEL: @is_signbit_set_simplify_zero(
719 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 0.000000e+00, double [[X:%.*]])
720 ; CHECK-NEXT: [[R:%.*]] = fcmp ogt double [[S]], 0.000000e+00
721 ; CHECK-NEXT: ret i1 [[R]]
723 %s = call double @llvm.copysign.f64(double 0.0, double %x)
724 %r = fcmp ogt double %s, 0.0
728 ; TODO: Handle NaN copysign constant.
730 define i1 @is_signbit_set_simplify_nan(double %x) {
731 ; CHECK-LABEL: @is_signbit_set_simplify_nan(
732 ; CHECK-NEXT: [[S:%.*]] = call double @llvm.copysign.f64(double 0xFFFFFFFFFFFFFFFF, double [[X:%.*]])
733 ; CHECK-NEXT: [[R:%.*]] = fcmp ogt double [[S]], 0.000000e+00
734 ; CHECK-NEXT: ret i1 [[R]]
736 %s = call double @llvm.copysign.f64(double 0xffffffffffffffff, double %x)
737 %r = fcmp ogt double %s, 0.0
741 define <2 x i1> @lossy_oeq(<2 x float> %x) {
742 ; CHECK-LABEL: @lossy_oeq(
743 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
745 %e = fpext <2 x float> %x to <2 x double>
746 %r = fcmp oeq <2 x double> %e, <double 0.1, double 0.1>
750 define i1 @lossy_one(float %x, double* %p) {
751 ; CHECK-LABEL: @lossy_one(
752 ; CHECK-NEXT: [[E:%.*]] = fpext float [[X:%.*]] to double
753 ; CHECK-NEXT: store double [[E]], double* [[P:%.*]], align 8
754 ; CHECK-NEXT: [[R:%.*]] = fcmp ord float [[X]], 0.000000e+00
755 ; CHECK-NEXT: ret i1 [[R]]
757 %e = fpext float %x to double
758 store double %e, double* %p
759 %r = fcmp one double %e, 0.1
763 define i1 @lossy_ueq(half %x) {
764 ; CHECK-LABEL: @lossy_ueq(
765 ; CHECK-NEXT: [[R:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
766 ; CHECK-NEXT: ret i1 [[R]]
768 %e = fpext half %x to double
769 %r = fcmp ueq double %e, 65536.0
773 define i1 @lossy_une(half %x) {
774 ; CHECK-LABEL: @lossy_une(
775 ; CHECK-NEXT: ret i1 true
777 %e = fpext half %x to float
778 %r = fcmp une float %e, 2049.0
782 define <2 x i1> @lossy_ogt(<2 x float> %x) {
783 ; CHECK-LABEL: @lossy_ogt(
784 ; CHECK-NEXT: [[E:%.*]] = fpext <2 x float> [[X:%.*]] to <2 x double>
785 ; CHECK-NEXT: [[R:%.*]] = fcmp ogt <2 x double> [[E]], <double 1.000000e-01, double 1.000000e-01>
786 ; CHECK-NEXT: ret <2 x i1> [[R]]
788 %e = fpext <2 x float> %x to <2 x double>
789 %r = fcmp ogt <2 x double> %e, <double 0.1, double 0.1>
793 define i1 @lossy_oge(float %x, double* %p) {
794 ; CHECK-LABEL: @lossy_oge(
795 ; CHECK-NEXT: [[E:%.*]] = fpext float [[X:%.*]] to double
796 ; CHECK-NEXT: store double [[E]], double* [[P:%.*]], align 8
797 ; CHECK-NEXT: [[R:%.*]] = fcmp oge double [[E]], 1.000000e-01
798 ; CHECK-NEXT: ret i1 [[R]]
800 %e = fpext float %x to double
801 store double %e, double* %p
802 %r = fcmp oge double %e, 0.1
806 define i1 @lossy_olt(half %x) {
807 ; CHECK-LABEL: @lossy_olt(
808 ; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to double
809 ; CHECK-NEXT: [[R:%.*]] = fcmp olt double [[E]], 6.553600e+04
810 ; CHECK-NEXT: ret i1 [[R]]
812 %e = fpext half %x to double
813 %r = fcmp olt double %e, 65536.0
817 define i1 @lossy_ole(half %x) {
818 ; CHECK-LABEL: @lossy_ole(
819 ; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to float
820 ; CHECK-NEXT: [[R:%.*]] = fcmp ole float [[E]], 2.049000e+03
821 ; CHECK-NEXT: ret i1 [[R]]
823 %e = fpext half %x to float
824 %r = fcmp ole float %e, 2049.0
828 define <2 x i1> @lossy_ugt(<2 x float> %x) {
829 ; CHECK-LABEL: @lossy_ugt(
830 ; CHECK-NEXT: [[E:%.*]] = fpext <2 x float> [[X:%.*]] to <2 x double>
831 ; CHECK-NEXT: [[R:%.*]] = fcmp ugt <2 x double> [[E]], <double 1.000000e-01, double 1.000000e-01>
832 ; CHECK-NEXT: ret <2 x i1> [[R]]
834 %e = fpext <2 x float> %x to <2 x double>
835 %r = fcmp ugt <2 x double> %e, <double 0.1, double 0.1>
839 define i1 @lossy_uge(float %x, double* %p) {
840 ; CHECK-LABEL: @lossy_uge(
841 ; CHECK-NEXT: [[E:%.*]] = fpext float [[X:%.*]] to double
842 ; CHECK-NEXT: store double [[E]], double* [[P:%.*]], align 8
843 ; CHECK-NEXT: [[R:%.*]] = fcmp uge double [[E]], 1.000000e-01
844 ; CHECK-NEXT: ret i1 [[R]]
846 %e = fpext float %x to double
847 store double %e, double* %p
848 %r = fcmp uge double %e, 0.1
852 define i1 @lossy_ult(half %x) {
853 ; CHECK-LABEL: @lossy_ult(
854 ; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to double
855 ; CHECK-NEXT: [[R:%.*]] = fcmp ult double [[E]], 6.553600e+04
856 ; CHECK-NEXT: ret i1 [[R]]
858 %e = fpext half %x to double
859 %r = fcmp ult double %e, 65536.0
863 define i1 @lossy_ule(half %x) {
864 ; CHECK-LABEL: @lossy_ule(
865 ; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to float
866 ; CHECK-NEXT: [[R:%.*]] = fcmp ule float [[E]], 2.049000e+03
867 ; CHECK-NEXT: ret i1 [[R]]
869 %e = fpext half %x to float
870 %r = fcmp ule float %e, 2049.0
874 define i1 @lossy_ord(half %x) {
875 ; CHECK-LABEL: @lossy_ord(
876 ; CHECK-NEXT: [[R:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
877 ; CHECK-NEXT: ret i1 [[R]]
879 %e = fpext half %x to double
880 %r = fcmp ord double %e, 65536.0
884 define i1 @lossy_uno(half %x) {
885 ; CHECK-LABEL: @lossy_uno(
886 ; CHECK-NEXT: [[R:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
887 ; CHECK-NEXT: ret i1 [[R]]
889 %e = fpext half %x to float
890 %r = fcmp uno float %e, 2049.0
894 define i1 @fneg_oeq(float %a) {
895 ; CHECK-LABEL: @fneg_oeq(
896 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[A:%.*]], 0.000000e+00
897 ; CHECK-NEXT: ret i1 [[CMP]]
899 %fneg = fneg float %a
900 %cmp = fcmp oeq float %fneg, %a
904 define i1 @fneg_ogt(half %a) {
905 ; CHECK-LABEL: @fneg_ogt(
906 ; CHECK-NEXT: [[CMP:%.*]] = fcmp fast olt half [[A:%.*]], 0xH0000
907 ; CHECK-NEXT: ret i1 [[CMP]]
910 %cmp = fcmp fast ogt half %fneg, %a
914 define <2 x i1> @fneg_oge(<2 x float> %a) {
915 ; CHECK-LABEL: @fneg_oge(
916 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ole <2 x float> [[A:%.*]], zeroinitializer
917 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
919 %fneg = fneg fast <2 x float> %a
920 %cmp = fcmp oge <2 x float> %fneg, %a
924 define i1 @fneg_olt(float %a, float* %q) {
925 ; CHECK-LABEL: @fneg_olt(
926 ; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[A:%.*]]
927 ; CHECK-NEXT: store float [[FNEG]], float* [[Q:%.*]], align 4
928 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[A]], 0.000000e+00
929 ; CHECK-NEXT: ret i1 [[CMP]]
931 %fneg = fneg float %a
932 store float %fneg, float* %q
933 %cmp = fcmp olt float %fneg, %a
937 define i1 @fneg_ole(float %a) {
938 ; CHECK-LABEL: @fneg_ole(
939 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz oge float [[A:%.*]], 0.000000e+00
940 ; CHECK-NEXT: ret i1 [[CMP]]
942 %fneg = fneg float %a
943 %cmp = fcmp nsz ole float %fneg, %a
947 define i1 @fneg_one(float %a) {
948 ; CHECK-LABEL: @fneg_one(
949 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan one float [[A:%.*]], 0.000000e+00
950 ; CHECK-NEXT: ret i1 [[CMP]]
952 %fneg = fneg float %a
953 %cmp = fcmp nnan one float %fneg, %a
957 define i1 @fneg_ord(float %a) {
958 ; CHECK-LABEL: @fneg_ord(
959 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ord float [[A:%.*]], 0.000000e+00
960 ; CHECK-NEXT: ret i1 [[CMP]]
962 %fneg = fneg float %a
963 %cmp = fcmp ninf ord float %fneg, %a
967 define i1 @fneg_uno(float %a) {
968 ; CHECK-LABEL: @fneg_uno(
969 ; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[A:%.*]], 0.000000e+00
970 ; CHECK-NEXT: ret i1 [[CMP]]
972 %fneg = fneg float %a
973 %cmp = fcmp uno float %fneg, %a
977 define i1 @fneg_ueq(half %a) {
978 ; CHECK-LABEL: @fneg_ueq(
979 ; CHECK-NEXT: [[CMP:%.*]] = fcmp fast ueq half [[A:%.*]], 0xH0000
980 ; CHECK-NEXT: ret i1 [[CMP]]
983 %cmp = fcmp fast ueq half %fneg, %a
987 define <2 x i1> @fneg_ugt(<2 x float> %a) {
988 ; CHECK-LABEL: @fneg_ugt(
989 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ult <2 x float> [[A:%.*]], zeroinitializer
990 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
992 %fneg = fneg fast <2 x float> %a
993 %cmp = fcmp ugt <2 x float> %fneg, %a
997 define i1 @fneg_uge(float %a, float* %q) {
998 ; CHECK-LABEL: @fneg_uge(
999 ; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[A:%.*]]
1000 ; CHECK-NEXT: store float [[FNEG]], float* [[Q:%.*]], align 4
1001 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ule float [[A]], 0.000000e+00
1002 ; CHECK-NEXT: ret i1 [[CMP]]
1004 %fneg = fneg float %a
1005 store float %fneg, float* %q
1006 %cmp = fcmp uge float %fneg, %a
1010 define i1 @fneg_ult(float %a) {
1011 ; CHECK-LABEL: @fneg_ult(
1012 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz ugt float [[A:%.*]], 0.000000e+00
1013 ; CHECK-NEXT: ret i1 [[CMP]]
1015 %fneg = fneg float %a
1016 %cmp = fcmp nsz ult float %fneg, %a
1020 define i1 @fneg_ule(float %a) {
1021 ; CHECK-LABEL: @fneg_ule(
1022 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan uge float [[A:%.*]], 0.000000e+00
1023 ; CHECK-NEXT: ret i1 [[CMP]]
1025 %fneg = fneg float %a
1026 %cmp = fcmp nnan ule float %fneg, %a
1030 define i1 @fneg_une(float %a) {
1031 ; CHECK-LABEL: @fneg_une(
1032 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf une float [[A:%.*]], 0.000000e+00
1033 ; CHECK-NEXT: ret i1 [[CMP]]
1035 %fneg = fneg float %a
1036 %cmp = fcmp ninf une float %fneg, %a
1040 define i1 @fneg_oeq_swap(float %p) {
1041 ; CHECK-LABEL: @fneg_oeq_swap(
1042 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1043 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[A]], 0.000000e+00
1044 ; CHECK-NEXT: ret i1 [[CMP]]
1046 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1047 %fneg = fneg float %a
1048 %cmp = fcmp oeq float %a, %fneg
1052 define i1 @fneg_ogt_swap(half %p) {
1053 ; CHECK-LABEL: @fneg_ogt_swap(
1054 ; CHECK-NEXT: [[A:%.*]] = fadd half [[P:%.*]], [[P]]
1055 ; CHECK-NEXT: [[CMP:%.*]] = fcmp fast ogt half [[A]], 0xH0000
1056 ; CHECK-NEXT: ret i1 [[CMP]]
1058 %a = fadd half %p, %p ; thwart complexity-based canonicalization
1059 %fneg = fneg half %a
1060 %cmp = fcmp fast ogt half %a, %fneg
1064 define <2 x i1> @fneg_oge_swap(<2 x float> %p) {
1065 ; CHECK-LABEL: @fneg_oge_swap(
1066 ; CHECK-NEXT: [[A:%.*]] = fadd <2 x float> [[P:%.*]], [[P]]
1067 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge <2 x float> [[A]], zeroinitializer
1068 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1070 %a = fadd <2 x float> %p, %p ; thwart complexity-based canonicalization
1071 %fneg = fneg fast <2 x float> %a
1072 %cmp = fcmp oge <2 x float> %a, %fneg
1076 define i1 @fneg_olt_swap(float %p, float* %q) {
1077 ; CHECK-LABEL: @fneg_olt_swap(
1078 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1079 ; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[A]]
1080 ; CHECK-NEXT: store float [[FNEG]], float* [[Q:%.*]], align 4
1081 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[A]], 0.000000e+00
1082 ; CHECK-NEXT: ret i1 [[CMP]]
1084 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1085 %fneg = fneg float %a
1086 store float %fneg, float* %q
1087 %cmp = fcmp olt float %a, %fneg
1091 define i1 @fneg_ole_swap(float %p) {
1092 ; CHECK-LABEL: @fneg_ole_swap(
1093 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1094 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz ole float [[A]], 0.000000e+00
1095 ; CHECK-NEXT: ret i1 [[CMP]]
1097 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1098 %fneg = fneg float %a
1099 %cmp = fcmp nsz ole float %a, %fneg
1103 define i1 @fneg_one_swap(float %p) {
1104 ; CHECK-LABEL: @fneg_one_swap(
1105 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1106 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan one float [[A]], 0.000000e+00
1107 ; CHECK-NEXT: ret i1 [[CMP]]
1109 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1110 %fneg = fneg float %a
1111 %cmp = fcmp nnan one float %a, %fneg
1115 define i1 @fneg_ord_swap(float %p) {
1116 ; CHECK-LABEL: @fneg_ord_swap(
1117 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1118 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf ord float [[A]], 0.000000e+00
1119 ; CHECK-NEXT: ret i1 [[CMP]]
1121 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1122 %fneg = fneg float %a
1123 %cmp = fcmp ninf ord float %a, %fneg
1127 define i1 @fneg_uno_swap(float %p) {
1128 ; CHECK-LABEL: @fneg_uno_swap(
1129 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1130 ; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[A]], 0.000000e+00
1131 ; CHECK-NEXT: ret i1 [[CMP]]
1133 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1134 %fneg = fneg float %a
1135 %cmp = fcmp uno float %a, %fneg
1139 define i1 @fneg_ueq_swap(half %p) {
1140 ; CHECK-LABEL: @fneg_ueq_swap(
1141 ; CHECK-NEXT: [[A:%.*]] = fadd half [[P:%.*]], [[P]]
1142 ; CHECK-NEXT: [[CMP:%.*]] = fcmp fast ueq half [[A]], 0xH0000
1143 ; CHECK-NEXT: ret i1 [[CMP]]
1145 %a = fadd half %p, %p ; thwart complexity-based canonicalization
1146 %fneg = fneg half %a
1147 %cmp = fcmp fast ueq half %a, %fneg
1151 define <2 x i1> @fneg_ugt_swap(<2 x float> %p) {
1152 ; CHECK-LABEL: @fneg_ugt_swap(
1153 ; CHECK-NEXT: [[A:%.*]] = fadd <2 x float> [[P:%.*]], [[P]]
1154 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt <2 x float> [[A]], zeroinitializer
1155 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1157 %a = fadd <2 x float> %p, %p ; thwart complexity-based canonicalization
1158 %fneg = fneg fast <2 x float> %a
1159 %cmp = fcmp ugt <2 x float> %a, %fneg
1163 define i1 @fneg_uge_swap(float %p, float* %q) {
1164 ; CHECK-LABEL: @fneg_uge_swap(
1165 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1166 ; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[A]]
1167 ; CHECK-NEXT: store float [[FNEG]], float* [[Q:%.*]], align 4
1168 ; CHECK-NEXT: [[CMP:%.*]] = fcmp uge float [[A]], 0.000000e+00
1169 ; CHECK-NEXT: ret i1 [[CMP]]
1171 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1172 %fneg = fneg float %a
1173 store float %fneg, float* %q
1174 %cmp = fcmp uge float %a, %fneg
1178 define i1 @fneg_ult_swap(float %p) {
1179 ; CHECK-LABEL: @fneg_ult_swap(
1180 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1181 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz ult float [[A]], 0.000000e+00
1182 ; CHECK-NEXT: ret i1 [[CMP]]
1184 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1185 %fneg = fneg float %a
1186 %cmp = fcmp nsz ult float %a, %fneg
1190 define i1 @fneg_ule_swap(float %p) {
1191 ; CHECK-LABEL: @fneg_ule_swap(
1192 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1193 ; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ule float [[A]], 0.000000e+00
1194 ; CHECK-NEXT: ret i1 [[CMP]]
1196 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1197 %fneg = fneg float %a
1198 %cmp = fcmp nnan ule float %a, %fneg
1202 define i1 @fneg_une_swap(float %p) {
1203 ; CHECK-LABEL: @fneg_une_swap(
1204 ; CHECK-NEXT: [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1205 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf une float [[A]], 0.000000e+00
1206 ; CHECK-NEXT: ret i1 [[CMP]]
1208 %a = fadd float %p, %p ; thwart complexity-based canonicalization
1209 %fneg = fneg float %a
1210 %cmp = fcmp ninf une float %a, %fneg