1 ; RUN: opt < %s -instcombine -S | FileCheck %s
3 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
4 target triple = "x86_64-unknown-linux-gnu"
6 ; Check for and against shrinkage when using the
7 ; unsafe-fp-math function attribute on a math lib
8 ; function. This optimization may be overridden by
9 ; the -enable-double-float-shrink option.
10 ; PR17850: http://llvm.org/bugs/show_bug.cgi?id=17850
12 define float @acos_test1(float %f) {
13 %conv = fpext float %f to double
14 %call = call fast double @acos(double %conv)
15 %conv1 = fptrunc double %call to float
17 ; CHECK-LABEL: acos_test1
18 ; CHECK: call fast float @acosf(float %f)
21 define double @acos_test2(float %f) {
22 %conv = fpext float %f to double
23 %call = call fast double @acos(double %conv)
25 ; CHECK-LABEL: acos_test2
26 ; CHECK: call fast double @acos(double %conv)
29 define float @acosh_test1(float %f) {
30 %conv = fpext float %f to double
31 %call = call fast double @acosh(double %conv)
32 %conv1 = fptrunc double %call to float
34 ; CHECK-LABEL: acosh_test1
35 ; CHECK: call fast float @acoshf(float %f)
38 define double @acosh_test2(float %f) {
39 %conv = fpext float %f to double
40 %call = call fast double @acosh(double %conv)
42 ; CHECK-LABEL: acosh_test2
43 ; CHECK: call fast double @acosh(double %conv)
46 define float @asin_test1(float %f) {
47 %conv = fpext float %f to double
48 %call = call fast double @asin(double %conv)
49 %conv1 = fptrunc double %call to float
51 ; CHECK-LABEL: asin_test1
52 ; CHECK: call fast float @asinf(float %f)
55 define double @asin_test2(float %f) {
56 %conv = fpext float %f to double
57 %call = call fast double @asin(double %conv)
59 ; CHECK-LABEL: asin_test2
60 ; CHECK: call fast double @asin(double %conv)
63 define float @asinh_test1(float %f) {
64 %conv = fpext float %f to double
65 %call = call fast double @asinh(double %conv)
66 %conv1 = fptrunc double %call to float
68 ; CHECK-LABEL: asinh_test1
69 ; CHECK: call fast float @asinhf(float %f)
72 define double @asinh_test2(float %f) {
73 %conv = fpext float %f to double
74 %call = call fast double @asinh(double %conv)
76 ; CHECK-LABEL: asinh_test2
77 ; CHECK: call fast double @asinh(double %conv)
80 define float @atan_test1(float %f) {
81 %conv = fpext float %f to double
82 %call = call fast double @atan(double %conv)
83 %conv1 = fptrunc double %call to float
85 ; CHECK-LABEL: atan_test1
86 ; CHECK: call fast float @atanf(float %f)
89 define double @atan_test2(float %f) {
90 %conv = fpext float %f to double
91 %call = call fast double @atan(double %conv)
93 ; CHECK-LABEL: atan_test2
94 ; CHECK: call fast double @atan(double %conv)
97 define float @atanh_test1(float %f) {
98 %conv = fpext float %f to double
99 %call = call fast double @atanh(double %conv)
100 %conv1 = fptrunc double %call to float
102 ; CHECK-LABEL: atanh_test1
103 ; CHECK: call fast float @atanhf(float %f)
106 define double @atanh_test2(float %f) {
107 %conv = fpext float %f to double
108 %call = call fast double @atanh(double %conv)
110 ; CHECK-LABEL: atanh_test2
111 ; CHECK: call fast double @atanh(double %conv)
114 define float @cbrt_test1(float %f) {
115 %conv = fpext float %f to double
116 %call = call fast double @cbrt(double %conv)
117 %conv1 = fptrunc double %call to float
119 ; CHECK-LABEL: cbrt_test1
120 ; CHECK: call fast float @cbrtf(float %f)
123 define double @cbrt_test2(float %f) {
124 %conv = fpext float %f to double
125 %call = call fast double @cbrt(double %conv)
127 ; CHECK-LABEL: cbrt_test2
128 ; CHECK: call fast double @cbrt(double %conv)
131 define float @exp_test1(float %f) {
132 %conv = fpext float %f to double
133 %call = call fast double @exp(double %conv)
134 %conv1 = fptrunc double %call to float
136 ; CHECK-LABEL: exp_test1
137 ; CHECK: call fast float @expf(float %f)
140 define double @exp_test2(float %f) {
141 %conv = fpext float %f to double
142 %call = call fast double @exp(double %conv)
144 ; CHECK-LABEL: exp_test2
145 ; CHECK: call fast double @exp(double %conv)
148 define float @expm1_test1(float %f) {
149 %conv = fpext float %f to double
150 %call = call fast double @expm1(double %conv)
151 %conv1 = fptrunc double %call to float
153 ; CHECK-LABEL: expm1_test1
154 ; CHECK: call fast float @expm1f(float %f)
157 define double @expm1_test2(float %f) {
158 %conv = fpext float %f to double
159 %call = call fast double @expm1(double %conv)
161 ; CHECK-LABEL: expm1_test2
162 ; CHECK: call fast double @expm1(double %conv)
165 ; exp10f() doesn't exist for this triple, so it doesn't shrink.
167 define float @exp10_test1(float %f) {
168 %conv = fpext float %f to double
169 %call = call fast double @exp10(double %conv)
170 %conv1 = fptrunc double %call to float
172 ; CHECK-LABEL: exp10_test1
173 ; CHECK: call fast double @exp10(double %conv)
176 define double @exp10_test2(float %f) {
177 %conv = fpext float %f to double
178 %call = call fast double @exp10(double %conv)
180 ; CHECK-LABEL: exp10_test2
181 ; CHECK: call fast double @exp10(double %conv)
184 define float @log_test1(float %f) {
185 %conv = fpext float %f to double
186 %call = call fast double @log(double %conv)
187 %conv1 = fptrunc double %call to float
189 ; CHECK-LABEL: log_test1
190 ; CHECK: call fast float @logf(float %f)
193 define double @log_test2(float %f) {
194 %conv = fpext float %f to double
195 %call = call fast double @log(double %conv)
197 ; CHECK-LABEL: log_test2
198 ; CHECK: call fast double @log(double %conv)
201 define float @log10_test1(float %f) {
202 %conv = fpext float %f to double
203 %call = call fast double @log10(double %conv)
204 %conv1 = fptrunc double %call to float
206 ; CHECK-LABEL: log10_test1
207 ; CHECK: call fast float @log10f(float %f)
210 define double @log10_test2(float %f) {
211 %conv = fpext float %f to double
212 %call = call fast double @log10(double %conv)
214 ; CHECK-LABEL: log10_test2
215 ; CHECK: call fast double @log10(double %conv)
218 define float @log1p_test1(float %f) {
219 %conv = fpext float %f to double
220 %call = call fast double @log1p(double %conv)
221 %conv1 = fptrunc double %call to float
223 ; CHECK-LABEL: log1p_test1
224 ; CHECK: call fast float @log1pf(float %f)
227 define double @log1p_test2(float %f) {
228 %conv = fpext float %f to double
229 %call = call fast double @log1p(double %conv)
231 ; CHECK-LABEL: log1p_test2
232 ; CHECK: call fast double @log1p(double %conv)
235 define float @log2_test1(float %f) {
236 %conv = fpext float %f to double
237 %call = call fast double @log2(double %conv)
238 %conv1 = fptrunc double %call to float
240 ; CHECK-LABEL: log2_test1
241 ; CHECK: call fast float @log2f(float %f)
244 define double @log2_test2(float %f) {
245 %conv = fpext float %f to double
246 %call = call fast double @log2(double %conv)
248 ; CHECK-LABEL: log2_test2
249 ; CHECK: call fast double @log2(double %conv)
252 define float @logb_test1(float %f) {
253 %conv = fpext float %f to double
254 %call = call fast double @logb(double %conv)
255 %conv1 = fptrunc double %call to float
257 ; CHECK-LABEL: logb_test1
258 ; CHECK: call fast float @logbf(float %f)
261 define double @logb_test2(float %f) {
262 %conv = fpext float %f to double
263 %call = call fast double @logb(double %conv)
265 ; CHECK-LABEL: logb_test2
266 ; CHECK: call fast double @logb(double %conv)
269 define float @sin_test1(float %f) {
270 %conv = fpext float %f to double
271 %call = call fast double @sin(double %conv)
272 %conv1 = fptrunc double %call to float
274 ; CHECK-LABEL: sin_test1
275 ; CHECK: call fast float @sinf(float %f)
278 define double @sin_test2(float %f) {
279 %conv = fpext float %f to double
280 %call = call fast double @sin(double %conv)
282 ; CHECK-LABEL: sin_test2
283 ; CHECK: call fast double @sin(double %conv)
286 define float @sqrt_test1(float %f) {
287 %conv = fpext float %f to double
288 %call = call double @sqrt(double %conv)
289 %conv1 = fptrunc double %call to float
291 ; CHECK-LABEL: sqrt_test1
292 ; CHECK: call float @sqrtf(float %f)
295 define double @sqrt_test2(float %f) {
296 %conv = fpext float %f to double
297 %call = call double @sqrt(double %conv)
299 ; CHECK-LABEL: sqrt_test2
300 ; CHECK: call double @sqrt(double %conv)
303 define float @sqrt_int_test1(float %f) {
304 %conv = fpext float %f to double
305 %call = call double @llvm.sqrt.f64(double %conv)
306 %conv1 = fptrunc double %call to float
308 ; CHECK-LABEL: sqrt_int_test1
309 ; CHECK: call float @llvm.sqrt.f32(float %f)
312 define double @sqrt_int_test2(float %f) {
313 %conv = fpext float %f to double
314 %call = call double @llvm.sqrt.f64(double %conv)
316 ; CHECK-LABEL: sqrt_int_test2
317 ; CHECK: call double @llvm.sqrt.f64(double %conv)
320 define float @tan_test1(float %f) {
321 %conv = fpext float %f to double
322 %call = call fast double @tan(double %conv)
323 %conv1 = fptrunc double %call to float
325 ; CHECK-LABEL: tan_test1
326 ; CHECK: call fast float @tanf(float %f)
329 define double @tan_test2(float %f) {
330 %conv = fpext float %f to double
331 %call = call fast double @tan(double %conv)
333 ; CHECK-LABEL: tan_test2
334 ; CHECK: call fast double @tan(double %conv)
336 define float @tanh_test1(float %f) {
337 %conv = fpext float %f to double
338 %call = call fast double @tanh(double %conv)
339 %conv1 = fptrunc double %call to float
341 ; CHECK-LABEL: tanh_test1
342 ; CHECK: call fast float @tanhf(float %f)
345 define double @tanh_test2(float %f) {
346 %conv = fpext float %f to double
347 %call = call fast double @tanh(double %conv)
349 ; CHECK-LABEL: tanh_test2
350 ; CHECK: call fast double @tanh(double %conv)
353 ; 'arcp' on an fmax() is meaningless. This test just proves that
354 ; flags are propagated for shrunken *binary* double FP calls.
355 define float @max1(float %a, float %b) {
356 %c = fpext float %a to double
357 %d = fpext float %b to double
358 %e = call arcp double @fmax(double %c, double %d)
359 %f = fptrunc double %e to float
363 ; CHECK-NEXT: call arcp float @fmaxf(float %a, float %b)
367 ; A function can have a name that matches a common libcall,
368 ; but with the wrong type(s). Let it be.
370 define float @fake_fmin(float %a, float %b) {
371 %c = fpext float %a to fp128
372 %d = fpext float %b to fp128
373 %e = call fp128 @fmin(fp128 %c, fp128 %d)
374 %f = fptrunc fp128 %e to float
377 ; CHECK-LABEL: fake_fmin(
378 ; CHECK-NEXT: %c = fpext float %a to fp128
379 ; CHECK-NEXT: %d = fpext float %b to fp128
380 ; CHECK-NEXT: %e = call fp128 @fmin(fp128 %c, fp128 %d)
381 ; CHECK-NEXT: %f = fptrunc fp128 %e to float
382 ; CHECK-NEXT: ret float %f
385 declare fp128 @fmin(fp128, fp128) ; This is not the 'fmin' you're looking for.
387 declare double @fmax(double, double)
389 declare double @tanh(double) #1
390 declare double @tan(double) #1
392 ; sqrt is a special case: the shrinking optimization
393 ; is valid even without unsafe-fp-math.
394 declare double @sqrt(double)
395 declare double @llvm.sqrt.f64(double)
397 declare double @sin(double) #1
398 declare double @log2(double) #1
399 declare double @log1p(double) #1
400 declare double @log10(double) #1
401 declare double @log(double) #1
402 declare double @logb(double) #1
403 declare double @exp10(double) #1
404 declare double @expm1(double) #1
405 declare double @exp(double) #1
406 declare double @cbrt(double) #1
407 declare double @atanh(double) #1
408 declare double @atan(double) #1
409 declare double @acos(double) #1
410 declare double @acosh(double) #1
411 declare double @asin(double) #1
412 declare double @asinh(double) #1
414 attributes #1 = { "unsafe-fp-math"="true" }