• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_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
16   ret float %conv1
17; CHECK-LABEL: acos_test1
18; CHECK: call fast float @acosf(float %f)
19}
20
21define double @acos_test2(float %f)   {
22   %conv = fpext float %f to double
23   %call = call fast double @acos(double %conv)
24   ret double %call
25; CHECK-LABEL: acos_test2
26; CHECK: call fast double @acos(double %conv)
27}
28
29define 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
33   ret float %conv1
34; CHECK-LABEL: acosh_test1
35; CHECK: call fast float @acoshf(float %f)
36}
37
38define double @acosh_test2(float %f)   {
39   %conv = fpext float %f to double
40   %call = call fast double @acosh(double %conv)
41   ret double %call
42; CHECK-LABEL: acosh_test2
43; CHECK: call fast double @acosh(double %conv)
44}
45
46define 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
50   ret float %conv1
51; CHECK-LABEL: asin_test1
52; CHECK: call fast float @asinf(float %f)
53}
54
55define double @asin_test2(float %f)   {
56   %conv = fpext float %f to double
57   %call = call fast double @asin(double %conv)
58   ret double %call
59; CHECK-LABEL: asin_test2
60; CHECK: call fast double @asin(double %conv)
61}
62
63define 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
67   ret float %conv1
68; CHECK-LABEL: asinh_test1
69; CHECK: call fast float @asinhf(float %f)
70}
71
72define double @asinh_test2(float %f)   {
73   %conv = fpext float %f to double
74   %call = call fast double @asinh(double %conv)
75   ret double %call
76; CHECK-LABEL: asinh_test2
77; CHECK: call fast double @asinh(double %conv)
78}
79
80define 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
84   ret float %conv1
85; CHECK-LABEL: atan_test1
86; CHECK: call fast float @atanf(float %f)
87}
88
89define double @atan_test2(float %f)   {
90   %conv = fpext float %f to double
91   %call = call fast double @atan(double %conv)
92   ret double %call
93; CHECK-LABEL: atan_test2
94; CHECK: call fast double @atan(double %conv)
95}
96
97define 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
101   ret float %conv1
102; CHECK-LABEL: atanh_test1
103; CHECK: call fast float @atanhf(float %f)
104}
105
106define double @atanh_test2(float %f)   {
107    %conv = fpext float %f to double
108    %call = call fast double @atanh(double %conv)
109    ret double %call
110; CHECK-LABEL: atanh_test2
111; CHECK: call fast double @atanh(double %conv)
112}
113
114define 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
118   ret float %conv1
119; CHECK-LABEL: cbrt_test1
120; CHECK: call fast float @cbrtf(float %f)
121}
122
123define double @cbrt_test2(float %f)   {
124   %conv = fpext float %f to double
125   %call = call fast  double @cbrt(double %conv)
126   ret double %call
127; CHECK-LABEL: cbrt_test2
128; CHECK: call fast double @cbrt(double %conv)
129}
130
131define 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
135   ret float %conv1
136; CHECK-LABEL: exp_test1
137; CHECK: call fast float @expf(float %f)
138}
139
140define double @exp_test2(float %f)   {
141   %conv = fpext float %f to double
142   %call = call fast double @exp(double %conv)
143   ret double %call
144; CHECK-LABEL: exp_test2
145; CHECK: call fast double @exp(double %conv)
146}
147
148define 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
152   ret float %conv1
153; CHECK-LABEL: expm1_test1
154; CHECK: call fast float @expm1f(float %f)
155}
156
157define double @expm1_test2(float %f)   {
158   %conv = fpext float %f to double
159   %call = call fast double @expm1(double %conv)
160   ret double %call
161; CHECK-LABEL: expm1_test2
162; CHECK: call fast double @expm1(double %conv)
163}
164
165; exp10f() doesn't exist for this triple, so it doesn't shrink.
166
167define 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
171   ret float %conv1
172; CHECK-LABEL: exp10_test1
173; CHECK: call fast double @exp10(double %conv)
174}
175
176define double @exp10_test2(float %f)   {
177   %conv = fpext float %f to double
178   %call = call fast double @exp10(double %conv)
179   ret double %call
180; CHECK-LABEL: exp10_test2
181; CHECK: call fast double @exp10(double %conv)
182}
183
184define 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
188   ret float %conv1
189; CHECK-LABEL: log_test1
190; CHECK: call fast float @logf(float %f)
191}
192
193define double @log_test2(float %f)   {
194   %conv = fpext float %f to double
195   %call = call fast double @log(double %conv)
196   ret double %call
197; CHECK-LABEL: log_test2
198; CHECK: call fast double @log(double %conv)
199}
200
201define 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
205   ret float %conv1
206; CHECK-LABEL: log10_test1
207; CHECK: call fast float @log10f(float %f)
208}
209
210define double @log10_test2(float %f) {
211   %conv = fpext float %f to double
212   %call = call fast double @log10(double %conv)
213   ret double %call
214; CHECK-LABEL: log10_test2
215; CHECK: call fast double @log10(double %conv)
216}
217
218define 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
222   ret float %conv1
223; CHECK-LABEL: log1p_test1
224; CHECK: call fast float @log1pf(float %f)
225}
226
227define double @log1p_test2(float %f)   {
228   %conv = fpext float %f to double
229   %call = call fast double @log1p(double %conv)
230   ret double %call
231; CHECK-LABEL: log1p_test2
232; CHECK: call fast double @log1p(double %conv)
233}
234
235define 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
239   ret float %conv1
240; CHECK-LABEL: log2_test1
241; CHECK: call fast float @log2f(float %f)
242}
243
244define double @log2_test2(float %f)   {
245   %conv = fpext float %f to double
246   %call = call fast double @log2(double %conv)
247   ret double %call
248; CHECK-LABEL: log2_test2
249; CHECK: call fast double @log2(double %conv)
250}
251
252define 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
256   ret float %conv1
257; CHECK-LABEL: logb_test1
258; CHECK: call fast float @logbf(float %f)
259}
260
261define double @logb_test2(float %f)   {
262   %conv = fpext float %f to double
263   %call = call fast double @logb(double %conv)
264   ret double %call
265; CHECK-LABEL: logb_test2
266; CHECK: call fast double @logb(double %conv)
267}
268
269define 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
273   ret float %conv1
274; CHECK-LABEL: sin_test1
275; CHECK: call fast float @sinf(float %f)
276}
277
278define double @sin_test2(float %f) {
279   %conv = fpext float %f to double
280   %call = call fast double @sin(double %conv)
281   ret double %call
282; CHECK-LABEL: sin_test2
283; CHECK: call fast double @sin(double %conv)
284}
285
286define 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
290   ret float %conv1
291; CHECK-LABEL: sqrt_test1
292; CHECK: call float @sqrtf(float %f)
293}
294
295define double @sqrt_test2(float %f) {
296   %conv = fpext float %f to double
297   %call = call double @sqrt(double %conv)
298   ret double %call
299; CHECK-LABEL: sqrt_test2
300; CHECK: call double @sqrt(double %conv)
301}
302
303define 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
307   ret float %conv1
308; CHECK-LABEL: sqrt_int_test1
309; CHECK: call float @llvm.sqrt.f32(float %f)
310}
311
312define double @sqrt_int_test2(float %f) {
313   %conv = fpext float %f to double
314   %call = call double @llvm.sqrt.f64(double %conv)
315   ret double %call
316; CHECK-LABEL: sqrt_int_test2
317; CHECK: call double @llvm.sqrt.f64(double %conv)
318}
319
320define 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
324   ret float %conv1
325; CHECK-LABEL: tan_test1
326; CHECK: call fast float @tanf(float %f)
327}
328
329define double @tan_test2(float %f) {
330   %conv = fpext float %f to double
331   %call = call fast double @tan(double %conv)
332   ret double %call
333; CHECK-LABEL: tan_test2
334; CHECK: call fast double @tan(double %conv)
335}
336define 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
340   ret float %conv1
341; CHECK-LABEL: tanh_test1
342; CHECK: call fast float @tanhf(float %f)
343}
344
345define double @tanh_test2(float %f) {
346   %conv = fpext float %f to double
347   %call = call fast double @tanh(double %conv)
348   ret double %call
349; CHECK-LABEL: tanh_test2
350; CHECK: call fast double @tanh(double %conv)
351}
352
353; 'arcp' on an fmax() is meaningless. This test just proves that
354; flags are propagated for shrunken *binary* double FP calls.
355define 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
360  ret float %f
361
362; CHECK-LABEL: max1(
363; CHECK-NEXT:  call arcp float @fmaxf(float %a, float %b)
364; CHECK-NEXT:  ret
365}
366
367; A function can have a name that matches a common libcall,
368; but with the wrong type(s). Let it be.
369
370define 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
375  ret float %f
376
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
383}
384
385declare fp128 @fmin(fp128, fp128) ; This is not the 'fmin' you're looking for.
386
387declare double @fmax(double, double)
388
389declare double @tanh(double)
390declare double @tan(double)
391
392; sqrt is a special case: the shrinking optimization
393; is valid even without unsafe-fp-math.
394declare double @sqrt(double)
395declare double @llvm.sqrt.f64(double)
396
397declare double @sin(double)
398declare double @log2(double)
399declare double @log1p(double)
400declare double @log10(double)
401declare double @log(double)
402declare double @logb(double)
403declare double @exp10(double)
404declare double @expm1(double)
405declare double @exp(double)
406declare double @cbrt(double)
407declare double @atanh(double)
408declare double @atan(double)
409declare double @acos(double)
410declare double @acosh(double)
411declare double @asin(double)
412declare double @asinh(double)
413
414