Revert "[InstCombine] Support gep nuw in icmp folds" (#118698)
[llvm-project.git] / llvm / test / Transforms / InstCombine / fcmp.ll
blob119cffd73c662c2dfa5be1ea54ee11bfc66f0fe6
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 declare void @use(float)
12 define i1 @fpext_fpext(float %x, float %y) {
13 ; CHECK-LABEL: @fpext_fpext(
14 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
15 ; CHECK-NEXT:    ret i1 [[CMP]]
17   %ext1 = fpext float %x to double
18   %ext2 = fpext float %y to double
19   %cmp = fcmp nnan ogt double %ext1, %ext2
20   ret i1 %cmp
23 define i1 @fpext_constant(float %a) {
24 ; CHECK-LABEL: @fpext_constant(
25 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ogt float [[A:%.*]], 1.000000e+00
26 ; CHECK-NEXT:    ret i1 [[CMP]]
28   %ext = fpext float %a to double
29   %cmp = fcmp ninf ogt double %ext, 1.000000e+00
30   ret i1 %cmp
33 define <2 x i1> @fpext_constant_vec_splat(<2 x half> %a) {
34 ; CHECK-LABEL: @fpext_constant_vec_splat(
35 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ole <2 x half> [[A:%.*]], splat (half 0xH5140)
36 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
38   %ext = fpext <2 x half> %a to <2 x double>
39   %cmp = fcmp nnan ole <2 x double> %ext, <double 42.0, double 42.0>
40   ret <2 x i1> %cmp
43 define i1 @fpext_constant_lossy(float %a) {
44 ; CHECK-LABEL: @fpext_constant_lossy(
45 ; CHECK-NEXT:    [[EXT:%.*]] = fpext float [[A:%.*]] to double
46 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x3FF0000000000001
47 ; CHECK-NEXT:    ret i1 [[CMP]]
49   %ext = fpext float %a to double
50   %cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float.
51   ret i1 %cmp
54 define i1 @fpext_constant_denorm(float %a) {
55 ; CHECK-LABEL: @fpext_constant_denorm(
56 ; CHECK-NEXT:    [[EXT:%.*]] = fpext float [[A:%.*]] to double
57 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x36A0000000000000
58 ; CHECK-NEXT:    ret i1 [[CMP]]
60   %ext = fpext float %a to double
61   %cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float.
62   ret i1 %cmp
65 define i1 @fneg_constant_swap_pred(float %x) {
66 ; CHECK-LABEL: @fneg_constant_swap_pred(
67 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[X:%.*]], -1.000000e+00
68 ; CHECK-NEXT:    ret i1 [[CMP]]
70   %neg = fsub float -0.0, %x
71   %cmp = fcmp ogt float %neg, 1.0
72   ret i1 %cmp
75 define i1 @unary_fneg_constant_swap_pred(float %x) {
76 ; CHECK-LABEL: @unary_fneg_constant_swap_pred(
77 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[X:%.*]], -1.000000e+00
78 ; CHECK-NEXT:    ret i1 [[CMP]]
80   %neg = fneg float %x
81   %cmp = fcmp ogt float %neg, 1.0
82   ret i1 %cmp
85 define <2 x i1> @fneg_constant_swap_pred_vec(<2 x float> %x) {
86 ; CHECK-LABEL: @fneg_constant_swap_pred_vec(
87 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00>
88 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
90   %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
91   %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>
92   ret <2 x i1> %cmp
95 define <2 x i1> @unary_fneg_constant_swap_pred_vec(<2 x float> %x) {
96 ; CHECK-LABEL: @unary_fneg_constant_swap_pred_vec(
97 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00>
98 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
100   %neg = fneg <2 x float> %x
101   %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>
102   ret <2 x i1> %cmp
105 define <2 x i1> @fneg_constant_swap_pred_vec_poison(<2 x float> %x) {
106 ; CHECK-LABEL: @fneg_constant_swap_pred_vec_poison(
107 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00>
108 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
110   %neg = fsub <2 x float> <float poison, float -0.0>, %x
111   %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>
112   ret <2 x i1> %cmp
115 ; The new fcmp should have the same FMF as the original.
117 define i1 @fneg_fmf(float %x) {
118 ; CHECK-LABEL: @fneg_fmf(
119 ; CHECK-NEXT:    [[R:%.*]] = fcmp fast oeq float [[X:%.*]], -4.200000e+01
120 ; CHECK-NEXT:    ret i1 [[R]]
122   %n = fsub fast float -0.0, %x
123   %r = fcmp fast oeq float %n, 42.0
124   ret i1 %r
127 define i1 @unary_fneg_fmf(float %x) {
128 ; CHECK-LABEL: @unary_fneg_fmf(
129 ; CHECK-NEXT:    [[R:%.*]] = fcmp fast oeq float [[X:%.*]], -4.200000e+01
130 ; CHECK-NEXT:    ret i1 [[R]]
132   %n = fneg fast float %x
133   %r = fcmp fast oeq float %n, 42.0
134   ret i1 %r
137 ; The new fcmp should have the same FMF as the original, vector edition.
139 define <2 x i1> @fcmp_fneg_fmf_vec(<2 x float> %x) {
140 ; CHECK-LABEL: @fcmp_fneg_fmf_vec(
141 ; CHECK-NEXT:    [[R:%.*]] = fcmp reassoc nnan ule <2 x float> [[X:%.*]], <float -4.200000e+01, float 1.900000e+01>
142 ; CHECK-NEXT:    ret <2 x i1> [[R]]
144   %n = fsub nsz <2 x float> zeroinitializer, %x
145   %r = fcmp nnan reassoc uge <2 x float> %n, <float 42.0, float -19.0>
146   ret <2 x i1> %r
149 define i1 @fneg_fneg_swap_pred(float %x, float %y) {
150 ; CHECK-LABEL: @fneg_fneg_swap_pred(
151 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
152 ; CHECK-NEXT:    ret i1 [[CMP]]
154   %neg1 = fsub float -0.0, %x
155   %neg2 = fsub float -0.0, %y
156   %cmp = fcmp nnan olt float %neg1, %neg2
157   ret i1 %cmp
160 define i1 @unary_fneg_unary_fneg_swap_pred(float %x, float %y) {
161 ; CHECK-LABEL: @unary_fneg_unary_fneg_swap_pred(
162 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
163 ; CHECK-NEXT:    ret i1 [[CMP]]
165   %neg1 = fneg float %x
166   %neg2 = fneg float %y
167   %cmp = fcmp nnan olt float %neg1, %neg2
168   ret i1 %cmp
171 define i1 @unary_fneg_fneg_swap_pred(float %x, float %y) {
172 ; CHECK-LABEL: @unary_fneg_fneg_swap_pred(
173 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
174 ; CHECK-NEXT:    ret i1 [[CMP]]
176   %neg1 = fneg float %x
177   %neg2 = fsub float -0.0, %y
178   %cmp = fcmp nnan olt float %neg1, %neg2
179   ret i1 %cmp
182 define i1 @fneg_unary_fneg_swap_pred(float %x, float %y) {
183 ; CHECK-LABEL: @fneg_unary_fneg_swap_pred(
184 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ogt float [[X:%.*]], [[Y:%.*]]
185 ; CHECK-NEXT:    ret i1 [[CMP]]
187   %neg1 = fsub float -0.0, %x
188   %neg2 = fneg float %y
189   %cmp = fcmp nnan olt float %neg1, %neg2
190   ret i1 %cmp
193 define <2 x i1> @fneg_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
194 ; CHECK-LABEL: @fneg_fneg_swap_pred_vec(
195 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]]
196 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
198   %neg1 = fsub <2 x float> <float -0.0, float -0.0>, %x
199   %neg2 = fsub <2 x float> <float -0.0, float -0.0>, %y
200   %cmp = fcmp ninf olt <2 x float> %neg1, %neg2
201   ret <2 x i1> %cmp
204 define <2 x i1> @unary_fneg_unary_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
205 ; CHECK-LABEL: @unary_fneg_unary_fneg_swap_pred_vec(
206 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]]
207 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
209   %neg1 = fneg <2 x float> %x
210   %neg2 = fneg <2 x float> %y
211   %cmp = fcmp ninf olt <2 x float> %neg1, %neg2
212   ret <2 x i1> %cmp
215 define <2 x i1> @unary_fneg_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
216 ; CHECK-LABEL: @unary_fneg_fneg_swap_pred_vec(
217 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]]
218 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
220   %neg1 = fneg <2 x float> %x
221   %neg2 = fsub <2 x float> <float -0.0, float -0.0>, %y
222   %cmp = fcmp ninf olt <2 x float> %neg1, %neg2
223   ret <2 x i1> %cmp
226 define <2 x i1> @fneg_unary_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
227 ; CHECK-LABEL: @fneg_unary_fneg_swap_pred_vec(
228 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ogt <2 x float> [[X:%.*]], [[Y:%.*]]
229 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
231   %neg1 = fsub <2 x float> <float -0.0, float -0.0>, %x
232   %neg2 = fneg <2 x float> %y
233   %cmp = fcmp ninf olt <2 x float> %neg1, %neg2
234   ret <2 x i1> %cmp
237 define <2 x i1> @fneg_fneg_swap_pred_vec_poison(<2 x float> %x, <2 x float> %y) {
238 ; CHECK-LABEL: @fneg_fneg_swap_pred_vec_poison(
239 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]]
240 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
242   %neg1 = fsub <2 x float> <float -0.0, float poison>, %x
243   %neg2 = fsub <2 x float> <float poison, float -0.0>, %y
244   %cmp = fcmp olt <2 x float> %neg1, %neg2
245   ret <2 x i1> %cmp
248 define <2 x i1> @unary_fneg_fneg_swap_pred_vec_poison(<2 x float> %x, <2 x float> %y) {
249 ; CHECK-LABEL: @unary_fneg_fneg_swap_pred_vec_poison(
250 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]]
251 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
253   %neg1 = fneg <2 x float> %x
254   %neg2 = fsub <2 x float> <float poison, float -0.0>, %y
255   %cmp = fcmp olt <2 x float> %neg1, %neg2
256   ret <2 x i1> %cmp
259 define <2 x i1> @fneg_unary_fneg_swap_pred_vec_poison(<2 x float> %x, <2 x float> %y) {
260 ; CHECK-LABEL: @fneg_unary_fneg_swap_pred_vec_poison(
261 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]]
262 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
264   %neg1 = fsub <2 x float> <float -0.0, float poison>, %x
265   %neg2 = fneg <2 x float> %y
266   %cmp = fcmp olt <2 x float> %neg1, %neg2
267   ret <2 x i1> %cmp
270 define i1 @test7(float %x) {
271 ; CHECK-LABEL: @test7(
272 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[X:%.*]], 0.000000e+00
273 ; CHECK-NEXT:    ret i1 [[CMP]]
275   %ext = fpext float %x to ppc_fp128
276   %cmp = fcmp ogt ppc_fp128 %ext, 0xM00000000000000000000000000000000
277   ret i1 %cmp
280 define float @test8(float %x) {
281 ; CHECK-LABEL: @test8(
282 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
283 ; CHECK-NEXT:    [[CONV2:%.*]] = uitofp i1 [[CMP]] to float
284 ; CHECK-NEXT:    ret float [[CONV2]]
286   %conv = fpext float %x to double
287   %cmp = fcmp olt double %conv, 0.000000e+00
288   %conv1 = zext i1 %cmp to i32
289   %conv2 = sitofp i32 %conv1 to float
290   ret float %conv2
291 ; Float comparison to zero shouldn't cast to double.
294 define i1 @fabs_uge(double %a) {
295 ; CHECK-LABEL: @fabs_uge(
296 ; CHECK-NEXT:    ret i1 true
298   %call = call double @llvm.fabs.f64(double %a)
299   %cmp = fcmp uge double %call, 0.0
300   ret i1 %cmp
303 define i1 @fabs_olt(half %a) {
304 ; CHECK-LABEL: @fabs_olt(
305 ; CHECK-NEXT:    ret i1 false
307   %call = call half @llvm.fabs.f16(half %a)
308   %cmp = fcmp olt half %call, 0.0
309   ret i1 %cmp
312 define <2 x i1> @fabs_ole(<2 x float> %a) {
313 ; CHECK-LABEL: @fabs_ole(
314 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf oeq <2 x float> [[A:%.*]], zeroinitializer
315 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
317   %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
318   %cmp = fcmp ninf ole <2 x float> %call, zeroinitializer
319   ret <2 x i1> %cmp
322 define <2 x i1> @fabs_ule(<2 x float> %a) {
323 ; CHECK-LABEL: @fabs_ule(
324 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf arcp ueq <2 x float> [[A:%.*]], zeroinitializer
325 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
327   %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
328   %cmp = fcmp ninf arcp ule <2 x float> %call, zeroinitializer
329   ret <2 x i1> %cmp
332 define i1 @fabs_ogt(double %a) {
333 ; CHECK-LABEL: @fabs_ogt(
334 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp reassoc one double [[A:%.*]], 0.000000e+00
335 ; CHECK-NEXT:    ret i1 [[CMP]]
337   %call = call double @llvm.fabs.f64(double %a)
338   %cmp = fcmp reassoc ogt double %call, 0.0
339   ret i1 %cmp
342 define i1 @fabs_ugt(double %a) {
343 ; CHECK-LABEL: @fabs_ugt(
344 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp reassoc ninf une double [[A:%.*]], 0.000000e+00
345 ; CHECK-NEXT:    ret i1 [[CMP]]
347   %call = call double @llvm.fabs.f64(double %a)
348   %cmp = fcmp ninf reassoc ugt double %call, 0.0
349   ret i1 %cmp
352 define i1 @fabs_oge(double %a) {
353 ; CHECK-LABEL: @fabs_oge(
354 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp afn ord double [[A:%.*]], 0.000000e+00
355 ; CHECK-NEXT:    ret i1 [[CMP]]
357   %call = call double @llvm.fabs.f64(double %a)
358   %cmp = fcmp afn oge double %call, 0.0
359   ret i1 %cmp
362 define i1 @fabs_ult(double %a) {
363 ; CHECK-LABEL: @fabs_ult(
364 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp reassoc arcp uno double [[A:%.*]], 0.000000e+00
365 ; CHECK-NEXT:    ret i1 [[CMP]]
367   %call = call double @llvm.fabs.f64(double %a)
368   %cmp = fcmp reassoc arcp ult double %call, 0.0
369   ret i1 %cmp
372 define <2 x i1> @fabs_ult_nnan(<2 x float> %a) {
373 ; CHECK-LABEL: @fabs_ult_nnan(
374 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
376   %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
377   %cmp = fcmp nnan reassoc arcp ult <2 x float> %call, zeroinitializer
378   ret <2 x i1> %cmp
381 define i1 @fabs_une(half %a) {
382 ; CHECK-LABEL: @fabs_une(
383 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf une half [[A:%.*]], 0xH0000
384 ; CHECK-NEXT:    ret i1 [[CMP]]
386   %call = call half @llvm.fabs.f16(half %a)
387   %cmp = fcmp ninf une half %call, 0.0
388   ret i1 %cmp
391 define i1 @fabs_oeq(double %a) {
392 ; CHECK-LABEL: @fabs_oeq(
393 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp reassoc ninf oeq double [[A:%.*]], 0.000000e+00
394 ; CHECK-NEXT:    ret i1 [[CMP]]
396   %call = call double @llvm.fabs.f64(double %a)
397   %cmp = fcmp ninf reassoc oeq double %call, 0.0
398   ret i1 %cmp
401 define i1 @fabs_one(double %a) {
402 ; CHECK-LABEL: @fabs_one(
403 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast one double [[A:%.*]], 0.000000e+00
404 ; CHECK-NEXT:    ret i1 [[CMP]]
406   %call = call double @llvm.fabs.f64(double %a)
407   %cmp = fcmp fast one double %call, 0.0
408   ret i1 %cmp
411 define <2 x i1> @fabs_ueq(<2 x float> %a) {
412 ; CHECK-LABEL: @fabs_ueq(
413 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp arcp ueq <2 x float> [[A:%.*]], zeroinitializer
414 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
416   %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
417   %cmp = fcmp arcp ueq <2 x float> %call, zeroinitializer
418   ret <2 x i1> %cmp
421 define <2 x i1> @fabs_ord(<2 x float> %a) {
422 ; CHECK-LABEL: @fabs_ord(
423 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp arcp ord <2 x float> [[A:%.*]], zeroinitializer
424 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
426   %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
427   %cmp = fcmp arcp ord <2 x float> %call, zeroinitializer
428   ret <2 x i1> %cmp
431 define <2 x i1> @fabs_uno(<2 x float> %a) {
432 ; CHECK-LABEL: @fabs_uno(
433 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp arcp uno <2 x float> [[A:%.*]], zeroinitializer
434 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
436   %call = call <2 x float> @llvm.fabs.v2f32(<2 x float> %a)
437   %cmp = fcmp arcp uno <2 x float> %call, zeroinitializer
438   ret <2 x i1> %cmp
441 ; Don't crash.
442 define i32 @test17(double %a, ptr %p) {
443 ; CHECK-LABEL: @test17(
444 ; CHECK-NEXT:    [[CALL:%.*]] = tail call double [[P:%.*]](double [[A:%.*]])
445 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq double [[CALL]], 0.000000e+00
446 ; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
447 ; CHECK-NEXT:    ret i32 [[CONV]]
449   %call = tail call double %p(double %a)
450   %cmp = fcmp ueq double %call, 0.000000e+00
451   %conv = zext i1 %cmp to i32
452   ret i32 %conv
455 ; Can fold fcmp with undef on one side by choosing NaN for the undef
456 define i32 @test18_undef_unordered(float %a) {
457 ; CHECK-LABEL: @test18_undef_unordered(
458 ; CHECK-NEXT:    ret i32 1
460   %cmp = fcmp ueq float %a, undef
461   %conv = zext i1 %cmp to i32
462   ret i32 %conv
464 ; Can fold fcmp with undef on one side by choosing NaN for the undef
465 define i32 @test18_undef_ordered(float %a) {
466 ; CHECK-LABEL: @test18_undef_ordered(
467 ; CHECK-NEXT:    ret i32 0
469   %cmp = fcmp oeq float %a, undef
470   %conv = zext i1 %cmp to i32
471   ret i32 %conv
474 ; Can fold fcmp with undef on both side
475 ;   fcmp u_pred undef, undef -> true
476 ;   fcmp o_pred undef, undef -> false
477 ; because whatever you choose for the first undef
478 ; you can choose NaN for the other undef
479 define i1 @test19_undef_unordered() {
480 ; CHECK-LABEL: @test19_undef_unordered(
481 ; CHECK-NEXT:    ret i1 true
483   %cmp = fcmp ueq float undef, undef
484   ret i1 %cmp
487 define i1 @test19_undef_ordered() {
488 ; CHECK-LABEL: @test19_undef_ordered(
489 ; CHECK-NEXT:    ret i1 false
491   %cmp = fcmp oeq float undef, undef
492   ret i1 %cmp
495 ; Can fold 1.0 / X < 0.0 --> X < 0 with ninf
496 define i1 @test20_recipX_olt_0(float %X) {
497 ; CHECK-LABEL: @test20_recipX_olt_0(
498 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf olt float [[X:%.*]], 0.000000e+00
499 ; CHECK-NEXT:    ret i1 [[CMP]]
501   %div = fdiv ninf float 1.0, %X
502   %cmp = fcmp ninf olt float %div, 0.0
503   ret i1 %cmp
506 ; Can fold -2.0 / X <= 0.0 --> X >= 0 with ninf
507 define i1 @test21_recipX_ole_0(float %X) {
508 ; CHECK-LABEL: @test21_recipX_ole_0(
509 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf oge float [[X:%.*]], 0.000000e+00
510 ; CHECK-NEXT:    ret i1 [[CMP]]
512   %div = fdiv ninf float -2.0, %X
513   %cmp = fcmp ninf ole float %div, 0.0
514   ret i1 %cmp
517 ; Can fold 2.0 / X > 0.0 --> X > 0 with ninf
518 define i1 @test22_recipX_ogt_0(float %X) {
519 ; CHECK-LABEL: @test22_recipX_ogt_0(
520 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ogt float [[X:%.*]], 0.000000e+00
521 ; CHECK-NEXT:    ret i1 [[CMP]]
523   %div = fdiv ninf float 2.0, %X
524   %cmp = fcmp ninf ogt float %div, 0.0
525   ret i1 %cmp
528 ; Can fold -1.0 / X >= 0.0 --> X <= 0 with ninf
529 define i1 @test23_recipX_oge_0(float %X) {
530 ; CHECK-LABEL: @test23_recipX_oge_0(
531 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ole float [[X:%.*]], 0.000000e+00
532 ; CHECK-NEXT:    ret i1 [[CMP]]
534   %div = fdiv ninf float -1.0, %X
535   %cmp = fcmp ninf oge float %div, 0.0
536   ret i1 %cmp
539 ; Do not fold 1.0 / X > 0.0 when ninf is missing
540 define i1 @test24_recipX_noninf_cmp(float %X) {
541 ; CHECK-LABEL: @test24_recipX_noninf_cmp(
542 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv ninf float 2.000000e+00, [[X:%.*]]
543 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[DIV]], 0.000000e+00
544 ; CHECK-NEXT:    ret i1 [[CMP]]
546   %div = fdiv ninf float 2.0, %X
547   %cmp = fcmp ogt float %div, 0.0
548   ret i1 %cmp
551 ; Do not fold 1.0 / X > 0.0 when ninf is missing
552 define i1 @test25_recipX_noninf_div(float %X) {
553 ; CHECK-LABEL: @test25_recipX_noninf_div(
554 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float 2.000000e+00, [[X:%.*]]
555 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ogt float [[DIV]], 0.000000e+00
556 ; CHECK-NEXT:    ret i1 [[CMP]]
558   %div = fdiv float 2.0, %X
559   %cmp = fcmp ninf ogt float %div, 0.0
560   ret i1 %cmp
563 ; Do not fold 1.0 / X > 0.0 with unordered predicates
564 define i1 @test26_recipX_unorderd(float %X) {
565 ; CHECK-LABEL: @test26_recipX_unorderd(
566 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv ninf float 2.000000e+00, [[X:%.*]]
567 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ugt float [[DIV]], 0.000000e+00
568 ; CHECK-NEXT:    ret i1 [[CMP]]
570   %div = fdiv ninf float 2.0, %X
571   %cmp = fcmp ninf ugt float %div, 0.0
572   ret i1 %cmp
575 ; Fold <-1.0, -1.0> / X > <-0.0, -0.0>
576 define <2 x i1> @test27_recipX_gt_vecsplat(<2 x float> %X) {
577 ; CHECK-LABEL: @test27_recipX_gt_vecsplat(
578 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf olt <2 x float> [[X:%.*]], zeroinitializer
579 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
581   %div = fdiv ninf <2 x float> <float -1.0, float -1.0>, %X
582   %cmp = fcmp ninf ogt <2 x float> %div, <float -0.0, float -0.0>
583   ret <2 x i1> %cmp
586 define i1 @is_signbit_set(double %x) {
587 ; CHECK-LABEL: @is_signbit_set(
588 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast double [[X:%.*]] to i64
589 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i64 [[TMP1]], 0
590 ; CHECK-NEXT:    ret i1 [[R]]
592   %s = call double @llvm.copysign.f64(double 1.0, double %x)
593   %r = fcmp olt double %s, 0.0
594   ret i1 %r
597 define i1 @is_signbit_set_1(double %x) {
598 ; CHECK-LABEL: @is_signbit_set_1(
599 ; CHECK-NEXT:    [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]])
600 ; CHECK-NEXT:    [[R:%.*]] = fcmp ult double [[S]], 0.000000e+00
601 ; CHECK-NEXT:    ret i1 [[R]]
603   %s = call double @llvm.copysign.f64(double 1.0, double %x)
604   %r = fcmp ult double %s, 0.0
605   ret i1 %r
608 define i1 @is_signbit_set_2(double %x) {
609 ; CHECK-LABEL: @is_signbit_set_2(
610 ; CHECK-NEXT:    [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]])
611 ; CHECK-NEXT:    [[R:%.*]] = fcmp ole double [[S]], 0.000000e+00
612 ; CHECK-NEXT:    ret i1 [[R]]
614   %s = call double @llvm.copysign.f64(double 1.0, double %x)
615   %r = fcmp ole double %s, 0.0
616   ret i1 %r
619 define i1 @is_signbit_set_3(double %x) {
620 ; CHECK-LABEL: @is_signbit_set_3(
621 ; CHECK-NEXT:    [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]])
622 ; CHECK-NEXT:    [[R:%.*]] = fcmp ule double [[S]], 0.000000e+00
623 ; CHECK-NEXT:    ret i1 [[R]]
625   %s = call double @llvm.copysign.f64(double 1.0, double %x)
626   %r = fcmp ule double %s, 0.0
627   ret i1 %r
630 ; Vectors are ok; the sign of zero in the compare doesn't matter; the copysign constant can be any non-zero number.
632 define <2 x i1> @is_signbit_set_anyzero(<2 x double> %x) {
633 ; CHECK-LABEL: @is_signbit_set_anyzero(
634 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x double> [[X:%.*]] to <2 x i64>
635 ; CHECK-NEXT:    [[R:%.*]] = icmp slt <2 x i64> [[TMP1]], zeroinitializer
636 ; CHECK-NEXT:    ret <2 x i1> [[R]]
638   %s = call <2 x double> @llvm.copysign.v2f64(<2 x double> <double 42.0, double 42.0>, <2 x double> %x)
639   %r = fcmp olt <2 x double> %s, <double -0.0, double 0.0>
640   ret <2 x i1> %r
643 ; TODO: Handle different predicates.
645 define i1 @is_signbit_clear(double %x) {
646 ; CHECK-LABEL: @is_signbit_clear(
647 ; CHECK-NEXT:    [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]])
648 ; CHECK-NEXT:    [[R:%.*]] = fcmp ogt double [[S]], 0.000000e+00
649 ; CHECK-NEXT:    ret i1 [[R]]
651   %s = call double @llvm.copysign.f64(double -42.0, double %x)
652   %r = fcmp ogt double %s, 0.0
653   ret i1 %r
656 define i1 @is_signbit_clear_1(double %x) {
657 ; CHECK-LABEL: @is_signbit_clear_1(
658 ; CHECK-NEXT:    [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]])
659 ; CHECK-NEXT:    [[R:%.*]] = fcmp ugt double [[S]], 0.000000e+00
660 ; CHECK-NEXT:    ret i1 [[R]]
662   %s = call double @llvm.copysign.f64(double -42.0, double %x)
663   %r = fcmp ugt double %s, 0.0
664   ret i1 %r
667 define i1 @is_signbit_clear_2(double %x) {
668 ; CHECK-LABEL: @is_signbit_clear_2(
669 ; CHECK-NEXT:    [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]])
670 ; CHECK-NEXT:    [[R:%.*]] = fcmp oge double [[S]], 0.000000e+00
671 ; CHECK-NEXT:    ret i1 [[R]]
673   %s = call double @llvm.copysign.f64(double -42.0, double %x)
674   %r = fcmp oge double %s, 0.0
675   ret i1 %r
678 define i1 @is_signbit_clear_3(double %x) {
679 ; CHECK-LABEL: @is_signbit_clear_3(
680 ; CHECK-NEXT:    [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]])
681 ; CHECK-NEXT:    [[R:%.*]] = fcmp uge double [[S]], 0.000000e+00
682 ; CHECK-NEXT:    ret i1 [[R]]
684   %s = call double @llvm.copysign.f64(double -42.0, double %x)
685   %r = fcmp uge double %s, 0.0
686   ret i1 %r
689 ; Negative test - uses
691 define i1 @is_signbit_set_extra_use(double %x, ptr %p) {
692 ; CHECK-LABEL: @is_signbit_set_extra_use(
693 ; CHECK-NEXT:    [[S:%.*]] = call double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]])
694 ; CHECK-NEXT:    store double [[S]], ptr [[P:%.*]], align 8
695 ; CHECK-NEXT:    [[R:%.*]] = fcmp olt double [[S]], 0.000000e+00
696 ; CHECK-NEXT:    ret i1 [[R]]
698   %s = call double @llvm.copysign.f64(double 1.0, double %x)
699   store double %s, ptr %p
700   %r = fcmp olt double %s, 0.0
701   ret i1 %r
704 ; TODO: Handle non-zero compare constant.
706 define i1 @is_signbit_clear_nonzero(double %x) {
707 ; CHECK-LABEL: @is_signbit_clear_nonzero(
708 ; CHECK-NEXT:    [[S:%.*]] = call double @llvm.copysign.f64(double 4.200000e+01, double [[X:%.*]])
709 ; CHECK-NEXT:    [[R:%.*]] = fcmp ogt double [[S]], 1.000000e+00
710 ; CHECK-NEXT:    ret i1 [[R]]
712   %s = call double @llvm.copysign.f64(double -42.0, double %x)
713   %r = fcmp ogt double %s, 1.0
714   ret i1 %r
717 ; TODO: Handle zero copysign constant.
719 define i1 @is_signbit_set_simplify_zero(double %x) {
720 ; CHECK-LABEL: @is_signbit_set_simplify_zero(
721 ; CHECK-NEXT:    ret i1 false
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:    ret i1 false
734   %s = call double @llvm.copysign.f64(double 0xffffffffffffffff, double %x)
735   %r = fcmp ogt double %s, 0.0
736   ret i1 %r
739 define <2 x i1> @lossy_oeq(<2 x float> %x) {
740 ; CHECK-LABEL: @lossy_oeq(
741 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
743   %e = fpext <2 x float> %x to <2 x double>
744   %r = fcmp oeq <2 x double> %e, <double 0.1, double 0.1>
745   ret <2 x i1> %r
748 define i1 @lossy_one(float %x, ptr %p) {
749 ; CHECK-LABEL: @lossy_one(
750 ; CHECK-NEXT:    [[E:%.*]] = fpext float [[X:%.*]] to double
751 ; CHECK-NEXT:    store double [[E]], ptr [[P:%.*]], align 8
752 ; CHECK-NEXT:    [[R:%.*]] = fcmp ord float [[X]], 0.000000e+00
753 ; CHECK-NEXT:    ret i1 [[R]]
755   %e = fpext float %x to double
756   store double %e, ptr %p
757   %r = fcmp one double %e, 0.1
758   ret i1 %r
761 define i1 @lossy_ueq(half %x) {
762 ; CHECK-LABEL: @lossy_ueq(
763 ; CHECK-NEXT:    [[R:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
764 ; CHECK-NEXT:    ret i1 [[R]]
766   %e = fpext half %x to double
767   %r = fcmp ueq double %e, 65536.0
768   ret i1 %r
771 define i1 @lossy_une(half %x) {
772 ; CHECK-LABEL: @lossy_une(
773 ; CHECK-NEXT:    ret i1 true
775   %e = fpext half %x to float
776   %r = fcmp une float %e, 2049.0
777   ret i1 %r
780 define <2 x i1> @lossy_ogt(<2 x float> %x) {
781 ; CHECK-LABEL: @lossy_ogt(
782 ; CHECK-NEXT:    [[E:%.*]] = fpext <2 x float> [[X:%.*]] to <2 x double>
783 ; CHECK-NEXT:    [[R:%.*]] = fcmp ogt <2 x double> [[E]], splat (double 1.000000e-01)
784 ; CHECK-NEXT:    ret <2 x i1> [[R]]
786   %e = fpext <2 x float> %x to <2 x double>
787   %r = fcmp ogt <2 x double> %e, <double 0.1, double 0.1>
788   ret <2 x i1> %r
791 define i1 @lossy_oge(float %x, ptr %p) {
792 ; CHECK-LABEL: @lossy_oge(
793 ; CHECK-NEXT:    [[E:%.*]] = fpext float [[X:%.*]] to double
794 ; CHECK-NEXT:    store double [[E]], ptr [[P:%.*]], align 8
795 ; CHECK-NEXT:    [[R:%.*]] = fcmp oge double [[E]], 1.000000e-01
796 ; CHECK-NEXT:    ret i1 [[R]]
798   %e = fpext float %x to double
799   store double %e, ptr %p
800   %r = fcmp oge double %e, 0.1
801   ret i1 %r
804 define i1 @lossy_olt(half %x) {
805 ; CHECK-LABEL: @lossy_olt(
806 ; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to double
807 ; CHECK-NEXT:    [[R:%.*]] = fcmp olt double [[E]], 6.553600e+04
808 ; CHECK-NEXT:    ret i1 [[R]]
810   %e = fpext half %x to double
811   %r = fcmp olt double %e, 65536.0
812   ret i1 %r
815 define i1 @lossy_ole(half %x) {
816 ; CHECK-LABEL: @lossy_ole(
817 ; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to float
818 ; CHECK-NEXT:    [[R:%.*]] = fcmp ole float [[E]], 2.049000e+03
819 ; CHECK-NEXT:    ret i1 [[R]]
821   %e = fpext half %x to float
822   %r = fcmp ole float %e, 2049.0
823   ret i1 %r
826 define <2 x i1> @lossy_ugt(<2 x float> %x) {
827 ; CHECK-LABEL: @lossy_ugt(
828 ; CHECK-NEXT:    [[E:%.*]] = fpext <2 x float> [[X:%.*]] to <2 x double>
829 ; CHECK-NEXT:    [[R:%.*]] = fcmp ugt <2 x double> [[E]], splat (double 1.000000e-01)
830 ; CHECK-NEXT:    ret <2 x i1> [[R]]
832   %e = fpext <2 x float> %x to <2 x double>
833   %r = fcmp ugt <2 x double> %e, <double 0.1, double 0.1>
834   ret <2 x i1> %r
837 define i1 @lossy_uge(float %x, ptr %p) {
838 ; CHECK-LABEL: @lossy_uge(
839 ; CHECK-NEXT:    [[E:%.*]] = fpext float [[X:%.*]] to double
840 ; CHECK-NEXT:    store double [[E]], ptr [[P:%.*]], align 8
841 ; CHECK-NEXT:    [[R:%.*]] = fcmp uge double [[E]], 1.000000e-01
842 ; CHECK-NEXT:    ret i1 [[R]]
844   %e = fpext float %x to double
845   store double %e, ptr %p
846   %r = fcmp uge double %e, 0.1
847   ret i1 %r
850 define i1 @lossy_ult(half %x) {
851 ; CHECK-LABEL: @lossy_ult(
852 ; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to double
853 ; CHECK-NEXT:    [[R:%.*]] = fcmp ult double [[E]], 6.553600e+04
854 ; CHECK-NEXT:    ret i1 [[R]]
856   %e = fpext half %x to double
857   %r = fcmp ult double %e, 65536.0
858   ret i1 %r
861 define i1 @lossy_ule(half %x) {
862 ; CHECK-LABEL: @lossy_ule(
863 ; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to float
864 ; CHECK-NEXT:    [[R:%.*]] = fcmp ule float [[E]], 2.049000e+03
865 ; CHECK-NEXT:    ret i1 [[R]]
867   %e = fpext half %x to float
868   %r = fcmp ule float %e, 2049.0
869   ret i1 %r
872 define i1 @lossy_ord(half %x) {
873 ; CHECK-LABEL: @lossy_ord(
874 ; CHECK-NEXT:    [[R:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
875 ; CHECK-NEXT:    ret i1 [[R]]
877   %e = fpext half %x to double
878   %r = fcmp ord double %e, 65536.0
879   ret i1 %r
882 define i1 @lossy_uno(half %x) {
883 ; CHECK-LABEL: @lossy_uno(
884 ; CHECK-NEXT:    [[R:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
885 ; CHECK-NEXT:    ret i1 [[R]]
887   %e = fpext half %x to float
888   %r = fcmp uno float %e, 2049.0
889   ret i1 %r
892 define i1 @fneg_oeq(float %a) {
893 ; CHECK-LABEL: @fneg_oeq(
894 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[A:%.*]], 0.000000e+00
895 ; CHECK-NEXT:    ret i1 [[CMP]]
897   %fneg = fneg float %a
898   %cmp = fcmp oeq float %fneg, %a
899   ret i1 %cmp
902 define i1 @fneg_ogt(half %a) {
903 ; CHECK-LABEL: @fneg_ogt(
904 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast olt half [[A:%.*]], 0xH0000
905 ; CHECK-NEXT:    ret i1 [[CMP]]
907   %fneg = fneg half %a
908   %cmp = fcmp fast ogt half %fneg, %a
909   ret i1 %cmp
912 define <2 x i1> @fneg_oge(<2 x float> %a) {
913 ; CHECK-LABEL: @fneg_oge(
914 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole <2 x float> [[A:%.*]], zeroinitializer
915 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
917   %fneg = fneg fast <2 x float> %a
918   %cmp = fcmp oge <2 x float> %fneg, %a
919   ret <2 x i1> %cmp
922 define i1 @fneg_olt(float %a, ptr %q) {
923 ; CHECK-LABEL: @fneg_olt(
924 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A:%.*]]
925 ; CHECK-NEXT:    store float [[FNEG]], ptr [[Q:%.*]], align 4
926 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[A]], 0.000000e+00
927 ; CHECK-NEXT:    ret i1 [[CMP]]
929   %fneg = fneg float %a
930   store float %fneg, ptr %q
931   %cmp = fcmp olt float %fneg, %a
932   ret i1 %cmp
935 define i1 @fneg_ole(float %a) {
936 ; CHECK-LABEL: @fneg_ole(
937 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz oge float [[A:%.*]], 0.000000e+00
938 ; CHECK-NEXT:    ret i1 [[CMP]]
940   %fneg = fneg float %a
941   %cmp = fcmp nsz ole float %fneg, %a
942   ret i1 %cmp
945 define i1 @fneg_one(float %a) {
946 ; CHECK-LABEL: @fneg_one(
947 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan one float [[A:%.*]], 0.000000e+00
948 ; CHECK-NEXT:    ret i1 [[CMP]]
950   %fneg = fneg float %a
951   %cmp = fcmp nnan one float %fneg, %a
952   ret i1 %cmp
955 define i1 @fneg_ord(float %a) {
956 ; CHECK-LABEL: @fneg_ord(
957 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ord float [[A:%.*]], 0.000000e+00
958 ; CHECK-NEXT:    ret i1 [[CMP]]
960   %fneg = fneg float %a
961   %cmp = fcmp ninf ord float %fneg, %a
962   ret i1 %cmp
965 define i1 @fneg_uno(float %a) {
966 ; CHECK-LABEL: @fneg_uno(
967 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno float [[A:%.*]], 0.000000e+00
968 ; CHECK-NEXT:    ret i1 [[CMP]]
970   %fneg = fneg float %a
971   %cmp = fcmp uno float %fneg, %a
972   ret i1 %cmp
975 define i1 @fneg_ueq(half %a) {
976 ; CHECK-LABEL: @fneg_ueq(
977 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ueq half [[A:%.*]], 0xH0000
978 ; CHECK-NEXT:    ret i1 [[CMP]]
980   %fneg = fneg half %a
981   %cmp = fcmp fast ueq half %fneg, %a
982   ret i1 %cmp
985 define <2 x i1> @fneg_ugt(<2 x float> %a) {
986 ; CHECK-LABEL: @fneg_ugt(
987 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult <2 x float> [[A:%.*]], zeroinitializer
988 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
990   %fneg = fneg fast <2 x float> %a
991   %cmp = fcmp ugt <2 x float> %fneg, %a
992   ret <2 x i1> %cmp
995 define i1 @fneg_uge(float %a, ptr %q) {
996 ; CHECK-LABEL: @fneg_uge(
997 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A:%.*]]
998 ; CHECK-NEXT:    store float [[FNEG]], ptr [[Q:%.*]], align 4
999 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule float [[A]], 0.000000e+00
1000 ; CHECK-NEXT:    ret i1 [[CMP]]
1002   %fneg = fneg float %a
1003   store float %fneg, ptr %q
1004   %cmp = fcmp uge float %fneg, %a
1005   ret i1 %cmp
1008 define i1 @fneg_ult(float %a) {
1009 ; CHECK-LABEL: @fneg_ult(
1010 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz ugt float [[A:%.*]], 0.000000e+00
1011 ; CHECK-NEXT:    ret i1 [[CMP]]
1013   %fneg = fneg float %a
1014   %cmp = fcmp nsz ult float %fneg, %a
1015   ret i1 %cmp
1018 define i1 @fneg_ule(float %a) {
1019 ; CHECK-LABEL: @fneg_ule(
1020 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan uge float [[A:%.*]], 0.000000e+00
1021 ; CHECK-NEXT:    ret i1 [[CMP]]
1023   %fneg = fneg float %a
1024   %cmp = fcmp nnan ule float %fneg, %a
1025   ret i1 %cmp
1028 define i1 @fneg_une(float %a) {
1029 ; CHECK-LABEL: @fneg_une(
1030 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf une float [[A:%.*]], 0.000000e+00
1031 ; CHECK-NEXT:    ret i1 [[CMP]]
1033   %fneg = fneg float %a
1034   %cmp = fcmp ninf une float %fneg, %a
1035   ret i1 %cmp
1038 define i1 @fneg_oeq_swap(float %p) {
1039 ; CHECK-LABEL: @fneg_oeq_swap(
1040 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1041 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[A]], 0.000000e+00
1042 ; CHECK-NEXT:    ret i1 [[CMP]]
1044   %a = fadd float %p, %p ; thwart complexity-based canonicalization
1045   %fneg = fneg float %a
1046   %cmp = fcmp oeq float %a, %fneg
1047   ret i1 %cmp
1050 define i1 @fneg_ogt_swap(half %p) {
1051 ; CHECK-LABEL: @fneg_ogt_swap(
1052 ; CHECK-NEXT:    [[A:%.*]] = fadd half [[P:%.*]], [[P]]
1053 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ogt half [[A]], 0xH0000
1054 ; CHECK-NEXT:    ret i1 [[CMP]]
1056   %a = fadd half %p, %p ; thwart complexity-based canonicalization
1057   %fneg = fneg half %a
1058   %cmp = fcmp fast ogt half %a, %fneg
1059   ret i1 %cmp
1062 define <2 x i1> @fneg_oge_swap(<2 x float> %p) {
1063 ; CHECK-LABEL: @fneg_oge_swap(
1064 ; CHECK-NEXT:    [[A:%.*]] = fadd <2 x float> [[P:%.*]], [[P]]
1065 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge <2 x float> [[A]], zeroinitializer
1066 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1068   %a = fadd <2 x float> %p, %p ; thwart complexity-based canonicalization
1069   %fneg = fneg fast <2 x float> %a
1070   %cmp = fcmp oge <2 x float> %a, %fneg
1071   ret <2 x i1> %cmp
1074 define i1 @fneg_olt_swap(float %p, ptr %q) {
1075 ; CHECK-LABEL: @fneg_olt_swap(
1076 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1077 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A]]
1078 ; CHECK-NEXT:    store float [[FNEG]], ptr [[Q:%.*]], align 4
1079 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[A]], 0.000000e+00
1080 ; CHECK-NEXT:    ret i1 [[CMP]]
1082   %a = fadd float %p, %p ; thwart complexity-based canonicalization
1083   %fneg = fneg float %a
1084   store float %fneg, ptr %q
1085   %cmp = fcmp olt float %a, %fneg
1086   ret i1 %cmp
1089 define i1 @fneg_ole_swap(float %p) {
1090 ; CHECK-LABEL: @fneg_ole_swap(
1091 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1092 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz ole float [[A]], 0.000000e+00
1093 ; CHECK-NEXT:    ret i1 [[CMP]]
1095   %a = fadd float %p, %p ; thwart complexity-based canonicalization
1096   %fneg = fneg float %a
1097   %cmp = fcmp nsz ole float %a, %fneg
1098   ret i1 %cmp
1101 define i1 @fneg_one_swap(float %p) {
1102 ; CHECK-LABEL: @fneg_one_swap(
1103 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1104 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan one float [[A]], 0.000000e+00
1105 ; CHECK-NEXT:    ret i1 [[CMP]]
1107   %a = fadd float %p, %p ; thwart complexity-based canonicalization
1108   %fneg = fneg float %a
1109   %cmp = fcmp nnan one float %a, %fneg
1110   ret i1 %cmp
1113 define i1 @fneg_ord_swap(float %p) {
1114 ; CHECK-LABEL: @fneg_ord_swap(
1115 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1116 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ord float [[A]], 0.000000e+00
1117 ; CHECK-NEXT:    ret i1 [[CMP]]
1119   %a = fadd float %p, %p ; thwart complexity-based canonicalization
1120   %fneg = fneg float %a
1121   %cmp = fcmp ninf ord float %a, %fneg
1122   ret i1 %cmp
1125 define i1 @fneg_uno_swap(float %p) {
1126 ; CHECK-LABEL: @fneg_uno_swap(
1127 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1128 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno float [[A]], 0.000000e+00
1129 ; CHECK-NEXT:    ret i1 [[CMP]]
1131   %a = fadd float %p, %p ; thwart complexity-based canonicalization
1132   %fneg = fneg float %a
1133   %cmp = fcmp uno float %a, %fneg
1134   ret i1 %cmp
1137 define i1 @fneg_ueq_swap(half %p) {
1138 ; CHECK-LABEL: @fneg_ueq_swap(
1139 ; CHECK-NEXT:    [[A:%.*]] = fadd half [[P:%.*]], [[P]]
1140 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ueq half [[A]], 0xH0000
1141 ; CHECK-NEXT:    ret i1 [[CMP]]
1143   %a = fadd half %p, %p ; thwart complexity-based canonicalization
1144   %fneg = fneg half %a
1145   %cmp = fcmp fast ueq half %a, %fneg
1146   ret i1 %cmp
1149 define <2 x i1> @fneg_ugt_swap(<2 x float> %p) {
1150 ; CHECK-LABEL: @fneg_ugt_swap(
1151 ; CHECK-NEXT:    [[A:%.*]] = fadd <2 x float> [[P:%.*]], [[P]]
1152 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt <2 x float> [[A]], zeroinitializer
1153 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1155   %a = fadd <2 x float> %p, %p ; thwart complexity-based canonicalization
1156   %fneg = fneg fast <2 x float> %a
1157   %cmp = fcmp ugt <2 x float> %a, %fneg
1158   ret <2 x i1> %cmp
1161 define i1 @fneg_uge_swap(float %p, ptr %q) {
1162 ; CHECK-LABEL: @fneg_uge_swap(
1163 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1164 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[A]]
1165 ; CHECK-NEXT:    store float [[FNEG]], ptr [[Q:%.*]], align 4
1166 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[A]], 0.000000e+00
1167 ; CHECK-NEXT:    ret i1 [[CMP]]
1169   %a = fadd float %p, %p ; thwart complexity-based canonicalization
1170   %fneg = fneg float %a
1171   store float %fneg, ptr %q
1172   %cmp = fcmp uge float %a, %fneg
1173   ret i1 %cmp
1176 define i1 @fneg_ult_swap(float %p) {
1177 ; CHECK-LABEL: @fneg_ult_swap(
1178 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1179 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz ult float [[A]], 0.000000e+00
1180 ; CHECK-NEXT:    ret i1 [[CMP]]
1182   %a = fadd float %p, %p ; thwart complexity-based canonicalization
1183   %fneg = fneg float %a
1184   %cmp = fcmp nsz ult float %a, %fneg
1185   ret i1 %cmp
1188 define i1 @fneg_ule_swap(float %p) {
1189 ; CHECK-LABEL: @fneg_ule_swap(
1190 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1191 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ule float [[A]], 0.000000e+00
1192 ; CHECK-NEXT:    ret i1 [[CMP]]
1194   %a = fadd float %p, %p ; thwart complexity-based canonicalization
1195   %fneg = fneg float %a
1196   %cmp = fcmp nnan ule float %a, %fneg
1197   ret i1 %cmp
1200 define i1 @fneg_une_swap(float %p) {
1201 ; CHECK-LABEL: @fneg_une_swap(
1202 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[P:%.*]], [[P]]
1203 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf une float [[A]], 0.000000e+00
1204 ; CHECK-NEXT:    ret i1 [[CMP]]
1206   %a = fadd float %p, %p ; thwart complexity-based canonicalization
1207   %fneg = fneg float %a
1208   %cmp = fcmp ninf une float %a, %fneg
1209   ret i1 %cmp
1212 define i1 @bitcast_eq0(i32 %x) {
1213 ; CHECK-LABEL: @bitcast_eq0(
1214 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 2147483647
1215 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 0
1216 ; CHECK-NEXT:    ret i1 [[R]]
1218   %f = bitcast i32 %x to float
1219   %r = fcmp oeq float %f, 0.0
1220   ret i1 %r
1223 define <2 x i1> @bitcast_ne0(<2 x i32> %x) {
1224 ; CHECK-LABEL: @bitcast_ne0(
1225 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 2147483647)
1226 ; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
1227 ; CHECK-NEXT:    ret <2 x i1> [[R]]
1229   %f = bitcast <2 x i32> %x to <2 x float>
1230   %r = fcmp une <2 x float> %f, <float 0.0, float 0.0>
1231   ret <2 x i1> %r
1234 ; negative test - extra use
1236 define i1 @bitcast_eq0_use(i32 %x) {
1237 ; CHECK-LABEL: @bitcast_eq0_use(
1238 ; CHECK-NEXT:    [[F:%.*]] = bitcast i32 [[X:%.*]] to float
1239 ; CHECK-NEXT:    call void @use(float [[F]])
1240 ; CHECK-NEXT:    [[R:%.*]] = fcmp oeq float [[F]], 0.000000e+00
1241 ; CHECK-NEXT:    ret i1 [[R]]
1243   %f = bitcast i32 %x to float
1244   call void @use(float %f)
1245   %r = fcmp oeq float %f, 0.0
1246   ret i1 %r
1249 ; negative test - this could be transformed, but requires a new bitcast
1251 define i1 @bitcast_nonint_eq0(<2 x i16> %x) {
1252 ; CHECK-LABEL: @bitcast_nonint_eq0(
1253 ; CHECK-NEXT:    [[F:%.*]] = bitcast <2 x i16> [[X:%.*]] to float
1254 ; CHECK-NEXT:    [[R:%.*]] = fcmp ogt float [[F]], 0.000000e+00
1255 ; CHECK-NEXT:    ret i1 [[R]]
1257   %f = bitcast <2 x i16> %x to float
1258   %r = fcmp ogt float %f, 0.0
1259   ret i1 %r
1262 ; negative test - wrong predicate
1264 define i1 @bitcast_gt0(i32 %x) {
1265 ; CHECK-LABEL: @bitcast_gt0(
1266 ; CHECK-NEXT:    [[F:%.*]] = bitcast i32 [[X:%.*]] to float
1267 ; CHECK-NEXT:    [[R:%.*]] = fcmp ogt float [[F]], 0.000000e+00
1268 ; CHECK-NEXT:    ret i1 [[R]]
1270   %f = bitcast i32 %x to float
1271   %r = fcmp ogt float %f, 0.0
1272   ret i1 %r
1275 ; negative test - this could be transformed, but requires a new bitcast
1277 define <1 x i1> @bitcast_1vec_eq0(i32 %x) {
1278 ; CHECK-LABEL: @bitcast_1vec_eq0(
1279 ; CHECK-NEXT:    [[F:%.*]] = bitcast i32 [[X:%.*]] to <1 x float>
1280 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq <1 x float> [[F]], zeroinitializer
1281 ; CHECK-NEXT:    ret <1 x i1> [[CMP]]
1283   %f = bitcast i32 %x to <1 x float>
1284   %cmp = fcmp oeq <1 x float> %f, zeroinitializer
1285   ret <1 x i1> %cmp
1288 ; Simplify fcmp (x + 0.0), y => fcmp x, y
1290 define i1 @fcmp_fadd_zero_ugt(float %x, float %y) {
1291 ; CHECK-LABEL: @fcmp_fadd_zero_ugt(
1292 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt float [[X:%.*]], [[Y:%.*]]
1293 ; CHECK-NEXT:    ret i1 [[CMP]]
1295   %add = fadd float %x, 0.000000e+00
1296   %cmp = fcmp ugt float %add, %y
1297   ret i1 %cmp
1300 define i1 @fcmp_fadd_zero_uge(float %x, float %y) {
1301 ; CHECK-LABEL: @fcmp_fadd_zero_uge(
1302 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[X:%.*]], [[Y:%.*]]
1303 ; CHECK-NEXT:    ret i1 [[CMP]]
1305   %add = fadd float %x, 0.000000e+00
1306   %cmp = fcmp uge float %add, %y
1307   ret i1 %cmp
1310 define i1 @fcmp_fadd_zero_ogt(float %x, float %y) {
1311 ; CHECK-LABEL: @fcmp_fadd_zero_ogt(
1312 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]]
1313 ; CHECK-NEXT:    ret i1 [[CMP]]
1315   %add = fadd float %x, 0.000000e+00
1316   %cmp = fcmp ogt float %add, %y
1317   ret i1 %cmp
1320 define i1 @fcmp_fadd_zero_oge(float %x, float %y) {
1321 ; CHECK-LABEL: @fcmp_fadd_zero_oge(
1322 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[X:%.*]], [[Y:%.*]]
1323 ; CHECK-NEXT:    ret i1 [[CMP]]
1325   %add = fadd float %x, 0.000000e+00
1326   %cmp = fcmp oge float %add, %y
1327   ret i1 %cmp
1330 define i1 @fcmp_fadd_zero_ult(float %x, float %y) {
1331 ; CHECK-LABEL: @fcmp_fadd_zero_ult(
1332 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult float [[X:%.*]], [[Y:%.*]]
1333 ; CHECK-NEXT:    ret i1 [[CMP]]
1335   %add = fadd float %x, 0.000000e+00
1336   %cmp = fcmp ult float %add, %y
1337   ret i1 %cmp
1340 define i1 @fcmp_fadd_zero_ule(float %x, float %y) {
1341 ; CHECK-LABEL: @fcmp_fadd_zero_ule(
1342 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule float [[X:%.*]], [[Y:%.*]]
1343 ; CHECK-NEXT:    ret i1 [[CMP]]
1345   %add = fadd float %x, 0.000000e+00
1346   %cmp = fcmp ule float %add, %y
1347   ret i1 %cmp
1350 define i1 @fcmp_fadd_zero_olt(float %x, float %y) {
1351 ; CHECK-LABEL: @fcmp_fadd_zero_olt(
1352 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[Y:%.*]]
1353 ; CHECK-NEXT:    ret i1 [[CMP]]
1355   %add = fadd float %x, 0.000000e+00
1356   %cmp = fcmp olt float %add, %y
1357   ret i1 %cmp
1360 define i1 @fcmp_fadd_zero_ole(float %x, float %y) {
1361 ; CHECK-LABEL: @fcmp_fadd_zero_ole(
1362 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole float [[X:%.*]], [[Y:%.*]]
1363 ; CHECK-NEXT:    ret i1 [[CMP]]
1365   %add = fadd float %x, 0.000000e+00
1366   %cmp = fcmp ole float %add, %y
1367   ret i1 %cmp
1370 define i1 @fcmp_fadd_zero_oeq(float %x, float %y) {
1371 ; CHECK-LABEL: @fcmp_fadd_zero_oeq(
1372 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[X:%.*]], [[Y:%.*]]
1373 ; CHECK-NEXT:    ret i1 [[CMP]]
1375   %add = fadd float %x, 0.000000e+00
1376   %cmp = fcmp oeq float %add, %y
1377   ret i1 %cmp
1380 define i1 @fcmp_fadd_zero_one(float %x, float %y) {
1381 ; CHECK-LABEL: @fcmp_fadd_zero_one(
1382 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp one float [[X:%.*]], [[Y:%.*]]
1383 ; CHECK-NEXT:    ret i1 [[CMP]]
1385   %add = fadd float %x, 0.000000e+00
1386   %cmp = fcmp one float %add, %y
1387   ret i1 %cmp
1390 define i1 @fcmp_fadd_zero_ueq(float %x, float %y) {
1391 ; CHECK-LABEL: @fcmp_fadd_zero_ueq(
1392 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq float [[X:%.*]], [[Y:%.*]]
1393 ; CHECK-NEXT:    ret i1 [[CMP]]
1395   %add = fadd float %x, 0.000000e+00
1396   %cmp = fcmp ueq float %add, %y
1397   ret i1 %cmp
1400 define i1 @fcmp_fadd_zero_une(float %x, float %y) {
1401 ; CHECK-LABEL: @fcmp_fadd_zero_une(
1402 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[X:%.*]], [[Y:%.*]]
1403 ; CHECK-NEXT:    ret i1 [[CMP]]
1405   %add = fadd float %x, 0.000000e+00
1406   %cmp = fcmp une float %add, %y
1407   ret i1 %cmp
1410 define i1 @fcmp_fadd_zero_ord(float %x, float %y) {
1411 ; CHECK-LABEL: @fcmp_fadd_zero_ord(
1412 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
1413 ; CHECK-NEXT:    ret i1 [[CMP]]
1415   %add = fadd float %x, 0.000000e+00
1416   %cmp = fcmp ord float %add, %y
1417   ret i1 %cmp
1420 define i1 @fcmp_fadd_zero_uno(float %x, float %y) {
1421 ; CHECK-LABEL: @fcmp_fadd_zero_uno(
1422 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno float [[X:%.*]], [[Y:%.*]]
1423 ; CHECK-NEXT:    ret i1 [[CMP]]
1425   %add = fadd float %x, 0.000000e+00
1426   %cmp = fcmp uno float %add, %y
1427   ret i1 %cmp
1430 define i1 @fcmp_fadd_neg_zero(float %x, float %y) {
1431 ; CHECK-LABEL: @fcmp_fadd_neg_zero(
1432 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt float [[X:%.*]], [[Y:%.*]]
1433 ; CHECK-NEXT:    ret i1 [[CMP]]
1435   %add = fadd float %x, -0.000000e+00
1436   %cmp = fcmp ugt float %add, %y
1437   ret i1 %cmp
1440 define i1 @fcmp_fadd_zero_switched(float %x, float %y) {
1441 ; CHECK-LABEL: @fcmp_fadd_zero_switched(
1442 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt float [[X:%.*]], [[Y:%.*]]
1443 ; CHECK-NEXT:    ret i1 [[CMP]]
1445   %add = fadd float %y, 0.000000e+00
1446   %cmp = fcmp ugt float %x, %add
1447   ret i1 %cmp
1450 define <2 x i1> @fcmp_fadd_zero_vec(<2 x float> %x, <2 x float> %y) {
1451 ; CHECK-LABEL: @fcmp_fadd_zero_vec(
1452 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt <2 x float> [[X:%.*]], [[Y:%.*]]
1453 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1455   %add = fadd <2 x float> %x, <float 0.0, float -0.0>
1456   %cmp = fcmp ugt <2 x float> %add, %y
1457   ret <2 x i1> %cmp
1460 define i1 @fcmp_fast_fadd_fast_zero(float %x, float %y) {
1461 ; CHECK-LABEL: @fcmp_fast_fadd_fast_zero(
1462 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ugt float [[X:%.*]], [[Y:%.*]]
1463 ; CHECK-NEXT:    ret i1 [[CMP]]
1465   %add = fadd fast float %x, 0.000000e+00
1466   %cmp = fcmp fast ugt float %add, %y
1467   ret i1 %cmp
1470 define i1 @fcmp_fast_fadd_zero(float %x, float %y) {
1471 ; CHECK-LABEL: @fcmp_fast_fadd_zero(
1472 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ugt float [[X:%.*]], [[Y:%.*]]
1473 ; CHECK-NEXT:    ret i1 [[CMP]]
1475   %add = fadd float %x, 0.000000e+00
1476   %cmp = fcmp fast ugt float %add, %y
1477   ret i1 %cmp
1480 define i1 @fcmp_fadd_fast_zero(float %x, float %y) {
1481 ; CHECK-LABEL: @fcmp_fadd_fast_zero(
1482 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt float [[X:%.*]], [[Y:%.*]]
1483 ; CHECK-NEXT:    ret i1 [[CMP]]
1485   %add = fadd fast float %x, 0.000000e+00
1486   %cmp = fcmp ugt float %add, %y
1487   ret i1 %cmp
1490 define i1 @fcmp_ueq_sel_x_negx(float %x) {
1491 ; CHECK-LABEL: @fcmp_ueq_sel_x_negx(
1492 ; CHECK-NEXT:    [[RES:%.*]] = fcmp ueq float [[X:%.*]], 0.000000e+00
1493 ; CHECK-NEXT:    ret i1 [[RES]]
1495   %f = fcmp ueq float %x, 0.000000e+00
1496   %neg = fneg float %x
1497   %sel = select i1 %f, float %x, float %neg
1498   %res = fcmp ueq float %sel, 0.000000e+00
1499   ret i1 %res
1502 define i1 @fcmp_une_sel_x_negx(float %x) {
1503 ; CHECK-LABEL: @fcmp_une_sel_x_negx(
1504 ; CHECK-NEXT:    [[RES:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
1505 ; CHECK-NEXT:    ret i1 [[RES]]
1507   %f = fcmp une float %x, 0.000000e+00
1508   %neg = fneg float %x
1509   %sel = select i1 %f, float %x, float %neg
1510   %res = fcmp une float %sel, 0.000000e+00
1511   ret i1 %res
1514 define i1 @fcmp_oeq_sel_x_negx(float %x) {
1515 ; CHECK-LABEL: @fcmp_oeq_sel_x_negx(
1516 ; CHECK-NEXT:    [[RES:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
1517 ; CHECK-NEXT:    ret i1 [[RES]]
1519   %f = fcmp oeq float %x, 0.000000e+00
1520   %neg = fneg float %x
1521   %sel = select i1 %f, float %x, float %neg
1522   %res = fcmp oeq float %sel, 0.000000e+00
1523   ret i1 %res
1526 define i1 @fcmp_one_sel_x_negx(float %x) {
1527 ; CHECK-LABEL: @fcmp_one_sel_x_negx(
1528 ; CHECK-NEXT:    [[RES:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
1529 ; CHECK-NEXT:    ret i1 [[RES]]
1531   %f = fcmp one float %x, 0.000000e+00
1532   %neg = fneg float %x
1533   %sel = select i1 %f, float %x, float %neg
1534   %res = fcmp one float %sel, 0.000000e+00
1535   ret i1 %res
1538 define i1 @fcmp_ueq_sel_x_negx_nzero(float %x) {
1539 ; CHECK-LABEL: @fcmp_ueq_sel_x_negx_nzero(
1540 ; CHECK-NEXT:    [[RES:%.*]] = fcmp ueq float [[X:%.*]], 0.000000e+00
1541 ; CHECK-NEXT:    ret i1 [[RES]]
1543   %f = fcmp ueq float %x, 0.000000e+00
1544   %neg = fneg float %x
1545   %sel = select i1 %f, float %x, float %neg
1546   %res = fcmp ueq float %sel, -0.000000e+00
1547   ret i1 %res
1550 define i1 @fcmp_une_sel_x_negx_nzero(float %x) {
1551 ; CHECK-LABEL: @fcmp_une_sel_x_negx_nzero(
1552 ; CHECK-NEXT:    [[RES:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
1553 ; CHECK-NEXT:    ret i1 [[RES]]
1555   %f = fcmp une float %x, 0.000000e+00
1556   %neg = fneg float %x
1557   %sel = select i1 %f, float %x, float %neg
1558   %res = fcmp une float %sel, -0.000000e+00
1559   ret i1 %res
1562 define i1 @fcmp_oeq_sel_x_negx_nzero(float %x) {
1563 ; CHECK-LABEL: @fcmp_oeq_sel_x_negx_nzero(
1564 ; CHECK-NEXT:    [[RES:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
1565 ; CHECK-NEXT:    ret i1 [[RES]]
1567   %f = fcmp oeq float %x, 0.000000e+00
1568   %neg = fneg float %x
1569   %sel = select i1 %f, float %x, float %neg
1570   %res = fcmp oeq float %sel, -0.000000e+00
1571   ret i1 %res
1574 define i1 @fcmp_one_sel_x_negx_nzero(float %x) {
1575 ; CHECK-LABEL: @fcmp_one_sel_x_negx_nzero(
1576 ; CHECK-NEXT:    [[RES:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
1577 ; CHECK-NEXT:    ret i1 [[RES]]
1579   %f = fcmp one float %x, 0.000000e+00
1580   %neg = fneg float %x
1581   %sel = select i1 %f, float %x, float %neg
1582   %res = fcmp one float %sel, -0.000000e+00
1583   ret i1 %res
1586 define <8 x i1> @fcmp_ueq_sel_x_negx_vec(<8 x float> %x) {
1587 ; CHECK-LABEL: @fcmp_ueq_sel_x_negx_vec(
1588 ; CHECK-NEXT:    [[RES:%.*]] = fcmp ueq <8 x float> [[X:%.*]], zeroinitializer
1589 ; CHECK-NEXT:    ret <8 x i1> [[RES]]
1591   %f = fcmp ueq <8 x float> %x, zeroinitializer
1592   %neg = fneg <8 x float> %x
1593   %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
1594   %res = fcmp ueq <8 x float> %sel, zeroinitializer
1595   ret <8 x i1> %res
1598 define <8 x i1> @fcmp_une_sel_x_negx_vec(<8 x float> %x) {
1599 ; CHECK-LABEL: @fcmp_une_sel_x_negx_vec(
1600 ; CHECK-NEXT:    [[RES:%.*]] = fcmp une <8 x float> [[X:%.*]], zeroinitializer
1601 ; CHECK-NEXT:    ret <8 x i1> [[RES]]
1603   %f = fcmp une <8 x float> %x, zeroinitializer
1604   %neg = fneg <8 x float> %x
1605   %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
1606   %res = fcmp une <8 x float> %sel, zeroinitializer
1607   ret <8 x i1> %res
1610 define <8 x i1> @fcmp_oeq_sel_x_negx_vec(<8 x float> %x) {
1611 ; CHECK-LABEL: @fcmp_oeq_sel_x_negx_vec(
1612 ; CHECK-NEXT:    [[RES:%.*]] = fcmp oeq <8 x float> [[X:%.*]], zeroinitializer
1613 ; CHECK-NEXT:    ret <8 x i1> [[RES]]
1615   %f = fcmp oeq <8 x float> %x, zeroinitializer
1616   %neg = fneg <8 x float> %x
1617   %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
1618   %res = fcmp oeq <8 x float> %sel, zeroinitializer
1619   ret <8 x i1> %res
1622 define <8 x i1> @fcmp_one_sel_x_negx_vec(<8 x float> %x) {
1623 ; CHECK-LABEL: @fcmp_one_sel_x_negx_vec(
1624 ; CHECK-NEXT:    [[RES:%.*]] = fcmp one <8 x float> [[X:%.*]], zeroinitializer
1625 ; CHECK-NEXT:    ret <8 x i1> [[RES]]
1627   %f = fcmp one <8 x float> %x, zeroinitializer
1628   %neg = fneg <8 x float> %x
1629   %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
1630   %res = fcmp one <8 x float> %sel, zeroinitializer
1631   ret <8 x i1> %res
1634 define <2 x i1> @fcmp_oeq_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
1635 ; CHECK-LABEL: @fcmp_oeq_sel_x_negx_with_any_fpzero_ninf_vec(
1636 ; CHECK-NEXT:    [[ICMP:%.*]] = fcmp ninf oeq <2 x float> [[X:%.*]], zeroinitializer
1637 ; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
1639   %fneg = fneg <2 x float> %x
1640   %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1641   %icmp = fcmp ninf oeq <2 x float> %sel, <float 0.0, float -0.0>
1642   ret <2 x i1> %icmp
1645 define <2 x i1> @fcmp_one_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
1646 ; CHECK-LABEL: @fcmp_one_sel_x_negx_with_any_fpzero_ninf_vec(
1647 ; CHECK-NEXT:    [[ICMP:%.*]] = fcmp ninf one <2 x float> [[X:%.*]], zeroinitializer
1648 ; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
1650   %fneg = fneg <2 x float> %x
1651   %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1652   %icmp = fcmp ninf one <2 x float> %sel, <float 0.0, float -0.0>
1653   ret <2 x i1> %icmp
1656 define <2 x i1> @fcmp_ueq_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
1657 ; CHECK-LABEL: @fcmp_ueq_sel_x_negx_with_any_fpzero_ninf_vec(
1658 ; CHECK-NEXT:    [[ICMP:%.*]] = fcmp ninf ueq <2 x float> [[X:%.*]], zeroinitializer
1659 ; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
1661   %fneg = fneg <2 x float> %x
1662   %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1663   %icmp = fcmp ninf ueq <2 x float> %sel, <float 0.0, float -0.0>
1664   ret <2 x i1> %icmp
1667 define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
1668 ; CHECK-LABEL: @fcmp_une_sel_x_negx_with_any_fpzero_ninf_vec(
1669 ; CHECK-NEXT:    [[ICMP:%.*]] = fcmp ninf une <2 x float> [[X:%.*]], zeroinitializer
1670 ; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
1672   %fneg = fneg <2 x float> %x
1673   %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1674   %icmp = fcmp ninf une <2 x float> %sel, <float 0.0, float -0.0>
1675   ret <2 x i1> %icmp
1678 define <2 x i1> @fcmp_oeq_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
1679 ; CHECK-LABEL: @fcmp_oeq_sel_x_negx_with_any_fpzero_nnan_vec(
1680 ; CHECK-NEXT:    [[ICMP:%.*]] = fcmp nnan oeq <2 x float> [[X:%.*]], zeroinitializer
1681 ; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
1683   %fneg = fneg <2 x float> %x
1684   %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1685   %icmp = fcmp nnan oeq <2 x float> %sel, <float 0.0, float -0.0>
1686   ret <2 x i1> %icmp
1689 define <2 x i1> @fcmp_one_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
1690 ; CHECK-LABEL: @fcmp_one_sel_x_negx_with_any_fpzero_nnan_vec(
1691 ; CHECK-NEXT:    [[ICMP:%.*]] = fcmp nnan one <2 x float> [[X:%.*]], zeroinitializer
1692 ; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
1694   %fneg = fneg <2 x float> %x
1695   %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1696   %icmp = fcmp nnan one <2 x float> %sel, <float 0.0, float -0.0>
1697   ret <2 x i1> %icmp
1700 define <2 x i1> @fcmp_ueq_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
1701 ; CHECK-LABEL: @fcmp_ueq_sel_x_negx_with_any_fpzero_nnan_vec(
1702 ; CHECK-NEXT:    [[ICMP:%.*]] = fcmp nnan ueq <2 x float> [[X:%.*]], zeroinitializer
1703 ; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
1705   %fneg = fneg <2 x float> %x
1706   %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1707   %icmp = fcmp nnan ueq <2 x float> %sel, <float 0.0, float -0.0>
1708   ret <2 x i1> %icmp
1711 define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
1712 ; CHECK-LABEL: @fcmp_une_sel_x_negx_with_any_fpzero_nnan_vec(
1713 ; CHECK-NEXT:    [[ICMP:%.*]] = fcmp nnan une <2 x float> [[X:%.*]], zeroinitializer
1714 ; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
1716   %fneg = fneg <2 x float> %x
1717   %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1718   %icmp = fcmp nnan une <2 x float> %sel, <float 0.0, float -0.0>
1719   ret <2 x i1> %icmp
1722 ; negative test - extra use
1724 define i1 @fcmp_ueq_fsub_nnan_const_extra_use(float %x, float %y) {
1725 ; CHECK-LABEL: @fcmp_ueq_fsub_nnan_const_extra_use(
1726 ; CHECK-NEXT:    [[FS:%.*]] = fsub nnan float [[X:%.*]], [[Y:%.*]]
1727 ; CHECK-NEXT:    call void @use(float [[FS]])
1728 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ueq float [[FS]], 0.000000e+00
1729 ; CHECK-NEXT:    ret i1 [[CMP]]
1731   %fs = fsub nnan float %x, %y
1732   call void @use(float %fs)
1733   %cmp = fcmp nnan ueq float %fs, 0.000000e+00
1734   ret i1 %cmp
1737 ; negative test - extra use
1739 define i1 @fcmp_oeq_fsub_ninf_const_extra_use(float %x, float %y) {
1740 ; CHECK-LABEL: @fcmp_oeq_fsub_ninf_const_extra_use(
1741 ; CHECK-NEXT:    [[FS:%.*]] = fsub ninf float [[X:%.*]], [[Y:%.*]]
1742 ; CHECK-NEXT:    call void @use(float [[FS]])
1743 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf oeq float [[FS]], 0.000000e+00
1744 ; CHECK-NEXT:    ret i1 [[CMP]]
1746   %fs = fsub ninf float %x, %y
1747   call void @use(float %fs)
1748   %cmp = fcmp ninf oeq float %fs, 0.000000e+00
1749   ret i1 %cmp
1752 define i1 @fcmp_oeq_fsub_const(float %x, float %y) {
1753 ; CHECK-LABEL: @fcmp_oeq_fsub_const(
1754 ; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1755 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[FS]], 0.000000e+00
1756 ; CHECK-NEXT:    ret i1 [[CMP]]
1758   %fs = fsub float %x, %y
1759   %cmp = fcmp oeq float %fs, 0.000000e+00
1760   ret i1 %cmp
1763 define i1 @fcmp_oge_fsub_const(float %x, float %y) {
1764 ; CHECK-LABEL: @fcmp_oge_fsub_const(
1765 ; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1766 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[FS]], 0.000000e+00
1767 ; CHECK-NEXT:    ret i1 [[CMP]]
1769   %fs = fsub float %x, %y
1770   %cmp = fcmp oge float %fs, 0.000000e+00
1771   ret i1 %cmp
1774 define i1 @fcmp_ole_fsub_const(float %x, float %y) {
1775 ; CHECK-LABEL: @fcmp_ole_fsub_const(
1776 ; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1777 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole float [[FS]], 0.000000e+00
1778 ; CHECK-NEXT:    ret i1 [[CMP]]
1780   %fs = fsub float %x, %y
1781   %cmp = fcmp ole float %fs, 0.000000e+00
1782   ret i1 %cmp
1785 define i1 @fcmp_ueq_fsub_const(float %x, float %y) {
1786 ; CHECK-LABEL: @fcmp_ueq_fsub_const(
1787 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq float [[X:%.*]], [[Y:%.*]]
1788 ; CHECK-NEXT:    ret i1 [[CMP]]
1790   %fs = fsub float %x, %y
1791   %cmp = fcmp ueq float %fs, 0.000000e+00
1792   ret i1 %cmp
1795 define i1 @fcmp_uge_fsub_const(float %x, float %y) {
1796 ; CHECK-LABEL: @fcmp_uge_fsub_const(
1797 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[X:%.*]], [[Y:%.*]]
1798 ; CHECK-NEXT:    ret i1 [[CMP]]
1800   %fs = fsub float %x, %y
1801   %cmp = fcmp uge float %fs, 0.000000e+00
1802   ret i1 %cmp
1805 define i1 @fcmp_ule_fsub_const(float %x, float %y) {
1806 ; CHECK-LABEL: @fcmp_ule_fsub_const(
1807 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule float [[X:%.*]], [[Y:%.*]]
1808 ; CHECK-NEXT:    ret i1 [[CMP]]
1810   %fs = fsub float %x, %y
1811   %cmp = fcmp ule float %fs, 0.000000e+00
1812   ret i1 %cmp
1815 define i1 @fcmp_ugt_fsub_const(float %x, float %y) {
1816 ; CHECK-LABEL: @fcmp_ugt_fsub_const(
1817 ; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1818 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt float [[FS]], 0.000000e+00
1819 ; CHECK-NEXT:    ret i1 [[CMP]]
1821   %fs = fsub float %x, %y
1822   %cmp = fcmp ugt float %fs, 0.000000e+00
1823   ret i1 %cmp
1826 define i1 @fcmp_ult_fsub_const(float %x, float %y) {
1827 ; CHECK-LABEL: @fcmp_ult_fsub_const(
1828 ; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1829 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult float [[FS]], 0.000000e+00
1830 ; CHECK-NEXT:    ret i1 [[CMP]]
1832   %fs = fsub float %x, %y
1833   %cmp = fcmp ult float %fs, 0.000000e+00
1834   ret i1 %cmp
1837 define i1 @fcmp_une_fsub_const(float %x, float %y) {
1838 ; CHECK-LABEL: @fcmp_une_fsub_const(
1839 ; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
1840 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[FS]], 0.000000e+00
1841 ; CHECK-NEXT:    ret i1 [[CMP]]
1843   %fs = fsub float %x, %y
1844   %cmp = fcmp une float %fs, 0.000000e+00
1845   ret i1 %cmp
1848 define <8 x i1> @fcmp_uge_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1849 ; CHECK-LABEL: @fcmp_uge_fsub_const_ninf_vec(
1850 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf uge <8 x float> [[X:%.*]], [[Y:%.*]]
1851 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
1853   %fs = fsub ninf <8 x float> %x, %y
1854   %cmp = fcmp ninf uge <8 x float> %fs, zeroinitializer
1855   ret <8 x i1> %cmp
1858 define <8 x i1> @fcmp_ule_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1859 ; CHECK-LABEL: @fcmp_ule_fsub_const_ninf_vec(
1860 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ule <8 x float> [[X:%.*]], [[Y:%.*]]
1861 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
1863   %fs = fsub ninf <8 x float> %x, %y
1864   %cmp = fcmp ninf ule <8 x float> %fs, zeroinitializer
1865   ret <8 x i1> %cmp
1868 define <8 x i1> @fcmp_ueq_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1869 ; CHECK-LABEL: @fcmp_ueq_fsub_const_ninf_vec(
1870 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ueq <8 x float> [[X:%.*]], [[Y:%.*]]
1871 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
1873   %fs = fsub ninf <8 x float> %x, %y
1874   %cmp = fcmp ninf ueq <8 x float> %fs, zeroinitializer
1875   ret <8 x i1> %cmp
1878 define <8 x i1> @fcmp_oge_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1879 ; CHECK-LABEL: @fcmp_oge_fsub_const_ninf_vec(
1880 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf oge <8 x float> [[X:%.*]], [[Y:%.*]]
1881 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
1883   %fs = fsub ninf <8 x float> %x, %y
1884   %cmp = fcmp ninf oge <8 x float> %fs, zeroinitializer
1885   ret <8 x i1> %cmp
1888 define <8 x i1> @fcmp_ole_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1889 ; CHECK-LABEL: @fcmp_ole_fsub_const_ninf_vec(
1890 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ole <8 x float> [[X:%.*]], [[Y:%.*]]
1891 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
1893   %fs = fsub ninf <8 x float> %x, %y
1894   %cmp = fcmp ninf ole <8 x float> %fs, zeroinitializer
1895   ret <8 x i1> %cmp
1898 define <8 x i1> @fcmp_oeq_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1899 ; CHECK-LABEL: @fcmp_oeq_fsub_const_ninf_vec(
1900 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf oeq <8 x float> [[X:%.*]], [[Y:%.*]]
1901 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
1903   %fs = fsub ninf <8 x float> %x, %y
1904   %cmp = fcmp ninf oeq <8 x float> %fs, zeroinitializer
1905   ret <8 x i1> %cmp
1908 define <8 x i1> @fcmp_ogt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1909 ; CHECK-LABEL: @fcmp_ogt_fsub_const_ninf_vec(
1910 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ogt <8 x float> [[X:%.*]], [[Y:%.*]]
1911 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
1913   %fs = fsub ninf <8 x float> %x, %y
1914   %cmp = fcmp ninf ogt <8 x float> %fs, zeroinitializer
1915   ret <8 x i1> %cmp
1918 define <8 x i1> @fcmp_olt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1919 ; CHECK-LABEL: @fcmp_olt_fsub_const_ninf_vec(
1920 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf olt <8 x float> [[X:%.*]], [[Y:%.*]]
1921 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
1923   %fs = fsub ninf <8 x float> %x, %y
1924   %cmp = fcmp ninf olt <8 x float> %fs, zeroinitializer
1925   ret <8 x i1> %cmp
1928 define <8 x i1> @fcmp_one_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1929 ; CHECK-LABEL: @fcmp_one_fsub_const_ninf_vec(
1930 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf one <8 x float> [[X:%.*]], [[Y:%.*]]
1931 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
1933   %fs = fsub ninf <8 x float> %x, %y
1934   %cmp = fcmp ninf one <8 x float> %fs, zeroinitializer
1935   ret <8 x i1> %cmp
1938 define <8 x i1> @fcmp_ugt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1939 ; CHECK-LABEL: @fcmp_ugt_fsub_const_ninf_vec(
1940 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ugt <8 x float> [[X:%.*]], [[Y:%.*]]
1941 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
1943   %fs = fsub ninf <8 x float> %x, %y
1944   %cmp = fcmp ninf ugt <8 x float> %fs, zeroinitializer
1945   ret <8 x i1> %cmp
1948 define <8 x i1> @fcmp_ult_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1949 ; CHECK-LABEL: @fcmp_ult_fsub_const_ninf_vec(
1950 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ult <8 x float> [[X:%.*]], [[Y:%.*]]
1951 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
1953   %fs = fsub ninf <8 x float> %x, %y
1954   %cmp = fcmp ninf ult <8 x float> %fs, zeroinitializer
1955   ret <8 x i1> %cmp
1958 define <8 x i1> @fcmp_une_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
1959 ; CHECK-LABEL: @fcmp_une_fsub_const_ninf_vec(
1960 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf une <8 x float> [[X:%.*]], [[Y:%.*]]
1961 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
1963   %fs = fsub ninf <8 x float> %x, %y
1964   %cmp = fcmp ninf une <8 x float> %fs, zeroinitializer
1965   ret <8 x i1> %cmp
1968 define <8 x i1> @fcmp_uge_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
1969 ; CHECK-LABEL: @fcmp_uge_fsub_const_nnan_vec(
1970 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan uge <8 x float> [[X:%.*]], [[Y:%.*]]
1971 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
1973   %fs = fsub nnan <8 x float> %x, %y
1974   %cmp = fcmp nnan uge <8 x float> %fs, zeroinitializer
1975   ret <8 x i1> %cmp
1978 define <8 x i1> @fcmp_ule_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
1979 ; CHECK-LABEL: @fcmp_ule_fsub_const_nnan_vec(
1980 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ule <8 x float> [[X:%.*]], [[Y:%.*]]
1981 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
1983   %fs = fsub nnan <8 x float> %x, %y
1984   %cmp = fcmp nnan ule <8 x float> %fs, zeroinitializer
1985   ret <8 x i1> %cmp
1988 define <8 x i1> @fcmp_ueq_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
1989 ; CHECK-LABEL: @fcmp_ueq_fsub_const_nnan_vec(
1990 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ueq <8 x float> [[X:%.*]], [[Y:%.*]]
1991 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
1993   %fs = fsub nnan <8 x float> %x, %y
1994   %cmp = fcmp nnan ueq <8 x float> %fs, zeroinitializer
1995   ret <8 x i1> %cmp
1998 define <8 x i1> @fcmp_oge_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
1999 ; CHECK-LABEL: @fcmp_oge_fsub_const_nnan_vec(
2000 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan oge <8 x float> [[X:%.*]], [[Y:%.*]]
2001 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
2003   %fs = fsub nnan <8 x float> %x, %y
2004   %cmp = fcmp nnan oge <8 x float> %fs, zeroinitializer
2005   ret <8 x i1> %cmp
2008 define <8 x i1> @fcmp_ole_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2009 ; CHECK-LABEL: @fcmp_ole_fsub_const_nnan_vec(
2010 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ole <8 x float> [[X:%.*]], [[Y:%.*]]
2011 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
2013   %fs = fsub nnan <8 x float> %x, %y
2014   %cmp = fcmp nnan ole <8 x float> %fs, zeroinitializer
2015   ret <8 x i1> %cmp
2018 define <8 x i1> @fcmp_oeq_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2019 ; CHECK-LABEL: @fcmp_oeq_fsub_const_nnan_vec(
2020 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan oeq <8 x float> [[X:%.*]], [[Y:%.*]]
2021 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
2023   %fs = fsub nnan <8 x float> %x, %y
2024   %cmp = fcmp nnan oeq <8 x float> %fs, zeroinitializer
2025   ret <8 x i1> %cmp
2028 define <8 x i1> @fcmp_ogt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2029 ; CHECK-LABEL: @fcmp_ogt_fsub_const_nnan_vec(
2030 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ogt <8 x float> [[X:%.*]], [[Y:%.*]]
2031 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
2033   %fs = fsub nnan <8 x float> %x, %y
2034   %cmp = fcmp nnan ogt <8 x float> %fs, zeroinitializer
2035   ret <8 x i1> %cmp
2038 define <8 x i1> @fcmp_olt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2039 ; CHECK-LABEL: @fcmp_olt_fsub_const_nnan_vec(
2040 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan olt <8 x float> [[X:%.*]], [[Y:%.*]]
2041 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
2043   %fs = fsub nnan <8 x float> %x, %y
2044   %cmp = fcmp nnan olt <8 x float> %fs, zeroinitializer
2045   ret <8 x i1> %cmp
2048 define <8 x i1> @fcmp_one_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2049 ; CHECK-LABEL: @fcmp_one_fsub_const_nnan_vec(
2050 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan one <8 x float> [[X:%.*]], [[Y:%.*]]
2051 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
2053   %fs = fsub nnan <8 x float> %x, %y
2054   %cmp = fcmp nnan one <8 x float> %fs, zeroinitializer
2055   ret <8 x i1> %cmp
2058 define <8 x i1> @fcmp_ugt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2059 ; CHECK-LABEL: @fcmp_ugt_fsub_const_nnan_vec(
2060 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ugt <8 x float> [[X:%.*]], [[Y:%.*]]
2061 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
2063   %fs = fsub nnan <8 x float> %x, %y
2064   %cmp = fcmp nnan ugt <8 x float> %fs, zeroinitializer
2065   ret <8 x i1> %cmp
2068 define <8 x i1> @fcmp_ult_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2069 ; CHECK-LABEL: @fcmp_ult_fsub_const_nnan_vec(
2070 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ult <8 x float> [[X:%.*]], [[Y:%.*]]
2071 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
2073   %fs = fsub nnan <8 x float> %x, %y
2074   %cmp = fcmp nnan ult <8 x float> %fs, zeroinitializer
2075   ret <8 x i1> %cmp
2078 define <8 x i1> @fcmp_une_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
2079 ; CHECK-LABEL: @fcmp_une_fsub_const_nnan_vec(
2080 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan une <8 x float> [[X:%.*]], [[Y:%.*]]
2081 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
2083   %fs = fsub nnan <8 x float> %x, %y
2084   %cmp = fcmp nnan une <8 x float> %fs, zeroinitializer
2085   ret <8 x i1> %cmp
2088 define <8 x i1> @fcmp_ugt_fsub_const_vec_denormal_positive-zero(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="positive-zero,positive-zero" {
2089 ; CHECK-LABEL: @fcmp_ugt_fsub_const_vec_denormal_positive-zero(
2090 ; CHECK-NEXT:    [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]]
2091 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer
2092 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
2094   %fs = fsub <8 x float> %x, %y
2095   %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
2096   ret <8 x i1> %cmp
2099 define <8 x i1> @fcmp_ogt_fsub_const_vec_denormal_dynamic(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="dynamic,dynamic" {
2100 ; CHECK-LABEL: @fcmp_ogt_fsub_const_vec_denormal_dynamic(
2101 ; CHECK-NEXT:    [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]]
2102 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer
2103 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
2105   %fs = fsub <8 x float> %x, %y
2106   %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
2107   ret <8 x i1> %cmp
2110 define <8 x i1> @fcmp_ogt_fsub_const_vec_denormal_preserve-sign(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="preserve-sign,preserve-sign" {
2111 ; CHECK-LABEL: @fcmp_ogt_fsub_const_vec_denormal_preserve-sign(
2112 ; CHECK-NEXT:    [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]]
2113 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer
2114 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
2116   %fs = fsub <8 x float> %x, %y
2117   %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
2118   ret <8 x i1> %cmp
2121 define i1 @fcmp_sqrt_zero_olt(half %x) {
2122 ; CHECK-LABEL: @fcmp_sqrt_zero_olt(
2123 ; CHECK-NEXT:    ret i1 false
2125   %sqrt = call half @llvm.sqrt.f16(half %x)
2126   %cmp = fcmp olt half %sqrt, 0.0
2127   ret i1 %cmp
2130 define i1 @fcmp_sqrt_zero_ult(half %x) {
2131 ; CHECK-LABEL: @fcmp_sqrt_zero_ult(
2132 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH0000
2133 ; CHECK-NEXT:    ret i1 [[CMP]]
2135   %sqrt = call half @llvm.sqrt.f16(half %x)
2136   %cmp = fcmp ult half %sqrt, 0.0
2137   ret i1 %cmp
2140 define i1 @fcmp_sqrt_zero_ult_fmf(half %x) {
2141 ; CHECK-LABEL: @fcmp_sqrt_zero_ult_fmf(
2142 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp nsz ult half [[X:%.*]], 0xH0000
2143 ; CHECK-NEXT:    ret i1 [[CMP]]
2145   %sqrt = call half @llvm.sqrt.f16(half %x)
2146   %cmp = fcmp ninf nsz ult half %sqrt, 0.0
2147   ret i1 %cmp
2150 define i1 @fcmp_sqrt_zero_ult_fmf_sqrt_ninf(half %x) {
2151 ; CHECK-LABEL: @fcmp_sqrt_zero_ult_fmf_sqrt_ninf(
2152 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf nsz ult half [[X:%.*]], 0xH0000
2153 ; CHECK-NEXT:    ret i1 [[CMP]]
2155   %sqrt = call ninf half @llvm.sqrt.f16(half %x)
2156   %cmp = fcmp ninf nsz ult half %sqrt, 0.0
2157   ret i1 %cmp
2160 define i1 @fcmp_sqrt_zero_ult_nzero(half %x) {
2161 ; CHECK-LABEL: @fcmp_sqrt_zero_ult_nzero(
2162 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH0000
2163 ; CHECK-NEXT:    ret i1 [[CMP]]
2165   %sqrt = call half @llvm.sqrt.f16(half %x)
2166   %cmp = fcmp ult half %sqrt, -0.0
2167   ret i1 %cmp
2170 define <2 x i1> @fcmp_sqrt_zero_ult_vec(<2 x half> %x) {
2171 ; CHECK-LABEL: @fcmp_sqrt_zero_ult_vec(
2172 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult <2 x half> [[X:%.*]], zeroinitializer
2173 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2175   %sqrt = call <2 x half> @llvm.sqrt.v2f16(<2 x half> %x)
2176   %cmp = fcmp ult <2 x half> %sqrt, zeroinitializer
2177   ret <2 x i1> %cmp
2180 define <2 x i1> @fcmp_sqrt_zero_ult_vec_mixed_zero(<2 x half> %x) {
2181 ; CHECK-LABEL: @fcmp_sqrt_zero_ult_vec_mixed_zero(
2182 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult <2 x half> [[X:%.*]], zeroinitializer
2183 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2185   %sqrt = call <2 x half> @llvm.sqrt.v2f16(<2 x half> %x)
2186   %cmp = fcmp ult <2 x half> %sqrt, <half 0.0, half -0.0>
2187   ret <2 x i1> %cmp
2190 define i1 @fcmp_sqrt_zero_ole(half %x) {
2191 ; CHECK-LABEL: @fcmp_sqrt_zero_ole(
2192 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000
2193 ; CHECK-NEXT:    ret i1 [[CMP]]
2195   %sqrt = call half @llvm.sqrt.f16(half %x)
2196   %cmp = fcmp ole half %sqrt, 0.0
2197   ret i1 %cmp
2200 define i1 @fcmp_sqrt_zero_ule(half %x) {
2201 ; CHECK-LABEL: @fcmp_sqrt_zero_ule(
2202 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule half [[X:%.*]], 0xH0000
2203 ; CHECK-NEXT:    ret i1 [[CMP]]
2205   %sqrt = call half @llvm.sqrt.f16(half %x)
2206   %cmp = fcmp ule half %sqrt, 0.0
2207   ret i1 %cmp
2210 define i1 @fcmp_sqrt_zero_ogt(half %x) {
2211 ; CHECK-LABEL: @fcmp_sqrt_zero_ogt(
2212 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt half [[X:%.*]], 0xH0000
2213 ; CHECK-NEXT:    ret i1 [[CMP]]
2215   %sqrt = call half @llvm.sqrt.f16(half %x)
2216   %cmp = fcmp ogt half %sqrt, 0.0
2217   ret i1 %cmp
2220 define i1 @fcmp_sqrt_zero_ugt(half %x) {
2221 ; CHECK-LABEL: @fcmp_sqrt_zero_ugt(
2222 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une half [[X:%.*]], 0xH0000
2223 ; CHECK-NEXT:    ret i1 [[CMP]]
2225   %sqrt = call half @llvm.sqrt.f16(half %x)
2226   %cmp = fcmp ugt half %sqrt, 0.0
2227   ret i1 %cmp
2230 define i1 @fcmp_sqrt_zero_oge(half %x) {
2231 ; CHECK-LABEL: @fcmp_sqrt_zero_oge(
2232 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge half [[X:%.*]], 0xH0000
2233 ; CHECK-NEXT:    ret i1 [[CMP]]
2235   %sqrt = call half @llvm.sqrt.f16(half %x)
2236   %cmp = fcmp oge half %sqrt, 0.0
2237   ret i1 %cmp
2240 define i1 @fcmp_sqrt_zero_uge(half %x) {
2241 ; CHECK-LABEL: @fcmp_sqrt_zero_uge(
2242 ; CHECK-NEXT:    ret i1 true
2244   %sqrt = call half @llvm.sqrt.f16(half %x)
2245   %cmp = fcmp uge half %sqrt, 0.0
2246   ret i1 %cmp
2249 define i1 @fcmp_sqrt_zero_oeq(half %x) {
2250 ; CHECK-LABEL: @fcmp_sqrt_zero_oeq(
2251 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000
2252 ; CHECK-NEXT:    ret i1 [[CMP]]
2254   %sqrt = call half @llvm.sqrt.f16(half %x)
2255   %cmp = fcmp oeq half %sqrt, 0.0
2256   ret i1 %cmp
2259 define i1 @fcmp_sqrt_zero_ueq(half %x) {
2260 ; CHECK-LABEL: @fcmp_sqrt_zero_ueq(
2261 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule half [[X:%.*]], 0xH0000
2262 ; CHECK-NEXT:    ret i1 [[CMP]]
2264   %sqrt = call half @llvm.sqrt.f16(half %x)
2265   %cmp = fcmp ueq half %sqrt, 0.0
2266   ret i1 %cmp
2269 define i1 @fcmp_sqrt_zero_one(half %x) {
2270 ; CHECK-LABEL: @fcmp_sqrt_zero_one(
2271 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt half [[X:%.*]], 0xH0000
2272 ; CHECK-NEXT:    ret i1 [[CMP]]
2274   %sqrt = call half @llvm.sqrt.f16(half %x)
2275   %cmp = fcmp one half %sqrt, 0.0
2276   ret i1 %cmp
2279 define i1 @fcmp_sqrt_zero_une(half %x) {
2280 ; CHECK-LABEL: @fcmp_sqrt_zero_une(
2281 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une half [[X:%.*]], 0xH0000
2282 ; CHECK-NEXT:    ret i1 [[CMP]]
2284   %sqrt = call half @llvm.sqrt.f16(half %x)
2285   %cmp = fcmp une half %sqrt, 0.0
2286   ret i1 %cmp
2289 define i1 @fcmp_sqrt_zero_ord(half %x) {
2290 ; CHECK-LABEL: @fcmp_sqrt_zero_ord(
2291 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge half [[X:%.*]], 0xH0000
2292 ; CHECK-NEXT:    ret i1 [[CMP]]
2294   %sqrt = call half @llvm.sqrt.f16(half %x)
2295   %cmp = fcmp ord half %sqrt, 0.0
2296   ret i1 %cmp
2299 define i1 @fcmp_sqrt_zero_uno(half %x) {
2300 ; CHECK-LABEL: @fcmp_sqrt_zero_uno(
2301 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH0000
2302 ; CHECK-NEXT:    ret i1 [[CMP]]
2304   %sqrt = call half @llvm.sqrt.f16(half %x)
2305   %cmp = fcmp uno half %sqrt, 0.0
2306   ret i1 %cmp
2309 ; Make sure that ninf is cleared.
2310 define i1 @fcmp_sqrt_zero_uno_fmf(half %x) {
2311 ; CHECK-LABEL: @fcmp_sqrt_zero_uno_fmf(
2312 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult half [[X:%.*]], 0xH0000
2313 ; CHECK-NEXT:    ret i1 [[CMP]]
2315   %sqrt = call half @llvm.sqrt.f16(half %x)
2316   %cmp = fcmp ninf uno half %sqrt, 0.0
2317   ret i1 %cmp
2320 define i1 @fcmp_sqrt_zero_uno_fmf_sqrt_ninf(half %x) {
2321 ; CHECK-LABEL: @fcmp_sqrt_zero_uno_fmf_sqrt_ninf(
2322 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ult half [[X:%.*]], 0xH0000
2323 ; CHECK-NEXT:    ret i1 [[CMP]]
2325   %sqrt = call ninf half @llvm.sqrt.f16(half %x)
2326   %cmp = fcmp ninf uno half %sqrt, 0.0
2327   ret i1 %cmp
2330 ; negative tests
2332 define i1 @fcmp_sqrt_zero_ult_var(half %x, half %y) {
2333 ; CHECK-LABEL: @fcmp_sqrt_zero_ult_var(
2334 ; CHECK-NEXT:    [[SQRT:%.*]] = call half @llvm.sqrt.f16(half [[X:%.*]])
2335 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult half [[SQRT]], [[Y:%.*]]
2336 ; CHECK-NEXT:    ret i1 [[CMP]]
2338   %sqrt = call half @llvm.sqrt.f16(half %x)
2339   %cmp = fcmp ult half %sqrt, %y
2340   ret i1 %cmp
2343 define i1 @fcmp_sqrt_zero_ult_nonzero(half %x) {
2344 ; CHECK-LABEL: @fcmp_sqrt_zero_ult_nonzero(
2345 ; CHECK-NEXT:    [[SQRT:%.*]] = call half @llvm.sqrt.f16(half [[X:%.*]])
2346 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult half [[SQRT]], 0xH3C00
2347 ; CHECK-NEXT:    ret i1 [[CMP]]
2349   %sqrt = call half @llvm.sqrt.f16(half %x)
2350   %cmp = fcmp ult half %sqrt, 1.000000e+00
2351   ret i1 %cmp