• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt -S -instcombine < %s | FileCheck %s
2
3declare double @llvm.fabs.f64(double) nounwind readnone
4
5define i1 @test1(float %x, float %y) nounwind {
6  %ext1 = fpext float %x to double
7  %ext2 = fpext float %y to double
8  %cmp = fcmp ogt double %ext1, %ext2
9  ret i1 %cmp
10; CHECK-LABEL: @test1(
11; CHECK-NEXT: fcmp ogt float %x, %y
12}
13
14define i1 @test2(float %a) nounwind {
15  %ext = fpext float %a to double
16  %cmp = fcmp ogt double %ext, 1.000000e+00
17  ret i1 %cmp
18; CHECK-LABEL: @test2(
19; CHECK-NEXT: fcmp ogt float %a, 1.0
20}
21
22define i1 @test3(float %a) nounwind {
23  %ext = fpext float %a to double
24  %cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float.
25  ret i1 %cmp
26; CHECK-LABEL: @test3(
27; CHECK-NEXT: fpext float %a to double
28}
29
30define i1 @test4(float %a) nounwind {
31  %ext = fpext float %a to double
32  %cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float.
33  ret i1 %cmp
34; CHECK-LABEL: @test4(
35; CHECK-NEXT: fpext float %a to double
36}
37
38define i1 @test5(float %a) nounwind {
39  %neg = fsub float -0.000000e+00, %a
40  %cmp = fcmp ogt float %neg, 1.000000e+00
41  ret i1 %cmp
42; CHECK-LABEL: @test5(
43; CHECK-NEXT: fcmp olt float %a, -1.0
44}
45
46define i1 @test6(float %x, float %y) nounwind {
47  %neg1 = fsub float -0.000000e+00, %x
48  %neg2 = fsub float -0.000000e+00, %y
49  %cmp = fcmp olt float %neg1, %neg2
50  ret i1 %cmp
51; CHECK-LABEL: @test6(
52; CHECK-NEXT: fcmp ogt float %x, %y
53}
54
55define i1 @test7(float %x) nounwind readnone ssp noredzone {
56  %ext = fpext float %x to ppc_fp128
57  %cmp = fcmp ogt ppc_fp128 %ext, 0xM00000000000000000000000000000000
58  ret i1 %cmp
59; CHECK-LABEL: @test7(
60; CHECK-NEXT: fcmp ogt float %x, 0.000000e+00
61}
62
63define float @test8(float %x) nounwind readnone optsize ssp {
64  %conv = fpext float %x to double
65  %cmp = fcmp olt double %conv, 0.000000e+00
66  %conv1 = zext i1 %cmp to i32
67  %conv2 = sitofp i32 %conv1 to float
68  ret float %conv2
69; Float comparison to zero shouldn't cast to double.
70; CHECK-LABEL: @test8(
71; CHECK-NEXT: fcmp olt float %x, 0.000000e+00
72}
73
74declare double @fabs(double) nounwind readnone
75
76define i32 @test9(double %a) nounwind {
77  %call = tail call double @fabs(double %a) nounwind
78  %cmp = fcmp olt double %call, 0.000000e+00
79  %conv = zext i1 %cmp to i32
80  ret i32 %conv
81; CHECK-LABEL: @test9(
82; CHECK-NOT: fabs
83; CHECK: ret i32 0
84}
85
86define i32 @test9_intrinsic(double %a) nounwind {
87  %call = tail call double @llvm.fabs.f64(double %a) nounwind
88  %cmp = fcmp olt double %call, 0.000000e+00
89  %conv = zext i1 %cmp to i32
90  ret i32 %conv
91; CHECK-LABEL: @test9_intrinsic(
92; CHECK-NOT: fabs
93; CHECK: ret i32 0
94}
95
96define i32 @test10(double %a) nounwind {
97  %call = tail call double @fabs(double %a) nounwind
98  %cmp = fcmp ole double %call, 0.000000e+00
99  %conv = zext i1 %cmp to i32
100  ret i32 %conv
101; CHECK-LABEL: @test10(
102; CHECK-NOT: fabs
103; CHECK: fcmp oeq double %a, 0.000000e+00
104}
105
106define i32 @test10_intrinsic(double %a) nounwind {
107  %call = tail call double @llvm.fabs.f64(double %a) nounwind
108  %cmp = fcmp ole double %call, 0.000000e+00
109  %conv = zext i1 %cmp to i32
110  ret i32 %conv
111; CHECK-LABEL: @test10_intrinsic(
112; CHECK-NOT: fabs
113; CHECK: fcmp oeq double %a, 0.000000e+00
114}
115
116define i32 @test11(double %a) nounwind {
117  %call = tail call double @fabs(double %a) nounwind
118  %cmp = fcmp ogt double %call, 0.000000e+00
119  %conv = zext i1 %cmp to i32
120  ret i32 %conv
121; CHECK-LABEL: @test11(
122; CHECK-NOT: fabs
123; CHECK: fcmp one double %a, 0.000000e+00
124}
125
126define i32 @test11_intrinsic(double %a) nounwind {
127  %call = tail call double @llvm.fabs.f64(double %a) nounwind
128  %cmp = fcmp ogt double %call, 0.000000e+00
129  %conv = zext i1 %cmp to i32
130  ret i32 %conv
131; CHECK-LABEL: @test11_intrinsic(
132; CHECK-NOT: fabs
133; CHECK: fcmp one double %a, 0.000000e+00
134}
135
136define i32 @test12(double %a) nounwind {
137  %call = tail call double @fabs(double %a) nounwind
138  %cmp = fcmp oge double %call, 0.000000e+00
139  %conv = zext i1 %cmp to i32
140  ret i32 %conv
141; CHECK-LABEL: @test12(
142; CHECK-NOT: fabs
143; CHECK: fcmp ord double %a, 0.000000e+00
144}
145
146define i32 @test12_intrinsic(double %a) nounwind {
147  %call = tail call double @llvm.fabs.f64(double %a) nounwind
148  %cmp = fcmp oge double %call, 0.000000e+00
149  %conv = zext i1 %cmp to i32
150  ret i32 %conv
151; CHECK-LABEL: @test12_intrinsic(
152; CHECK-NOT: fabs
153; CHECK: fcmp ord double %a, 0.000000e+00
154}
155
156define i32 @test13(double %a) nounwind {
157  %call = tail call double @fabs(double %a) nounwind
158  %cmp = fcmp une double %call, 0.000000e+00
159  %conv = zext i1 %cmp to i32
160  ret i32 %conv
161; CHECK-LABEL: @test13(
162; CHECK-NOT: fabs
163; CHECK: fcmp une double %a, 0.000000e+00
164}
165
166define i32 @test13_intrinsic(double %a) nounwind {
167  %call = tail call double @llvm.fabs.f64(double %a) nounwind
168  %cmp = fcmp une double %call, 0.000000e+00
169  %conv = zext i1 %cmp to i32
170  ret i32 %conv
171; CHECK-LABEL: @test13_intrinsic(
172; CHECK-NOT: fabs
173; CHECK: fcmp une double %a, 0.000000e+00
174}
175
176define i32 @test14(double %a) nounwind {
177  %call = tail call double @fabs(double %a) nounwind
178  %cmp = fcmp oeq double %call, 0.000000e+00
179  %conv = zext i1 %cmp to i32
180  ret i32 %conv
181; CHECK-LABEL: @test14(
182; CHECK-NOT: fabs
183; CHECK: fcmp oeq double %a, 0.000000e+00
184}
185
186define i32 @test14_intrinsic(double %a) nounwind {
187  %call = tail call double @llvm.fabs.f64(double %a) nounwind
188  %cmp = fcmp oeq double %call, 0.000000e+00
189  %conv = zext i1 %cmp to i32
190  ret i32 %conv
191; CHECK-LABEL: @test14_intrinsic(
192; CHECK-NOT: fabs
193; CHECK: fcmp oeq double %a, 0.000000e+00
194}
195
196define i32 @test15(double %a) nounwind {
197  %call = tail call double @fabs(double %a) nounwind
198  %cmp = fcmp one double %call, 0.000000e+00
199  %conv = zext i1 %cmp to i32
200  ret i32 %conv
201; CHECK-LABEL: @test15(
202; CHECK-NOT: fabs
203; CHECK: fcmp one double %a, 0.000000e+00
204}
205
206define i32 @test15_intrinsic(double %a) nounwind {
207  %call = tail call double @llvm.fabs.f64(double %a) nounwind
208  %cmp = fcmp one double %call, 0.000000e+00
209  %conv = zext i1 %cmp to i32
210  ret i32 %conv
211; CHECK-LABEL: @test15_intrinsic(
212; CHECK-NOT: fabs
213; CHECK: fcmp one double %a, 0.000000e+00
214}
215
216define i32 @test16(double %a) nounwind {
217  %call = tail call double @fabs(double %a) nounwind
218  %cmp = fcmp ueq double %call, 0.000000e+00
219  %conv = zext i1 %cmp to i32
220  ret i32 %conv
221; CHECK-LABEL: @test16(
222; CHECK-NOT: fabs
223; CHECK: fcmp ueq double %a, 0.000000e+00
224}
225
226define i32 @test16_intrinsic(double %a) nounwind {
227  %call = tail call double @llvm.fabs.f64(double %a) nounwind
228  %cmp = fcmp ueq double %call, 0.000000e+00
229  %conv = zext i1 %cmp to i32
230  ret i32 %conv
231; CHECK-LABEL: @test16_intrinsic(
232; CHECK-NOT: fabs
233; CHECK: fcmp ueq double %a, 0.000000e+00
234}
235
236; Don't crash.
237define i32 @test17(double %a, double (double)* %p) nounwind {
238  %call = tail call double %p(double %a) nounwind
239  %cmp = fcmp ueq double %call, 0.000000e+00
240  %conv = zext i1 %cmp to i32
241  ret i32 %conv
242}
243
244; Can fold fcmp with undef on one side by choosing NaN for the undef
245define i32 @test18_undef_unordered(float %a) nounwind {
246; CHECK-LABEL: @test18_undef_unordered
247; CHECK: ret i32 1
248  %cmp = fcmp ueq float %a, undef
249  %conv = zext i1 %cmp to i32
250  ret i32 %conv
251}
252; Can fold fcmp with undef on one side by choosing NaN for the undef
253define i32 @test18_undef_ordered(float %a) nounwind {
254; CHECK-LABEL: @test18_undef_ordered
255; CHECK: ret i32 0
256  %cmp = fcmp oeq float %a, undef
257  %conv = zext i1 %cmp to i32
258  ret i32 %conv
259}
260
261; Can fold fcmp with undef on both side
262;   fcmp u_pred undef, undef -> true
263;   fcmp o_pred undef, undef -> false
264; because whatever you choose for the first undef
265; you can choose NaN for the other undef
266define i1 @test19_undef_unordered() nounwind {
267; CHECK-LABEL: @test19_undef
268; CHECK: ret i1 true
269  %cmp = fcmp ueq float undef, undef
270  ret i1 %cmp
271}
272define i1 @test19_undef_ordered() nounwind {
273; CHECK-LABEL: @test19_undef
274; CHECK: ret i1 false
275  %cmp = fcmp oeq float undef, undef
276  ret i1 %cmp
277}
278