1; RUN: opt < %s -instcombine -S | FileCheck %s
2
3target 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"
4target triple = "x86_64-unknown-linux-gnu"
5
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
11
12define float @acos_test(float %f)   {
13   %conv = fpext float %f to double
14   %call = call double @acos(double %conv)
15   %conv1 = fptrunc double %call to float
16   ret float %conv1
17; CHECK-LABEL: acos_test
18; CHECK: call float @acosf(float %f)
19}
20
21define double @acos_test2(float %f)   {
22   %conv = fpext float %f to double
23   %call = call double @acos(double %conv)
24   ret double %call
25; CHECK-LABEL: acos_test2
26; CHECK: call double @acos(double %conv)
27}
28
29define float @acosh_test(float %f)   {
30   %conv = fpext float %f to double
31   %call = call double @acosh(double %conv)
32   %conv1 = fptrunc double %call to float
33   ret float %conv1
34; CHECK-LABEL: acosh_test
35; CHECK: call float @acoshf(float %f)
36}
37
38define double @acosh_test2(float %f)   {
39   %conv = fpext float %f to double
40   %call = call double @acosh(double %conv)
41   ret double %call
42; CHECK-LABEL: acosh_test2
43; CHECK: call double @acosh(double %conv)
44}
45
46define float @asin_test(float %f)   {
47   %conv = fpext float %f to double
48   %call = call double @asin(double %conv)
49   %conv1 = fptrunc double %call to float
50   ret float %conv1
51; CHECK-LABEL: asin_test
52; CHECK: call float @asinf(float %f)
53}
54
55define double @asin_test2(float %f)   {
56   %conv = fpext float %f to double
57   %call = call double @asin(double %conv)
58   ret double %call
59; CHECK-LABEL: asin_test2
60; CHECK: call double @asin(double %conv)
61}
62
63define float @asinh_test(float %f)   {
64   %conv = fpext float %f to double
65   %call = call double @asinh(double %conv)
66   %conv1 = fptrunc double %call to float
67   ret float %conv1
68; CHECK-LABEL: asinh_test
69; CHECK: call float @asinhf(float %f)
70}
71
72define double @asinh_test2(float %f)   {
73   %conv = fpext float %f to double
74   %call = call double @asinh(double %conv)
75   ret double %call
76; CHECK-LABEL: asinh_test2
77; CHECK: call double @asinh(double %conv)
78}
79
80define float @atan_test(float %f)   {
81   %conv = fpext float %f to double
82   %call = call double @atan(double %conv)
83   %conv1 = fptrunc double %call to float
84   ret float %conv1
85; CHECK-LABEL: atan_test
86; CHECK: call float @atanf(float %f)
87}
88
89define double @atan_test2(float %f)   {
90   %conv = fpext float %f to double
91   %call = call double @atan(double %conv)
92   ret double %call
93; CHECK-LABEL: atan_test2
94; CHECK: call double @atan(double %conv)
95}
96define float @atanh_test(float %f)   {
97   %conv = fpext float %f to double
98   %call = call double @atanh(double %conv)
99   %conv1 = fptrunc double %call to float
100   ret float %conv1
101; CHECK-LABEL: atanh_test
102; CHECK: call float @atanhf(float %f)
103}
104
105define double @atanh_test2(float %f)   {
106    %conv = fpext float %f to double
107    %call = call double @atanh(double %conv)
108    ret double %call
109; CHECK-LABEL: atanh_test2
110; CHECK: call double @atanh(double %conv)
111}
112define float @cbrt_test(float %f)   {
113   %conv = fpext float %f to double
114   %call = call double @cbrt(double %conv)
115   %conv1 = fptrunc double %call to float
116   ret float %conv1
117; CHECK-LABEL: cbrt_test
118; CHECK: call float @cbrtf(float %f)
119}
120
121define double @cbrt_test2(float %f)   {
122   %conv = fpext float %f to double
123   %call = call double @cbrt(double %conv)
124   ret double %call
125; CHECK-LABEL: cbrt_test2
126; CHECK: call double @cbrt(double %conv)
127}
128define float @exp_test(float %f)   {
129   %conv = fpext float %f to double
130   %call = call double @exp(double %conv)
131   %conv1 = fptrunc double %call to float
132   ret float %conv1
133; CHECK-LABEL: exp_test
134; CHECK: call float @expf(float %f)
135}
136
137define double @exp_test2(float %f)   {
138   %conv = fpext float %f to double
139   %call = call double @exp(double %conv)
140   ret double %call
141; CHECK-LABEL: exp_test2
142; CHECK: call double @exp(double %conv)
143}
144define float @expm1_test(float %f)   {
145   %conv = fpext float %f to double
146   %call = call double @expm1(double %conv)
147   %conv1 = fptrunc double %call to float
148   ret float %conv1
149; CHECK-LABEL: expm1_test
150; CHECK: call float @expm1f(float %f)
151}
152
153define double @expm1_test2(float %f)   {
154   %conv = fpext float %f to double
155   %call = call double @expm1(double %conv)
156   ret double %call
157; CHECK-LABEL: expm1_test2
158; CHECK: call double @expm1(double %conv)
159}
160define float @exp10_test(float %f)   {
161   %conv = fpext float %f to double
162   %call = call double @exp10(double %conv)
163   %conv1 = fptrunc double %call to float
164   ret float %conv1
165; CHECK-LABEL: exp10_test
166; CHECK: call double @exp10(double %conv)
167}
168
169define double @exp10_test2(float %f)   {
170   %conv = fpext float %f to double
171   %call = call double @exp10(double %conv)
172   ret double %call
173; CHECK-LABEL: exp10_test2
174; CHECK: call double @exp10(double %conv)
175}
176define float @log_test(float %f)   {
177   %conv = fpext float %f to double
178   %call = call double @log(double %conv)
179   %conv1 = fptrunc double %call to float
180   ret float %conv1
181; CHECK-LABEL: log_test
182; CHECK: call float @logf(float %f)
183}
184
185define double @log_test2(float %f)   {
186   %conv = fpext float %f to double
187   %call = call double @log(double %conv)
188   ret double %call
189; CHECK-LABEL: log_test2
190; CHECK: call double @log(double %conv)
191}
192define float @log10_test(float %f)   {
193   %conv = fpext float %f to double
194   %call = call double @log10(double %conv)
195   %conv1 = fptrunc double %call to float
196   ret float %conv1
197; CHECK-LABEL: log10_test
198; CHECK: call float @log10f(float %f)
199}
200
201define double @log10_test2(float %f) {
202   %conv = fpext float %f to double
203   %call = call double @log10(double %conv)
204   ret double %call
205; CHECK-LABEL: log10_test2
206; CHECK: call double @log10(double %conv)
207}
208define float @log1p_test(float %f)   {
209   %conv = fpext float %f to double
210   %call = call double @log1p(double %conv)
211   %conv1 = fptrunc double %call to float
212   ret float %conv1
213; CHECK-LABEL: log1p_test
214; CHECK: call float @log1pf(float %f)
215}
216
217define double @log1p_test2(float %f)   {
218   %conv = fpext float %f to double
219   %call = call double @log1p(double %conv)
220   ret double %call
221; CHECK-LABEL: log1p_test2
222; CHECK: call double @log1p(double %conv)
223}
224define float @log2_test(float %f)   {
225   %conv = fpext float %f to double
226   %call = call double @log2(double %conv)
227   %conv1 = fptrunc double %call to float
228   ret float %conv1
229; CHECK-LABEL: log2_test
230; CHECK: call float @log2f(float %f)
231}
232
233define double @log2_test2(float %f)   {
234   %conv = fpext float %f to double
235   %call = call double @log2(double %conv)
236   ret double %call
237; CHECK-LABEL: log2_test2
238; CHECK: call double @log2(double %conv)
239}
240define float @logb_test(float %f)   {
241   %conv = fpext float %f to double
242   %call = call double @logb(double %conv)
243   %conv1 = fptrunc double %call to float
244   ret float %conv1
245; CHECK-LABEL: logb_test
246; CHECK: call float @logbf(float %f)
247}
248
249define double @logb_test2(float %f)   {
250   %conv = fpext float %f to double
251   %call = call double @logb(double %conv)
252   ret double %call
253; CHECK-LABEL: logb_test2
254; CHECK: call double @logb(double %conv)
255}
256define float @sin_test(float %f)   {
257   %conv = fpext float %f to double
258   %call = call double @sin(double %conv)
259   %conv1 = fptrunc double %call to float
260   ret float %conv1
261; CHECK-LABEL: sin_test
262; CHECK: call float @sinf(float %f)
263}
264
265define double @sin_test2(float %f) {
266   %conv = fpext float %f to double
267   %call = call double @sin(double %conv)
268   ret double %call
269; CHECK-LABEL: sin_test2
270; CHECK: call double @sin(double %conv)
271}
272
273define float @sqrt_test(float %f) {
274   %conv = fpext float %f to double
275   %call = call double @sqrt(double %conv)
276   %conv1 = fptrunc double %call to float
277   ret float %conv1
278; CHECK-LABEL: sqrt_test
279; CHECK: call float @sqrtf(float %f)
280}
281
282define double @sqrt_test2(float %f) {
283   %conv = fpext float %f to double
284   %call = call double @sqrt(double %conv)
285   ret double %call
286; CHECK-LABEL: sqrt_test2
287; CHECK: call double @sqrt(double %conv)
288}
289
290define float @sqrt_int_test(float %f) {
291   %conv = fpext float %f to double
292   %call = call double @llvm.sqrt.f64(double %conv)
293   %conv1 = fptrunc double %call to float
294   ret float %conv1
295; CHECK-LABEL: sqrt_int_test
296; CHECK: call float @llvm.sqrt.f32(float %f)
297}
298
299define double @sqrt_int_test2(float %f) {
300   %conv = fpext float %f to double
301   %call = call double @llvm.sqrt.f64(double %conv)
302   ret double %call
303; CHECK-LABEL: sqrt_int_test2
304; CHECK: call double @llvm.sqrt.f64(double %conv)
305}
306
307define float @tan_test(float %f) {
308   %conv = fpext float %f to double
309   %call = call double @tan(double %conv)
310   %conv1 = fptrunc double %call to float
311   ret float %conv1
312; CHECK-LABEL: tan_test
313; CHECK: call float @tanf(float %f)
314}
315
316define double @tan_test2(float %f) {
317   %conv = fpext float %f to double
318   %call = call double @tan(double %conv)
319   ret double %call
320; CHECK-LABEL: tan_test2
321; CHECK: call double @tan(double %conv)
322}
323define float @tanh_test(float %f) {
324   %conv = fpext float %f to double
325   %call = call double @tanh(double %conv)
326   %conv1 = fptrunc double %call to float
327   ret float %conv1
328; CHECK-LABEL: tanh_test
329; CHECK: call float @tanhf(float %f)
330}
331
332define double @tanh_test2(float %f) {
333   %conv = fpext float %f to double
334   %call = call double @tanh(double %conv)
335   ret double %call
336; CHECK-LABEL: tanh_test2
337; CHECK: call double @tanh(double %conv)
338}
339
340declare double @tanh(double) #1
341declare double @tan(double) #1
342
343; sqrt is a special case: the shrinking optimization
344; is valid even without unsafe-fp-math.
345declare double @sqrt(double)
346declare double @llvm.sqrt.f64(double)
347
348declare double @sin(double) #1
349declare double @log2(double) #1
350declare double @log1p(double) #1
351declare double @log10(double) #1
352declare double @log(double) #1
353declare double @logb(double) #1
354declare double @exp10(double) #1
355declare double @expm1(double) #1
356declare double @exp(double) #1
357declare double @cbrt(double) #1
358declare double @atanh(double) #1
359declare double @atan(double) #1
360declare double @acos(double) #1
361declare double @acosh(double) #1
362declare double @asin(double) #1
363declare double @asinh(double) #1
364
365attributes #1 = { "unsafe-fp-math"="true" }
366
367