1 ; RUN: opt -S -instcombine < %s | FileCheck %s
3 declare double @llvm.fabs.f64(double) nounwind readnone
5 define 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 }
14 define 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 }
22 define 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 }
30 define 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 }
38 define 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 }
46 define 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 }
55 define 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 }
63 define 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 }
74 declare double @fabs(double) nounwind readnone
76 define 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 }
86 define 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 }
96 define 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 }
106 define 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 }
116 define 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 }
126 define 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 }
136 define 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 }
146 define 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 }
156 define 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 }
166 define 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 }
176 define 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 }
186 define 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 }
196 define 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 }
206 define 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 }
216 define 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 }
226 define 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 }
236 ; Don't crash.
237 define 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 }