[SLP] Add cost model for `llvm.powi.*` intrinsics
[llvm-project.git] / llvm / test / Transforms / InstCombine / fcmp.ll
blob731174e87c71652d7d04a4a6accfcc6d9780b9c2
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
18   ret i1 %cmp
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
28   ret i1 %cmp
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>
38   ret <2 x i1> %cmp
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.
49   ret i1 %cmp
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.
60   ret i1 %cmp
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
70   ret i1 %cmp
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]]
78   %neg = fneg float %x
79   %cmp = fcmp ogt float %neg, 1.0
80   ret i1 %cmp
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>
90   ret <2 x i1> %cmp
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>
100   ret <2 x i1> %cmp
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>
110   ret <2 x i1> %cmp
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
122   ret i1 %r
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
132   ret i1 %r
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>
144   ret <2 x i1> %r
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
155   ret i1 %cmp
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
166   ret i1 %cmp
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
177   ret i1 %cmp
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
188   ret i1 %cmp
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
199   ret <2 x i1> %cmp
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
210   ret <2 x i1> %cmp
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
221   ret <2 x i1> %cmp
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
232   ret <2 x i1> %cmp
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
243   ret <2 x i1> %cmp
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
254   ret <2 x i1> %cmp
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
265   ret <2 x i1> %cmp
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
275   ret i1 %cmp
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
288   ret float %conv2
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
298   ret i1 %cmp
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
307   ret i1 %cmp
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
317   ret <2 x i1> %cmp
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
327   ret <2 x i1> %cmp
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
337   ret i1 %cmp
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
347   ret i1 %cmp
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
357   ret i1 %cmp
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
367   ret i1 %cmp
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
376   ret <2 x i1> %cmp
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
386   ret i1 %cmp
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
396   ret i1 %cmp
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
406   ret i1 %cmp
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
416   ret <2 x i1> %cmp
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
426   ret <2 x i1> %cmp
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
436   ret <2 x i1> %cmp
439 ; Don't crash.
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
450   ret i32 %conv
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
460   ret i32 %conv
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
469   ret i32 %conv
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
482   ret i1 %cmp
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
490   ret i1 %cmp
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
501   ret i1 %cmp
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
512   ret i1 %cmp
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
523   ret i1 %cmp
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
534   ret i1 %cmp
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
546   ret i1 %cmp
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
558   ret i1 %cmp
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
570   ret i1 %cmp
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>
581   ret <2 x i1> %cmp
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
592   ret i1 %r
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
603   ret i1 %r
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
614   ret i1 %r
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
625   ret i1 %r
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>
638   ret <2 x i1> %r
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
651   ret i1 %r
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
662   ret i1 %r
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
673   ret i1 %r
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
684   ret i1 %r
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
699   ret i1 %r
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
712   ret i1 %r
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
725   ret i1 %r
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
738   ret i1 %r
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>
747   ret <2 x i1> %r
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
760   ret i1 %r
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
770   ret i1 %r
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
779   ret i1 %r
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>
790   ret <2 x i1> %r
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
803   ret i1 %r
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
814   ret i1 %r
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
825   ret i1 %r
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>
836   ret <2 x i1> %r
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
849   ret i1 %r
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
860   ret i1 %r
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
871   ret i1 %r
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
881   ret i1 %r
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
891   ret i1 %r
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
901   ret i1 %cmp
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]]
909   %fneg = fneg half %a
910   %cmp = fcmp fast ogt half %fneg, %a
911   ret i1 %cmp
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
921   ret <2 x i1> %cmp
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
934   ret i1 %cmp
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
944   ret i1 %cmp
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
954   ret i1 %cmp
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
964   ret i1 %cmp
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
974   ret i1 %cmp
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]]
982   %fneg = fneg half %a
983   %cmp = fcmp fast ueq half %fneg, %a
984   ret i1 %cmp
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
994   ret <2 x i1> %cmp
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
1007   ret i1 %cmp
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
1017   ret i1 %cmp
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
1027   ret i1 %cmp
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
1037   ret i1 %cmp
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
1049   ret i1 %cmp
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
1061   ret i1 %cmp
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
1073   ret <2 x i1> %cmp
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
1088   ret i1 %cmp
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
1100   ret i1 %cmp
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
1112   ret i1 %cmp
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
1124   ret i1 %cmp
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
1136   ret i1 %cmp
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
1148   ret i1 %cmp
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
1160   ret <2 x i1> %cmp
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
1175   ret i1 %cmp
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
1187   ret i1 %cmp
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
1199   ret i1 %cmp
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
1211   ret i1 %cmp