xref: /llvm-project/llvm/test/Transforms/InstCombine/fcmp.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3
4declare half @llvm.fabs.f16(half)
5declare double @llvm.fabs.f64(double)
6declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
7declare double @llvm.copysign.f64(double, double)
8declare <2 x double> @llvm.copysign.v2f64(<2 x double>, <2 x double>)
9
10declare void @use(float)
11
12define 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]]
16;
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
21}
22
23define 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]]
27;
28  %ext = fpext float %a to double
29  %cmp = fcmp ninf ogt double %ext, 1.000000e+00
30  ret i1 %cmp
31}
32
33define <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]]
37;
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
41}
42
43define 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]]
48;
49  %ext = fpext float %a to double
50  %cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float.
51  ret i1 %cmp
52}
53
54define 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]]
59;
60  %ext = fpext float %a to double
61  %cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float.
62  ret i1 %cmp
63}
64
65define 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]]
69;
70  %neg = fsub float -0.0, %x
71  %cmp = fcmp ogt float %neg, 1.0
72  ret i1 %cmp
73}
74
75define 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]]
79;
80  %neg = fneg float %x
81  %cmp = fcmp ogt float %neg, 1.0
82  ret i1 %cmp
83}
84
85define <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]]
89;
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
93}
94
95define <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]]
99;
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
103}
104
105define <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]]
109;
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
113}
114
115; The new fcmp should have the same FMF as the original.
116
117define 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]]
121;
122  %n = fsub fast float -0.0, %x
123  %r = fcmp fast oeq float %n, 42.0
124  ret i1 %r
125}
126
127define 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]]
131;
132  %n = fneg fast float %x
133  %r = fcmp fast oeq float %n, 42.0
134  ret i1 %r
135}
136
137; The new fcmp should have the same FMF as the original, vector edition.
138
139define <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]]
143;
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
147}
148
149define 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]]
153;
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
158}
159
160define 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]]
164;
165  %neg1 = fneg float %x
166  %neg2 = fneg float %y
167  %cmp = fcmp nnan olt float %neg1, %neg2
168  ret i1 %cmp
169}
170
171define 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]]
175;
176  %neg1 = fneg float %x
177  %neg2 = fsub float -0.0, %y
178  %cmp = fcmp nnan olt float %neg1, %neg2
179  ret i1 %cmp
180}
181
182define 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]]
186;
187  %neg1 = fsub float -0.0, %x
188  %neg2 = fneg float %y
189  %cmp = fcmp nnan olt float %neg1, %neg2
190  ret i1 %cmp
191}
192
193define <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]]
197;
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
202}
203
204define <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]]
208;
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
213}
214
215define <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]]
219;
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
224}
225
226define <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]]
230;
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
235}
236
237define <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]]
241;
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
246}
247
248define <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]]
252;
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
257}
258
259define <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]]
263;
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
268}
269
270define 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]]
274;
275  %ext = fpext float %x to ppc_fp128
276  %cmp = fcmp ogt ppc_fp128 %ext, 0xM00000000000000000000000000000000
277  ret i1 %cmp
278}
279
280define 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]]
285;
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.
292}
293
294define i1 @fabs_uge(double %a) {
295; CHECK-LABEL: @fabs_uge(
296; CHECK-NEXT:    ret i1 true
297;
298  %call = call double @llvm.fabs.f64(double %a)
299  %cmp = fcmp uge double %call, 0.0
300  ret i1 %cmp
301}
302
303define i1 @fabs_olt(half %a) {
304; CHECK-LABEL: @fabs_olt(
305; CHECK-NEXT:    ret i1 false
306;
307  %call = call half @llvm.fabs.f16(half %a)
308  %cmp = fcmp olt half %call, 0.0
309  ret i1 %cmp
310}
311
312define <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]]
316;
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
320}
321
322define <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]]
326;
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
330}
331
332define 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]]
336;
337  %call = call double @llvm.fabs.f64(double %a)
338  %cmp = fcmp reassoc ogt double %call, 0.0
339  ret i1 %cmp
340}
341
342define 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]]
346;
347  %call = call double @llvm.fabs.f64(double %a)
348  %cmp = fcmp ninf reassoc ugt double %call, 0.0
349  ret i1 %cmp
350}
351
352define 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]]
356;
357  %call = call double @llvm.fabs.f64(double %a)
358  %cmp = fcmp afn oge double %call, 0.0
359  ret i1 %cmp
360}
361
362define 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]]
366;
367  %call = call double @llvm.fabs.f64(double %a)
368  %cmp = fcmp reassoc arcp ult double %call, 0.0
369  ret i1 %cmp
370}
371
372define <2 x i1> @fabs_ult_nnan(<2 x float> %a) {
373; CHECK-LABEL: @fabs_ult_nnan(
374; CHECK-NEXT:    ret <2 x i1> zeroinitializer
375;
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
379}
380
381define 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]]
385;
386  %call = call half @llvm.fabs.f16(half %a)
387  %cmp = fcmp ninf une half %call, 0.0
388  ret i1 %cmp
389}
390
391define 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]]
395;
396  %call = call double @llvm.fabs.f64(double %a)
397  %cmp = fcmp ninf reassoc oeq double %call, 0.0
398  ret i1 %cmp
399}
400
401define 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]]
405;
406  %call = call double @llvm.fabs.f64(double %a)
407  %cmp = fcmp fast one double %call, 0.0
408  ret i1 %cmp
409}
410
411define <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]]
415;
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
419}
420
421define <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]]
425;
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
429}
430
431define <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]]
435;
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
439}
440
441; Don't crash.
442define 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]]
448;
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
453}
454
455; Can fold fcmp with undef on one side by choosing NaN for the undef
456define i32 @test18_undef_unordered(float %a) {
457; CHECK-LABEL: @test18_undef_unordered(
458; CHECK-NEXT:    ret i32 1
459;
460  %cmp = fcmp ueq float %a, undef
461  %conv = zext i1 %cmp to i32
462  ret i32 %conv
463}
464; Can fold fcmp with undef on one side by choosing NaN for the undef
465define i32 @test18_undef_ordered(float %a) {
466; CHECK-LABEL: @test18_undef_ordered(
467; CHECK-NEXT:    ret i32 0
468;
469  %cmp = fcmp oeq float %a, undef
470  %conv = zext i1 %cmp to i32
471  ret i32 %conv
472}
473
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
479define i1 @test19_undef_unordered() {
480; CHECK-LABEL: @test19_undef_unordered(
481; CHECK-NEXT:    ret i1 true
482;
483  %cmp = fcmp ueq float undef, undef
484  ret i1 %cmp
485}
486
487define i1 @test19_undef_ordered() {
488; CHECK-LABEL: @test19_undef_ordered(
489; CHECK-NEXT:    ret i1 false
490;
491  %cmp = fcmp oeq float undef, undef
492  ret i1 %cmp
493}
494
495; Can fold 1.0 / X < 0.0 --> X < 0 with ninf
496define 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]]
500;
501  %div = fdiv ninf float 1.0, %X
502  %cmp = fcmp ninf olt float %div, 0.0
503  ret i1 %cmp
504}
505
506; Can fold -2.0 / X <= 0.0 --> X >= 0 with ninf
507define 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]]
511;
512  %div = fdiv ninf float -2.0, %X
513  %cmp = fcmp ninf ole float %div, 0.0
514  ret i1 %cmp
515}
516
517; Can fold 2.0 / X > 0.0 --> X > 0 with ninf
518define 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]]
522;
523  %div = fdiv ninf float 2.0, %X
524  %cmp = fcmp ninf ogt float %div, 0.0
525  ret i1 %cmp
526}
527
528; Can fold -1.0 / X >= 0.0 --> X <= 0 with ninf
529define 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]]
533;
534  %div = fdiv ninf float -1.0, %X
535  %cmp = fcmp ninf oge float %div, 0.0
536  ret i1 %cmp
537}
538
539; Do not fold 1.0 / X > 0.0 when ninf is missing
540define 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]]
545;
546  %div = fdiv ninf float 2.0, %X
547  %cmp = fcmp ogt float %div, 0.0
548  ret i1 %cmp
549}
550
551; Do not fold 1.0 / X > 0.0 when ninf is missing
552define 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]]
557;
558  %div = fdiv float 2.0, %X
559  %cmp = fcmp ninf ogt float %div, 0.0
560  ret i1 %cmp
561}
562
563; Do not fold 1.0 / X > 0.0 with unordered predicates
564define 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]]
569;
570  %div = fdiv ninf float 2.0, %X
571  %cmp = fcmp ninf ugt float %div, 0.0
572  ret i1 %cmp
573}
574
575; Fold <-1.0, -1.0> / X > <-0.0, -0.0>
576define <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]]
580;
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
584}
585
586define 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]]
591;
592  %s = call double @llvm.copysign.f64(double 1.0, double %x)
593  %r = fcmp olt double %s, 0.0
594  ret i1 %r
595}
596
597define 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]]
602;
603  %s = call double @llvm.copysign.f64(double 1.0, double %x)
604  %r = fcmp ult double %s, 0.0
605  ret i1 %r
606}
607
608define 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]]
613;
614  %s = call double @llvm.copysign.f64(double 1.0, double %x)
615  %r = fcmp ole double %s, 0.0
616  ret i1 %r
617}
618
619define 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]]
624;
625  %s = call double @llvm.copysign.f64(double 1.0, double %x)
626  %r = fcmp ule double %s, 0.0
627  ret i1 %r
628}
629
630; Vectors are ok; the sign of zero in the compare doesn't matter; the copysign constant can be any non-zero number.
631
632define <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]]
637;
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
641}
642
643; TODO: Handle different predicates.
644
645define 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]]
650;
651  %s = call double @llvm.copysign.f64(double -42.0, double %x)
652  %r = fcmp ogt double %s, 0.0
653  ret i1 %r
654}
655
656define 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]]
661;
662  %s = call double @llvm.copysign.f64(double -42.0, double %x)
663  %r = fcmp ugt double %s, 0.0
664  ret i1 %r
665}
666
667define 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]]
672;
673  %s = call double @llvm.copysign.f64(double -42.0, double %x)
674  %r = fcmp oge double %s, 0.0
675  ret i1 %r
676}
677
678define 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]]
683;
684  %s = call double @llvm.copysign.f64(double -42.0, double %x)
685  %r = fcmp uge double %s, 0.0
686  ret i1 %r
687}
688
689; Negative test - uses
690
691define 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]]
697;
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
702}
703
704; TODO: Handle non-zero compare constant.
705
706define 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]]
711;
712  %s = call double @llvm.copysign.f64(double -42.0, double %x)
713  %r = fcmp ogt double %s, 1.0
714  ret i1 %r
715}
716
717; TODO: Handle zero copysign constant.
718
719define i1 @is_signbit_set_simplify_zero(double %x) {
720; CHECK-LABEL: @is_signbit_set_simplify_zero(
721; CHECK-NEXT:    ret i1 false
722;
723  %s = call double @llvm.copysign.f64(double 0.0, double %x)
724  %r = fcmp ogt double %s, 0.0
725  ret i1 %r
726}
727
728; TODO: Handle NaN copysign constant.
729
730define i1 @is_signbit_set_simplify_nan(double %x) {
731; CHECK-LABEL: @is_signbit_set_simplify_nan(
732; CHECK-NEXT:    ret i1 false
733;
734  %s = call double @llvm.copysign.f64(double 0xffffffffffffffff, double %x)
735  %r = fcmp ogt double %s, 0.0
736  ret i1 %r
737}
738
739define <2 x i1> @lossy_oeq(<2 x float> %x) {
740; CHECK-LABEL: @lossy_oeq(
741; CHECK-NEXT:    ret <2 x i1> zeroinitializer
742;
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
746}
747
748define 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]]
754;
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
759}
760
761define 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]]
765;
766  %e = fpext half %x to double
767  %r = fcmp ueq double %e, 65536.0
768  ret i1 %r
769}
770
771define i1 @lossy_une(half %x) {
772; CHECK-LABEL: @lossy_une(
773; CHECK-NEXT:    ret i1 true
774;
775  %e = fpext half %x to float
776  %r = fcmp une float %e, 2049.0
777  ret i1 %r
778}
779
780define <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]]
785;
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
789}
790
791define 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]]
797;
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
802}
803
804define 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]]
809;
810  %e = fpext half %x to double
811  %r = fcmp olt double %e, 65536.0
812  ret i1 %r
813}
814
815define 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]]
820;
821  %e = fpext half %x to float
822  %r = fcmp ole float %e, 2049.0
823  ret i1 %r
824}
825
826define <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]]
831;
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
835}
836
837define 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]]
843;
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
848}
849
850define 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]]
855;
856  %e = fpext half %x to double
857  %r = fcmp ult double %e, 65536.0
858  ret i1 %r
859}
860
861define 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]]
866;
867  %e = fpext half %x to float
868  %r = fcmp ule float %e, 2049.0
869  ret i1 %r
870}
871
872define 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]]
876;
877  %e = fpext half %x to double
878  %r = fcmp ord double %e, 65536.0
879  ret i1 %r
880}
881
882define 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]]
886;
887  %e = fpext half %x to float
888  %r = fcmp uno float %e, 2049.0
889  ret i1 %r
890}
891
892define 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]]
896;
897  %fneg = fneg float %a
898  %cmp = fcmp oeq float %fneg, %a
899  ret i1 %cmp
900}
901
902define 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]]
906;
907  %fneg = fneg half %a
908  %cmp = fcmp fast ogt half %fneg, %a
909  ret i1 %cmp
910}
911
912define <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]]
916;
917  %fneg = fneg fast <2 x float> %a
918  %cmp = fcmp oge <2 x float> %fneg, %a
919  ret <2 x i1> %cmp
920}
921
922define 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]]
928;
929  %fneg = fneg float %a
930  store float %fneg, ptr %q
931  %cmp = fcmp olt float %fneg, %a
932  ret i1 %cmp
933}
934
935define 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]]
939;
940  %fneg = fneg float %a
941  %cmp = fcmp nsz ole float %fneg, %a
942  ret i1 %cmp
943}
944
945define 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]]
949;
950  %fneg = fneg float %a
951  %cmp = fcmp nnan one float %fneg, %a
952  ret i1 %cmp
953}
954
955define 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]]
959;
960  %fneg = fneg float %a
961  %cmp = fcmp ninf ord float %fneg, %a
962  ret i1 %cmp
963}
964
965define 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]]
969;
970  %fneg = fneg float %a
971  %cmp = fcmp uno float %fneg, %a
972  ret i1 %cmp
973}
974
975define 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]]
979;
980  %fneg = fneg half %a
981  %cmp = fcmp fast ueq half %fneg, %a
982  ret i1 %cmp
983}
984
985define <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]]
989;
990  %fneg = fneg fast <2 x float> %a
991  %cmp = fcmp ugt <2 x float> %fneg, %a
992  ret <2 x i1> %cmp
993}
994
995define 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]]
1001;
1002  %fneg = fneg float %a
1003  store float %fneg, ptr %q
1004  %cmp = fcmp uge float %fneg, %a
1005  ret i1 %cmp
1006}
1007
1008define 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]]
1012;
1013  %fneg = fneg float %a
1014  %cmp = fcmp nsz ult float %fneg, %a
1015  ret i1 %cmp
1016}
1017
1018define 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]]
1022;
1023  %fneg = fneg float %a
1024  %cmp = fcmp nnan ule float %fneg, %a
1025  ret i1 %cmp
1026}
1027
1028define 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]]
1032;
1033  %fneg = fneg float %a
1034  %cmp = fcmp ninf une float %fneg, %a
1035  ret i1 %cmp
1036}
1037
1038define 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]]
1043;
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
1048}
1049
1050define 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]]
1055;
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
1060}
1061
1062define <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]]
1067;
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
1072}
1073
1074define 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]]
1081;
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
1087}
1088
1089define 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]]
1094;
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
1099}
1100
1101define 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]]
1106;
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
1111}
1112
1113define 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]]
1118;
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
1123}
1124
1125define 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]]
1130;
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
1135}
1136
1137define 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]]
1142;
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
1147}
1148
1149define <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]]
1154;
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
1159}
1160
1161define 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]]
1168;
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
1174}
1175
1176define 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]]
1181;
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
1186}
1187
1188define 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]]
1193;
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
1198}
1199
1200define 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]]
1205;
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
1210}
1211
1212define 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]]
1217;
1218  %f = bitcast i32 %x to float
1219  %r = fcmp oeq float %f, 0.0
1220  ret i1 %r
1221}
1222
1223define <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]]
1228;
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
1232}
1233
1234; negative test - extra use
1235
1236define 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]]
1242;
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
1247}
1248
1249; negative test - this could be transformed, but requires a new bitcast
1250
1251define 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]]
1256;
1257  %f = bitcast <2 x i16> %x to float
1258  %r = fcmp ogt float %f, 0.0
1259  ret i1 %r
1260}
1261
1262; negative test - wrong predicate
1263
1264define 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]]
1269;
1270  %f = bitcast i32 %x to float
1271  %r = fcmp ogt float %f, 0.0
1272  ret i1 %r
1273}
1274
1275; negative test - this could be transformed, but requires a new bitcast
1276
1277define <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]]
1282;
1283  %f = bitcast i32 %x to <1 x float>
1284  %cmp = fcmp oeq <1 x float> %f, zeroinitializer
1285  ret <1 x i1> %cmp
1286}
1287
1288; Simplify fcmp (x + 0.0), y => fcmp x, y
1289
1290define 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]]
1294;
1295  %add = fadd float %x, 0.000000e+00
1296  %cmp = fcmp ugt float %add, %y
1297  ret i1 %cmp
1298}
1299
1300define 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]]
1304;
1305  %add = fadd float %x, 0.000000e+00
1306  %cmp = fcmp uge float %add, %y
1307  ret i1 %cmp
1308}
1309
1310define 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]]
1314;
1315  %add = fadd float %x, 0.000000e+00
1316  %cmp = fcmp ogt float %add, %y
1317  ret i1 %cmp
1318}
1319
1320define 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]]
1324;
1325  %add = fadd float %x, 0.000000e+00
1326  %cmp = fcmp oge float %add, %y
1327  ret i1 %cmp
1328}
1329
1330define 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]]
1334;
1335  %add = fadd float %x, 0.000000e+00
1336  %cmp = fcmp ult float %add, %y
1337  ret i1 %cmp
1338}
1339
1340define 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]]
1344;
1345  %add = fadd float %x, 0.000000e+00
1346  %cmp = fcmp ule float %add, %y
1347  ret i1 %cmp
1348}
1349
1350define 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]]
1354;
1355  %add = fadd float %x, 0.000000e+00
1356  %cmp = fcmp olt float %add, %y
1357  ret i1 %cmp
1358}
1359
1360define 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]]
1364;
1365  %add = fadd float %x, 0.000000e+00
1366  %cmp = fcmp ole float %add, %y
1367  ret i1 %cmp
1368}
1369
1370define 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]]
1374;
1375  %add = fadd float %x, 0.000000e+00
1376  %cmp = fcmp oeq float %add, %y
1377  ret i1 %cmp
1378}
1379
1380define 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]]
1384;
1385  %add = fadd float %x, 0.000000e+00
1386  %cmp = fcmp one float %add, %y
1387  ret i1 %cmp
1388}
1389
1390define 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]]
1394;
1395  %add = fadd float %x, 0.000000e+00
1396  %cmp = fcmp ueq float %add, %y
1397  ret i1 %cmp
1398}
1399
1400define 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]]
1404;
1405  %add = fadd float %x, 0.000000e+00
1406  %cmp = fcmp une float %add, %y
1407  ret i1 %cmp
1408}
1409
1410define 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]]
1414;
1415  %add = fadd float %x, 0.000000e+00
1416  %cmp = fcmp ord float %add, %y
1417  ret i1 %cmp
1418}
1419
1420define 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]]
1424;
1425  %add = fadd float %x, 0.000000e+00
1426  %cmp = fcmp uno float %add, %y
1427  ret i1 %cmp
1428}
1429
1430define 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]]
1434;
1435  %add = fadd float %x, -0.000000e+00
1436  %cmp = fcmp ugt float %add, %y
1437  ret i1 %cmp
1438}
1439
1440define 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]]
1444;
1445  %add = fadd float %y, 0.000000e+00
1446  %cmp = fcmp ugt float %x, %add
1447  ret i1 %cmp
1448}
1449
1450define <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]]
1454;
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
1458}
1459
1460define 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]]
1464;
1465  %add = fadd fast float %x, 0.000000e+00
1466  %cmp = fcmp fast ugt float %add, %y
1467  ret i1 %cmp
1468}
1469
1470define 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]]
1474;
1475  %add = fadd float %x, 0.000000e+00
1476  %cmp = fcmp fast ugt float %add, %y
1477  ret i1 %cmp
1478}
1479
1480define 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]]
1484;
1485  %add = fadd fast float %x, 0.000000e+00
1486  %cmp = fcmp ugt float %add, %y
1487  ret i1 %cmp
1488}
1489
1490define 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]]
1494;
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
1500}
1501
1502define 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]]
1506;
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
1512}
1513
1514define 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]]
1518;
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
1524}
1525
1526define 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]]
1530;
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
1536}
1537
1538define 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]]
1542;
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
1548}
1549
1550define 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]]
1554;
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
1560}
1561
1562define 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]]
1566;
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
1572}
1573
1574define 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]]
1578;
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
1584}
1585
1586define <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]]
1590;
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
1596}
1597
1598define <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]]
1602;
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
1608}
1609
1610define <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]]
1614;
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
1620}
1621
1622define <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]]
1626;
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
1632}
1633
1634define <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]]
1638;
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
1643}
1644
1645define <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]]
1649;
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
1654}
1655
1656define <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]]
1660;
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
1665}
1666
1667define <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]]
1671;
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
1676}
1677
1678define <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]]
1682;
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
1687}
1688
1689define <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]]
1693;
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
1698}
1699
1700define <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]]
1704;
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
1709}
1710
1711define <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]]
1715;
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
1720}
1721
1722; negative test - extra use
1723
1724define 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]]
1730;
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
1735}
1736
1737; negative test - extra use
1738
1739define 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]]
1745;
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
1750}
1751
1752define 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]]
1757;
1758  %fs = fsub float %x, %y
1759  %cmp = fcmp oeq float %fs, 0.000000e+00
1760  ret i1 %cmp
1761}
1762
1763define 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]]
1768;
1769  %fs = fsub float %x, %y
1770  %cmp = fcmp oge float %fs, 0.000000e+00
1771  ret i1 %cmp
1772}
1773
1774define 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]]
1779;
1780  %fs = fsub float %x, %y
1781  %cmp = fcmp ole float %fs, 0.000000e+00
1782  ret i1 %cmp
1783}
1784
1785define 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]]
1789;
1790  %fs = fsub float %x, %y
1791  %cmp = fcmp ueq float %fs, 0.000000e+00
1792  ret i1 %cmp
1793}
1794
1795define 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]]
1799;
1800  %fs = fsub float %x, %y
1801  %cmp = fcmp uge float %fs, 0.000000e+00
1802  ret i1 %cmp
1803}
1804
1805define 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]]
1809;
1810  %fs = fsub float %x, %y
1811  %cmp = fcmp ule float %fs, 0.000000e+00
1812  ret i1 %cmp
1813}
1814
1815define 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]]
1820;
1821  %fs = fsub float %x, %y
1822  %cmp = fcmp ugt float %fs, 0.000000e+00
1823  ret i1 %cmp
1824}
1825
1826define 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]]
1831;
1832  %fs = fsub float %x, %y
1833  %cmp = fcmp ult float %fs, 0.000000e+00
1834  ret i1 %cmp
1835}
1836
1837define 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]]
1842;
1843  %fs = fsub float %x, %y
1844  %cmp = fcmp une float %fs, 0.000000e+00
1845  ret i1 %cmp
1846}
1847
1848define <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]]
1852;
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
1856}
1857
1858define <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]]
1862;
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
1866}
1867
1868define <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]]
1872;
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
1876}
1877
1878define <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]]
1882;
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
1886}
1887
1888define <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]]
1892;
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
1896}
1897
1898define <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]]
1902;
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
1906}
1907
1908define <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]]
1912;
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
1916}
1917
1918define <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]]
1922;
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
1926}
1927
1928define <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]]
1932;
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
1936}
1937
1938define <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]]
1942;
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
1946}
1947
1948define <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]]
1952;
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
1956}
1957
1958define <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]]
1962;
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
1966}
1967
1968define <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]]
1972;
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
1976}
1977
1978define <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]]
1982;
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
1986}
1987
1988define <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]]
1992;
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
1996}
1997
1998define <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]]
2002;
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
2006}
2007
2008define <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]]
2012;
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
2016}
2017
2018define <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]]
2022;
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
2026}
2027
2028define <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]]
2032;
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
2036}
2037
2038define <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]]
2042;
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
2046}
2047
2048define <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]]
2052;
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
2056}
2057
2058define <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]]
2062;
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
2066}
2067
2068define <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]]
2072;
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
2076}
2077
2078define <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]]
2082;
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
2086}
2087
2088define <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]]
2093;
2094  %fs = fsub <8 x float> %x, %y
2095  %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
2096  ret <8 x i1> %cmp
2097}
2098
2099define <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]]
2104;
2105  %fs = fsub <8 x float> %x, %y
2106  %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
2107  ret <8 x i1> %cmp
2108}
2109
2110define <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]]
2115;
2116  %fs = fsub <8 x float> %x, %y
2117  %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
2118  ret <8 x i1> %cmp
2119}
2120
2121define i1 @fcmp_sqrt_zero_olt(half %x) {
2122; CHECK-LABEL: @fcmp_sqrt_zero_olt(
2123; CHECK-NEXT:    ret i1 false
2124;
2125  %sqrt = call half @llvm.sqrt.f16(half %x)
2126  %cmp = fcmp olt half %sqrt, 0.0
2127  ret i1 %cmp
2128}
2129
2130define 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]]
2134;
2135  %sqrt = call half @llvm.sqrt.f16(half %x)
2136  %cmp = fcmp ult half %sqrt, 0.0
2137  ret i1 %cmp
2138}
2139
2140define 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]]
2144;
2145  %sqrt = call half @llvm.sqrt.f16(half %x)
2146  %cmp = fcmp ninf nsz ult half %sqrt, 0.0
2147  ret i1 %cmp
2148}
2149
2150define 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]]
2154;
2155  %sqrt = call ninf half @llvm.sqrt.f16(half %x)
2156  %cmp = fcmp ninf nsz ult half %sqrt, 0.0
2157  ret i1 %cmp
2158}
2159
2160define 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]]
2164;
2165  %sqrt = call half @llvm.sqrt.f16(half %x)
2166  %cmp = fcmp ult half %sqrt, -0.0
2167  ret i1 %cmp
2168}
2169
2170define <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]]
2174;
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
2178}
2179
2180define <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]]
2184;
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
2188}
2189
2190define 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]]
2194;
2195  %sqrt = call half @llvm.sqrt.f16(half %x)
2196  %cmp = fcmp ole half %sqrt, 0.0
2197  ret i1 %cmp
2198}
2199
2200define 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]]
2204;
2205  %sqrt = call half @llvm.sqrt.f16(half %x)
2206  %cmp = fcmp ule half %sqrt, 0.0
2207  ret i1 %cmp
2208}
2209
2210define 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]]
2214;
2215  %sqrt = call half @llvm.sqrt.f16(half %x)
2216  %cmp = fcmp ogt half %sqrt, 0.0
2217  ret i1 %cmp
2218}
2219
2220define 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]]
2224;
2225  %sqrt = call half @llvm.sqrt.f16(half %x)
2226  %cmp = fcmp ugt half %sqrt, 0.0
2227  ret i1 %cmp
2228}
2229
2230define 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]]
2234;
2235  %sqrt = call half @llvm.sqrt.f16(half %x)
2236  %cmp = fcmp oge half %sqrt, 0.0
2237  ret i1 %cmp
2238}
2239
2240define i1 @fcmp_sqrt_zero_uge(half %x) {
2241; CHECK-LABEL: @fcmp_sqrt_zero_uge(
2242; CHECK-NEXT:    ret i1 true
2243;
2244  %sqrt = call half @llvm.sqrt.f16(half %x)
2245  %cmp = fcmp uge half %sqrt, 0.0
2246  ret i1 %cmp
2247}
2248
2249define 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]]
2253;
2254  %sqrt = call half @llvm.sqrt.f16(half %x)
2255  %cmp = fcmp oeq half %sqrt, 0.0
2256  ret i1 %cmp
2257}
2258
2259define 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]]
2263;
2264  %sqrt = call half @llvm.sqrt.f16(half %x)
2265  %cmp = fcmp ueq half %sqrt, 0.0
2266  ret i1 %cmp
2267}
2268
2269define 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]]
2273;
2274  %sqrt = call half @llvm.sqrt.f16(half %x)
2275  %cmp = fcmp one half %sqrt, 0.0
2276  ret i1 %cmp
2277}
2278
2279define 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]]
2283;
2284  %sqrt = call half @llvm.sqrt.f16(half %x)
2285  %cmp = fcmp une half %sqrt, 0.0
2286  ret i1 %cmp
2287}
2288
2289define 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]]
2293;
2294  %sqrt = call half @llvm.sqrt.f16(half %x)
2295  %cmp = fcmp ord half %sqrt, 0.0
2296  ret i1 %cmp
2297}
2298
2299define 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]]
2303;
2304  %sqrt = call half @llvm.sqrt.f16(half %x)
2305  %cmp = fcmp uno half %sqrt, 0.0
2306  ret i1 %cmp
2307}
2308
2309; Make sure that ninf is cleared.
2310define 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]]
2314;
2315  %sqrt = call half @llvm.sqrt.f16(half %x)
2316  %cmp = fcmp ninf uno half %sqrt, 0.0
2317  ret i1 %cmp
2318}
2319
2320define 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]]
2324;
2325  %sqrt = call ninf half @llvm.sqrt.f16(half %x)
2326  %cmp = fcmp ninf uno half %sqrt, 0.0
2327  ret i1 %cmp
2328}
2329
2330; negative tests
2331
2332define 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]]
2337;
2338  %sqrt = call half @llvm.sqrt.f16(half %x)
2339  %cmp = fcmp ult half %sqrt, %y
2340  ret i1 %cmp
2341}
2342
2343define 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]]
2348;
2349  %sqrt = call half @llvm.sqrt.f16(half %x)
2350  %cmp = fcmp ult half %sqrt, 1.000000e+00
2351  ret i1 %cmp
2352}
2353