1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -instcombine < %s | FileCheck %s
3
4declare double @llvm.fabs.f64(double) readnone
5
6define i1 @test1(float %x, float %y) {
7; CHECK-LABEL: @test1(
8; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]]
9; CHECK-NEXT:    ret i1 [[CMP]]
10;
11  %ext1 = fpext float %x to double
12  %ext2 = fpext float %y to double
13  %cmp = fcmp ogt double %ext1, %ext2
14  ret i1 %cmp
15}
16
17define i1 @test2(float %a) {
18; CHECK-LABEL: @test2(
19; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[A:%.*]], 1.000000e+00
20; CHECK-NEXT:    ret i1 [[CMP]]
21;
22  %ext = fpext float %a to double
23  %cmp = fcmp ogt double %ext, 1.000000e+00
24  ret i1 %cmp
25}
26
27define i1 @test3(float %a) {
28; CHECK-LABEL: @test3(
29; CHECK-NEXT:    [[EXT:%.*]] = fpext float [[A:%.*]] to double
30; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x3FF0000000000001
31; CHECK-NEXT:    ret i1 [[CMP]]
32;
33  %ext = fpext float %a to double
34  %cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float.
35  ret i1 %cmp
36}
37
38define i1 @test4(float %a) {
39; CHECK-LABEL: @test4(
40; CHECK-NEXT:    [[EXT:%.*]] = fpext float [[A:%.*]] to double
41; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x36A0000000000000
42; CHECK-NEXT:    ret i1 [[CMP]]
43;
44  %ext = fpext float %a to double
45  %cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float.
46  ret i1 %cmp
47}
48
49define i1 @fneg_constant_swap_pred(float %x) {
50; CHECK-LABEL: @fneg_constant_swap_pred(
51; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[X:%.*]], -1.000000e+00
52; CHECK-NEXT:    ret i1 [[CMP]]
53;
54  %neg = fsub float -0.0, %x
55  %cmp = fcmp ogt float %neg, 1.0
56  ret i1 %cmp
57}
58
59define <2 x i1> @fneg_constant_swap_pred_vec(<2 x float> %x) {
60; CHECK-LABEL: @fneg_constant_swap_pred_vec(
61; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00>
62; CHECK-NEXT:    ret <2 x i1> [[CMP]]
63;
64  %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
65  %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>
66  ret <2 x i1> %cmp
67}
68
69define <2 x i1> @fneg_constant_swap_pred_vec_undef(<2 x float> %x) {
70; CHECK-LABEL: @fneg_constant_swap_pred_vec_undef(
71; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <2 x float> [[X:%.*]], <float -1.000000e+00, float -2.000000e+00>
72; CHECK-NEXT:    ret <2 x i1> [[CMP]]
73;
74  %neg = fsub <2 x float> <float undef, float -0.0>, %x
75  %cmp = fcmp ogt <2 x float> %neg, <float 1.0, float 2.0>
76  ret <2 x i1> %cmp
77}
78
79define i1 @fneg_fneg_swap_pred(float %x, float %y) {
80; CHECK-LABEL: @fneg_fneg_swap_pred(
81; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]]
82; CHECK-NEXT:    ret i1 [[CMP]]
83;
84  %neg1 = fsub float -0.0, %x
85  %neg2 = fsub float -0.0, %y
86  %cmp = fcmp olt float %neg1, %neg2
87  ret i1 %cmp
88}
89
90define <2 x i1> @fneg_fneg_swap_pred_vec(<2 x float> %x, <2 x float> %y) {
91; CHECK-LABEL: @fneg_fneg_swap_pred_vec(
92; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]]
93; CHECK-NEXT:    ret <2 x i1> [[CMP]]
94;
95  %neg1 = fsub <2 x float> <float -0.0, float -0.0>, %x
96  %neg2 = fsub <2 x float> <float -0.0, float -0.0>, %y
97  %cmp = fcmp olt <2 x float> %neg1, %neg2
98  ret <2 x i1> %cmp
99}
100
101define <2 x i1> @fneg_fneg_swap_pred_vec_undef(<2 x float> %x, <2 x float> %y) {
102; CHECK-LABEL: @fneg_fneg_swap_pred_vec_undef(
103; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <2 x float> [[X:%.*]], [[Y:%.*]]
104; CHECK-NEXT:    ret <2 x i1> [[CMP]]
105;
106  %neg1 = fsub <2 x float> <float -0.0, float undef>, %x
107  %neg2 = fsub <2 x float> <float undef, float -0.0>, %y
108  %cmp = fcmp olt <2 x float> %neg1, %neg2
109  ret <2 x i1> %cmp
110}
111
112define i1 @test7(float %x) {
113; CHECK-LABEL: @test7(
114; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[X:%.*]], 0.000000e+00
115; CHECK-NEXT:    ret i1 [[CMP]]
116;
117  %ext = fpext float %x to ppc_fp128
118  %cmp = fcmp ogt ppc_fp128 %ext, 0xM00000000000000000000000000000000
119  ret i1 %cmp
120}
121
122define float @test8(float %x) {
123; CHECK-LABEL: @test8(
124; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
125; CHECK-NEXT:    [[CONV2:%.*]] = uitofp i1 [[CMP]] to float
126; CHECK-NEXT:    ret float [[CONV2]]
127;
128  %conv = fpext float %x to double
129  %cmp = fcmp olt double %conv, 0.000000e+00
130  %conv1 = zext i1 %cmp to i32
131  %conv2 = sitofp i32 %conv1 to float
132  ret float %conv2
133; Float comparison to zero shouldn't cast to double.
134}
135
136declare double @fabs(double) readnone
137
138define i32 @test9(double %a) {
139; CHECK-LABEL: @test9(
140; CHECK-NEXT:    ret i32 0
141;
142  %call = tail call double @fabs(double %a)
143  %cmp = fcmp olt double %call, 0.000000e+00
144  %conv = zext i1 %cmp to i32
145  ret i32 %conv
146}
147
148define i32 @test9_intrinsic(double %a) {
149; CHECK-LABEL: @test9_intrinsic(
150; CHECK-NEXT:    ret i32 0
151;
152  %call = tail call double @llvm.fabs.f64(double %a)
153  %cmp = fcmp olt double %call, 0.000000e+00
154  %conv = zext i1 %cmp to i32
155  ret i32 %conv
156}
157
158define i32 @test10(double %a) {
159; CHECK-LABEL: @test10(
160; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[A:%.*]], 0.000000e+00
161; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
162; CHECK-NEXT:    ret i32 [[CONV]]
163;
164  %call = tail call double @fabs(double %a)
165  %cmp = fcmp ole double %call, 0.000000e+00
166  %conv = zext i1 %cmp to i32
167  ret i32 %conv
168}
169
170define i32 @test10_intrinsic(double %a) {
171; CHECK-LABEL: @test10_intrinsic(
172; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[A:%.*]], 0.000000e+00
173; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
174; CHECK-NEXT:    ret i32 [[CONV]]
175;
176  %call = tail call double @llvm.fabs.f64(double %a)
177  %cmp = fcmp ole double %call, 0.000000e+00
178  %conv = zext i1 %cmp to i32
179  ret i32 %conv
180}
181
182define i32 @test11(double %a) {
183; CHECK-LABEL: @test11(
184; CHECK-NEXT:    [[CMP:%.*]] = fcmp one double [[A:%.*]], 0.000000e+00
185; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
186; CHECK-NEXT:    ret i32 [[CONV]]
187;
188  %call = tail call double @fabs(double %a)
189  %cmp = fcmp ogt double %call, 0.000000e+00
190  %conv = zext i1 %cmp to i32
191  ret i32 %conv
192}
193
194define i32 @test11_intrinsic(double %a) {
195; CHECK-LABEL: @test11_intrinsic(
196; CHECK-NEXT:    [[CMP:%.*]] = fcmp one double [[A:%.*]], 0.000000e+00
197; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
198; CHECK-NEXT:    ret i32 [[CONV]]
199;
200  %call = tail call double @llvm.fabs.f64(double %a)
201  %cmp = fcmp ogt double %call, 0.000000e+00
202  %conv = zext i1 %cmp to i32
203  ret i32 %conv
204}
205
206define i32 @test12(double %a) {
207; CHECK-LABEL: @test12(
208; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord double [[A:%.*]], 0.000000e+00
209; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
210; CHECK-NEXT:    ret i32 [[CONV]]
211;
212  %call = tail call double @fabs(double %a)
213  %cmp = fcmp oge double %call, 0.000000e+00
214  %conv = zext i1 %cmp to i32
215  ret i32 %conv
216}
217
218define i32 @test12_intrinsic(double %a) {
219; CHECK-LABEL: @test12_intrinsic(
220; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord double [[A:%.*]], 0.000000e+00
221; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
222; CHECK-NEXT:    ret i32 [[CONV]]
223;
224  %call = tail call double @llvm.fabs.f64(double %a)
225  %cmp = fcmp oge double %call, 0.000000e+00
226  %conv = zext i1 %cmp to i32
227  ret i32 %conv
228}
229
230define i32 @test13(double %a) {
231; CHECK-LABEL: @test13(
232; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[A:%.*]], 0.000000e+00
233; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
234; CHECK-NEXT:    ret i32 [[CONV]]
235;
236  %call = tail call double @fabs(double %a)
237  %cmp = fcmp une double %call, 0.000000e+00
238  %conv = zext i1 %cmp to i32
239  ret i32 %conv
240}
241
242define i32 @test13_intrinsic(double %a) {
243; CHECK-LABEL: @test13_intrinsic(
244; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[A:%.*]], 0.000000e+00
245; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
246; CHECK-NEXT:    ret i32 [[CONV]]
247;
248  %call = tail call double @llvm.fabs.f64(double %a)
249  %cmp = fcmp une double %call, 0.000000e+00
250  %conv = zext i1 %cmp to i32
251  ret i32 %conv
252}
253
254define i32 @test14(double %a) {
255; CHECK-LABEL: @test14(
256; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[A:%.*]], 0.000000e+00
257; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
258; CHECK-NEXT:    ret i32 [[CONV]]
259;
260  %call = tail call double @fabs(double %a)
261  %cmp = fcmp oeq double %call, 0.000000e+00
262  %conv = zext i1 %cmp to i32
263  ret i32 %conv
264}
265
266define i32 @test14_intrinsic(double %a) {
267; CHECK-LABEL: @test14_intrinsic(
268; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[A:%.*]], 0.000000e+00
269; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
270; CHECK-NEXT:    ret i32 [[CONV]]
271;
272  %call = tail call double @llvm.fabs.f64(double %a)
273  %cmp = fcmp oeq double %call, 0.000000e+00
274  %conv = zext i1 %cmp to i32
275  ret i32 %conv
276}
277
278define i32 @test15(double %a) {
279; CHECK-LABEL: @test15(
280; CHECK-NEXT:    [[CMP:%.*]] = fcmp one double [[A:%.*]], 0.000000e+00
281; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
282; CHECK-NEXT:    ret i32 [[CONV]]
283;
284  %call = tail call double @fabs(double %a)
285  %cmp = fcmp one double %call, 0.000000e+00
286  %conv = zext i1 %cmp to i32
287  ret i32 %conv
288}
289
290define i32 @test15_intrinsic(double %a) {
291; CHECK-LABEL: @test15_intrinsic(
292; CHECK-NEXT:    [[CMP:%.*]] = fcmp one double [[A:%.*]], 0.000000e+00
293; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
294; CHECK-NEXT:    ret i32 [[CONV]]
295;
296  %call = tail call double @llvm.fabs.f64(double %a)
297  %cmp = fcmp one double %call, 0.000000e+00
298  %conv = zext i1 %cmp to i32
299  ret i32 %conv
300}
301
302define i32 @test16(double %a) {
303; CHECK-LABEL: @test16(
304; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq double [[A:%.*]], 0.000000e+00
305; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
306; CHECK-NEXT:    ret i32 [[CONV]]
307;
308  %call = tail call double @fabs(double %a)
309  %cmp = fcmp ueq double %call, 0.000000e+00
310  %conv = zext i1 %cmp to i32
311  ret i32 %conv
312}
313
314define i32 @test16_intrinsic(double %a) {
315; CHECK-LABEL: @test16_intrinsic(
316; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq double [[A:%.*]], 0.000000e+00
317; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
318; CHECK-NEXT:    ret i32 [[CONV]]
319;
320  %call = tail call double @llvm.fabs.f64(double %a)
321  %cmp = fcmp ueq double %call, 0.000000e+00
322  %conv = zext i1 %cmp to i32
323  ret i32 %conv
324}
325
326; Don't crash.
327define i32 @test17(double %a, double (double)* %p) {
328; CHECK-LABEL: @test17(
329; CHECK-NEXT:    [[CALL:%.*]] = tail call double [[P:%.*]](double [[A:%.*]])
330; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq double [[CALL]], 0.000000e+00
331; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[CMP]] to i32
332; CHECK-NEXT:    ret i32 [[CONV]]
333;
334  %call = tail call double %p(double %a)
335  %cmp = fcmp ueq double %call, 0.000000e+00
336  %conv = zext i1 %cmp to i32
337  ret i32 %conv
338}
339
340; Can fold fcmp with undef on one side by choosing NaN for the undef
341define i32 @test18_undef_unordered(float %a) {
342; CHECK-LABEL: @test18_undef_unordered(
343; CHECK-NEXT:    ret i32 1
344;
345  %cmp = fcmp ueq float %a, undef
346  %conv = zext i1 %cmp to i32
347  ret i32 %conv
348}
349; Can fold fcmp with undef on one side by choosing NaN for the undef
350define i32 @test18_undef_ordered(float %a) {
351; CHECK-LABEL: @test18_undef_ordered(
352; CHECK-NEXT:    ret i32 0
353;
354  %cmp = fcmp oeq float %a, undef
355  %conv = zext i1 %cmp to i32
356  ret i32 %conv
357}
358
359; Can fold fcmp with undef on both side
360;   fcmp u_pred undef, undef -> true
361;   fcmp o_pred undef, undef -> false
362; because whatever you choose for the first undef
363; you can choose NaN for the other undef
364define i1 @test19_undef_unordered() {
365; CHECK-LABEL: @test19_undef_unordered(
366; CHECK-NEXT:    ret i1 true
367;
368  %cmp = fcmp ueq float undef, undef
369  ret i1 %cmp
370}
371
372define i1 @test19_undef_ordered() {
373; CHECK-LABEL: @test19_undef_ordered(
374; CHECK-NEXT:    ret i1 false
375;
376  %cmp = fcmp oeq float undef, undef
377  ret i1 %cmp
378}
379
380