xref: /llvm-project/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll (revision 5184d763c70bf0c64b309262a40d9528a7dc4a2f)
1; RUN: opt < %s -passes=instcombine -S -mtriple x86_64-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK,LINUX,ISC99
2; RUN: opt < %s -passes=instcombine -S -mtriple x86_64-pc-win32          | FileCheck %s --check-prefixes=CHECK,ISC99
3; RUN: opt < %s -passes=instcombine -S -mtriple x86_64-pc-windows-msvc16 | FileCheck %s --check-prefixes=CHECK,MS64,ISC89
4; RUN: opt < %s -passes=instcombine -S -mtriple i386-pc-windows-msvc     | FileCheck %s --check-prefixes=CHECK,ISC99
5; RUN: opt < %s -passes=instcombine -S -mtriple i686-pc-windows-msvc17   | FileCheck %s --check-prefixes=CHECK,MS32,ISC89
6
7; Check for and against shrinkage when using the
8; unsafe-fp-math function attribute on a math lib
9; function. This optimization may be overridden by
10; the -enable-double-float-shrink option.
11; PR17850: http://llvm.org/bugs/show_bug.cgi?id=17850
12
13define float @acos_test1(float %f)   {
14; CHECK-LABEL: @acos_test1(
15; LINUX-NEXT:    [[ACOSF:%.*]] = call fast float @acosf(float [[F:%.*]])
16; LINUX-NEXT:    ret float [[ACOSF]]
17; MS32:          [[ACOSF:%.*]] = call fast double @acos(double [[F:%.*]])
18; MS64-NEXT:     [[ACOSF:%.*]] = call fast float @acosf(float [[F:%.*]])
19;
20  %conv = fpext float %f to double
21  %call = call fast double @acos(double %conv)
22  %conv1 = fptrunc double %call to float
23  ret float %conv1
24}
25
26define double @acos_test2(float %f)   {
27; CHECK-LABEL: @acos_test2(
28; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
29; CHECK-NEXT:    [[CALL:%.*]] = call fast double @acos(double [[CONV]])
30; CHECK-NEXT:    ret double [[CALL]]
31;
32  %conv = fpext float %f to double
33  %call = call fast double @acos(double %conv)
34  ret double %call
35}
36
37define float @acosh_test1(float %f)   {
38; CHECK-LABEL: @acosh_test1(
39; ISC99-NEXT:    [[ACOSHF:%.*]] = call fast float @acoshf(float [[F:%.*]])
40; ISC99-NEXT:    ret float [[ACOSHF]]
41; ISC89:         [[ACOSHF:%.*]] = call fast double @acosh(double [[F:%.*]])
42;
43  %conv = fpext float %f to double
44  %call = call fast double @acosh(double %conv)
45  %conv1 = fptrunc double %call to float
46  ret float %conv1
47}
48
49define double @acosh_test2(float %f)   {
50; CHECK-LABEL: @acosh_test2(
51; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
52; CHECK-NEXT:    [[CALL:%.*]] = call fast double @acosh(double [[CONV]])
53; CHECK-NEXT:    ret double [[CALL]]
54;
55  %conv = fpext float %f to double
56  %call = call fast double @acosh(double %conv)
57  ret double %call
58}
59
60define float @asin_test1(float %f)   {
61; CHECK-LABEL: @asin_test1(
62; LINUX-NEXT:    [[ASINF:%.*]] = call fast float @asinf(float [[F:%.*]])
63; LINUX-NEXT:    ret float [[ASINF]]
64; MS32:          [[ASINF:%.*]] = call fast double @asin(double [[F:%.*]])
65; MS64-NEXT:     [[ASINF:%.*]] = call fast float @asinf(float [[F:%.*]])
66;
67  %conv = fpext float %f to double
68  %call = call fast double @asin(double %conv)
69  %conv1 = fptrunc double %call to float
70  ret float %conv1
71}
72
73define double @asin_test2(float %f)   {
74; CHECK-LABEL: @asin_test2(
75; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
76; CHECK-NEXT:    [[CALL:%.*]] = call fast double @asin(double [[CONV]])
77; CHECK-NEXT:    ret double [[CALL]]
78;
79  %conv = fpext float %f to double
80  %call = call fast double @asin(double %conv)
81  ret double %call
82}
83
84define float @asinh_test1(float %f)   {
85; CHECK-LABEL: @asinh_test1(
86; ISC99-NEXT:   [[ASINHF:%.*]] = call fast float @asinhf(float [[F:%.*]])
87; ISC99-NEXT:   ret float [[ASINHF]]
88; ISC89:        [[ASINHF:%.*]] = call fast double @asinh(double [[F:%.*]])
89;
90  %conv = fpext float %f to double
91  %call = call fast double @asinh(double %conv)
92  %conv1 = fptrunc double %call to float
93  ret float %conv1
94}
95
96define double @asinh_test2(float %f)   {
97; CHECK-LABEL: @asinh_test2(
98; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
99; CHECK-NEXT:    [[CALL:%.*]] = call fast double @asinh(double [[CONV]])
100; CHECK-NEXT:    ret double [[CALL]]
101;
102  %conv = fpext float %f to double
103  %call = call fast double @asinh(double %conv)
104  ret double %call
105}
106
107define float @atan_test1(float %f)   {
108; CHECK-LABEL: @atan_test1(
109; LINUX-NEXT:    [[ATANF:%.*]] = call fast float @atanf(float [[F:%.*]])
110; LINUX-NEXT:    ret float [[ATANF]]
111; MS32:          [[ATANF:%.*]] = call fast double @atan(double [[F:%.*]])
112; MS64-NEXT:     [[ATANF:%.*]] = call fast float @atanf(float [[F:%.*]])
113;
114  %conv = fpext float %f to double
115  %call = call fast double @atan(double %conv)
116  %conv1 = fptrunc double %call to float
117  ret float %conv1
118}
119
120define double @atan_test2(float %f)   {
121; CHECK-LABEL: @atan_test2(
122; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
123; CHECK-NEXT:    [[CALL:%.*]] = call fast double @atan(double [[CONV]])
124; CHECK-NEXT:    ret double [[CALL]]
125;
126  %conv = fpext float %f to double
127  %call = call fast double @atan(double %conv)
128  ret double %call
129}
130
131define float @atanh_test1(float %f)   {
132; CHECK-LABEL: @atanh_test1(
133; ISC99-NEXT:    [[ATANHF:%.*]] = call fast float @atanhf(float [[F:%.*]])
134; ISC99-NEXT:    ret float [[ATANHF]]
135; ISC89:         [[ATANHF:%.*]] = call fast double @atanh(double [[F:%.*]])
136;
137  %conv = fpext float %f to double
138  %call = call fast double @atanh(double %conv)
139  %conv1 = fptrunc double %call to float
140  ret float %conv1
141}
142
143define double @atanh_test2(float %f)   {
144; CHECK-LABEL: @atanh_test2(
145; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
146; CHECK-NEXT:    [[CALL:%.*]] = call fast double @atanh(double [[CONV]])
147; CHECK-NEXT:    ret double [[CALL]]
148;
149  %conv = fpext float %f to double
150  %call = call fast double @atanh(double %conv)
151  ret double %call
152}
153
154define float @cbrt_test1(float %f)   {
155; CHECK-LABEL: @cbrt_test1(
156; ISC99-NEXT:    [[CBRTF:%.*]] = call fast float @cbrtf(float [[F:%.*]])
157; ISC99-NEXT:    ret float [[CBRTF]]
158; ISC89:         [[CBRTF:%.*]] = call fast double @cbrt(double [[F:%.*]])
159;
160  %conv = fpext float %f to double
161  %call = call fast double @cbrt(double %conv)
162  %conv1 = fptrunc double %call to float
163  ret float %conv1
164}
165
166define double @cbrt_test2(float %f)   {
167; CHECK-LABEL: @cbrt_test2(
168; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
169; CHECK-NEXT:    [[CALL:%.*]] = call fast double @cbrt(double [[CONV]])
170; CHECK-NEXT:    ret double [[CALL]]
171;
172  %conv = fpext float %f to double
173  %call = call fast  double @cbrt(double %conv)
174  ret double %call
175}
176
177define float @exp_test1(float %f)   {
178; CHECK-LABEL: @exp_test1(
179; LINUX-NEXT:    [[EXPF:%.*]] = call fast float @expf(float [[F:%.*]])
180; LINUX-NEXT:    ret float [[EXPF]]
181; MS32:          [[EXPF:%.*]] = call fast double @exp(double [[F:%.*]])
182; MS64-NEXT:     [[EXPF:%.*]] = call fast float @expf(float [[F:%.*]])
183;
184  %conv = fpext float %f to double
185  %call = call fast double @exp(double %conv)
186  %conv1 = fptrunc double %call to float
187  ret float %conv1
188}
189
190define double @exp_test2(float %f)   {
191; CHECK-LABEL: @exp_test2(
192; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
193; CHECK-NEXT:    [[CALL:%.*]] = call fast double @exp(double [[CONV]])
194; CHECK-NEXT:    ret double [[CALL]]
195;
196  %conv = fpext float %f to double
197  %call = call fast double @exp(double %conv)
198  ret double %call
199}
200
201define float @expm1_test1(float %f)   {
202; CHECK-LABEL: @expm1_test1(
203; ISC99-NEXT:    [[EXPM1F:%.*]] = call fast float @expm1f(float [[F:%.*]])
204; ISC99-NEXT:    ret float [[EXPM1F]]
205; ISC89:         [[EXPM1F:%.*]] = call fast double @expm1(double [[F:%.*]])
206;
207  %conv = fpext float %f to double
208  %call = call fast double @expm1(double %conv)
209  %conv1 = fptrunc double %call to float
210  ret float %conv1
211}
212
213define double @expm1_test2(float %f)   {
214; CHECK-LABEL: @expm1_test2(
215; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
216; CHECK-NEXT:    [[CALL:%.*]] = call fast double @expm1(double [[CONV]])
217; CHECK-NEXT:    ret double [[CALL]]
218;
219  %conv = fpext float %f to double
220  %call = call fast double @expm1(double %conv)
221  ret double %call
222}
223
224; exp10f() doesn't exist for this triple, so it doesn't shrink.
225
226define float @exp10_test1(float %f)   {
227; CHECK-LABEL: @exp10_test1(
228; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
229; CHECK-NEXT:    [[CALL:%.*]] = call fast double @exp10(double [[CONV]])
230; CHECK-NEXT:    [[CONV1:%.*]] = fptrunc double [[CALL]] to float
231; CHECK-NEXT:    ret float [[CONV1]]
232;
233  %conv = fpext float %f to double
234  %call = call fast double @exp10(double %conv)
235  %conv1 = fptrunc double %call to float
236  ret float %conv1
237}
238
239define double @exp10_test2(float %f)   {
240; CHECK-LABEL: @exp10_test2(
241; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
242; CHECK-NEXT:    [[CALL:%.*]] = call fast double @exp10(double [[CONV]])
243; CHECK-NEXT:    ret double [[CALL]]
244;
245  %conv = fpext float %f to double
246  %call = call fast double @exp10(double %conv)
247  ret double %call
248}
249
250define float @log_test1(float %f)   {
251; CHECK-LABEL: @log_test1(
252; LINUX-NEXT:    [[LOGF:%.*]] = call fast float @llvm.log.f32(float [[F:%.*]])
253; LINUX-NEXT:    ret float [[LOGF]]
254; MS32:          [[LOGF:%.*]] = call fast double @llvm.log.f64(double [[F:%.*]])
255; MS64-NEXT:     [[LOGF:%.*]] = call fast float @llvm.log.f32(float [[F:%.*]])
256;
257  %conv = fpext float %f to double
258  %call = call fast double @log(double %conv)
259  %conv1 = fptrunc double %call to float
260  ret float %conv1
261}
262
263define double @log_test2(float %f)   {
264; CHECK-LABEL: @log_test2(
265; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
266; CHECK-NEXT:    [[CALL:%.*]] = call fast double @llvm.log.f64(double [[CONV]])
267; CHECK-NEXT:    ret double [[CALL]]
268;
269  %conv = fpext float %f to double
270  %call = call fast double @log(double %conv)
271  ret double %call
272}
273
274define float @log10_test1(float %f)   {
275; CHECK-LABEL: @log10_test1(
276; LINUX-NEXT:    [[LOG10F:%.*]] = call fast float @llvm.log10.f32(float [[F:%.*]])
277; LINUX-NEXT:    ret float [[LOG10F]]
278; MS32:          [[LOG10F:%.*]] = call fast double @llvm.log10.f64(double [[F:%.*]])
279; MS64-NEXT:     [[LOG10F:%.*]] = call fast float @llvm.log10.f32(float [[F:%.*]])
280;
281  %conv = fpext float %f to double
282  %call = call fast double @log10(double %conv)
283  %conv1 = fptrunc double %call to float
284  ret float %conv1
285}
286
287define double @log10_test2(float %f) {
288; CHECK-LABEL: @log10_test2(
289; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
290; CHECK-NEXT:    [[CALL:%.*]] = call fast double @llvm.log10.f64(double [[CONV]])
291; CHECK-NEXT:    ret double [[CALL]]
292;
293  %conv = fpext float %f to double
294  %call = call fast double @log10(double %conv)
295  ret double %call
296}
297
298define float @log1p_test1(float %f)   {
299; CHECK-LABEL: @log1p_test1(
300; ISC99-NEXT:    [[LOG1PF:%.*]] = call fast float @log1pf(float [[F:%.*]])
301; ISC99-NEXT:    ret float [[LOG1PF]]
302; ISC89:         [[LOG1PF:%.*]] = call fast double @log1p(double [[F:%.*]])
303;
304  %conv = fpext float %f to double
305  %call = call fast double @log1p(double %conv)
306  %conv1 = fptrunc double %call to float
307  ret float %conv1
308}
309
310define double @log1p_test2(float %f)   {
311; CHECK-LABEL: @log1p_test2(
312; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
313; CHECK-NEXT:    [[CALL:%.*]] = call fast double @log1p(double [[CONV]])
314; CHECK-NEXT:    ret double [[CALL]]
315;
316  %conv = fpext float %f to double
317  %call = call fast double @log1p(double %conv)
318  ret double %call
319}
320
321define float @log2_test1(float %f)   {
322; CHECK-LABEL: @log2_test1(
323; ISC99-NEXT:    [[LOG2F:%.*]] = call fast float @llvm.log2.f32(float [[F:%.*]])
324; ISC99-NEXT:    ret float [[LOG2F]]
325; ISC89:         [[LOG2F:%.*]] = call fast double @log2(double [[F:%.*]])
326;
327  %conv = fpext float %f to double
328  %call = call fast double @log2(double %conv)
329  %conv1 = fptrunc double %call to float
330  ret float %conv1
331}
332
333define double @log2_test2(float %f)   {
334; CHECK-LABEL: @log2_test2(
335; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
336; ISC99-NEXT:    [[CALL:%.*]] = call fast double @llvm.log2.f64(double [[CONV]])
337; ISC89-NEXT:    [[LOG2F:%.*]] = call fast double @log2(double [[F:%.*]])
338; CHECK-NEXT:    ret double [[CALL]]
339;
340  %conv = fpext float %f to double
341  %call = call fast double @log2(double %conv)
342  ret double %call
343}
344
345define float @logb_test1(float %f)   {
346; CHECK-LABEL: @logb_test1(
347; LINUX-NEXT:    [[LOGBF:%.*]] = call fast float @logbf(float [[F:%.*]])
348; LINUX-NEXT:    ret float [[LOGBF]]
349; MS32:          [[POWF:%.*]] = call fast double @logb(double [[F:%.*]])
350; MS64-NEXT:     [[LOGBF:%.*]] = call fast float @_logbf(float [[F:%.*]])
351;
352  %conv = fpext float %f to double
353  %call = call fast double @logb(double %conv)
354  %conv1 = fptrunc double %call to float
355  ret float %conv1
356}
357
358define double @logb_test2(float %f)   {
359; CHECK-LABEL: @logb_test2(
360; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
361; CHECK-NEXT:    [[CALL:%.*]] = call fast double @logb(double [[CONV]])
362; CHECK-NEXT:    ret double [[CALL]]
363;
364  %conv = fpext float %f to double
365  %call = call fast double @logb(double %conv)
366  ret double %call
367}
368
369define float @pow_test1(float %f, float %g)   {
370; CHECK-LABEL: @pow_test1(
371; LINUX-NEXT:    [[POWF:%.*]] = call fast float @powf(float %f, float %g)
372; LINUX-NEXT:    ret float [[POWF]]
373; MS32:          [[POWF:%.*]] = call fast double @pow(double %df, double %dg)
374; MS64-NEXT:     [[POWF:%.*]] = call fast float @powf(float %f, float %g)
375;
376  %df = fpext float %f to double
377  %dg = fpext float %g to double
378  %call = call fast double @pow(double %df, double %dg)
379  %fr = fptrunc double %call to float
380  ret float %fr
381}
382
383define double @pow_test2(float %f, float %g) {
384; CHECK-LABEL: @pow_test2(
385; CHECK:         [[POW:%.*]] = call fast double @pow(double %df, double %dg)
386; CHECK-NEXT:    ret double [[POW]]
387;
388  %df = fpext float %f to double
389  %dg = fpext float %g to double
390  %call = call fast double @pow(double %df, double %dg)
391  ret double %call
392}
393
394define float @sin_test1(float %f)   {
395; CHECK-LABEL: @sin_test1(
396; LINUX-NEXT:    [[SINF:%.*]] = call fast float @sinf(float [[F:%.*]])
397; LINUX-NEXT:    ret float [[SINF]]
398; MS32:          [[SINF:%.*]] = call fast double @sin(double [[F:%.*]])
399; MS64-NEXT:     [[SINF:%.*]] = call fast float @sinf(float [[F:%.*]])
400;
401  %conv = fpext float %f to double
402  %call = call fast double @sin(double %conv)
403  %conv1 = fptrunc double %call to float
404  ret float %conv1
405}
406
407define double @sin_test2(float %f) {
408; CHECK-LABEL: @sin_test2(
409; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
410; CHECK-NEXT:    [[CALL:%.*]] = call fast double @sin(double [[CONV]])
411; CHECK-NEXT:    ret double [[CALL]]
412;
413  %conv = fpext float %f to double
414  %call = call fast double @sin(double %conv)
415  ret double %call
416}
417
418define float @sqrt_test1(float %f) {
419; CHECK-LABEL: @sqrt_test1(
420; LINUX-NEXT:    [[SQRTF:%.*]] = call float @sqrtf(float [[F:%.*]])
421; LINUX-NEXT:    ret float [[SQRTF]]
422; MS32:          [[SQRTF:%.*]] = call double @sqrt(double [[F:%.*]])
423; MS64-NEXT:     [[SQRTF:%.*]] = call float @sqrtf(float [[F:%.*]])
424;
425  %conv = fpext float %f to double
426  %call = call double @sqrt(double %conv)
427  %conv1 = fptrunc double %call to float
428  ret float %conv1
429}
430
431define double @sqrt_test2(float %f) {
432; CHECK-LABEL: @sqrt_test2(
433; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
434; CHECK-NEXT:    [[CALL:%.*]] = call double @sqrt(double [[CONV]])
435; CHECK-NEXT:    ret double [[CALL]]
436;
437  %conv = fpext float %f to double
438  %call = call double @sqrt(double %conv)
439  ret double %call
440}
441
442define float @sqrt_int_test1(float %f) {
443; CHECK-LABEL: @sqrt_int_test1(
444; LINUX-NEXT:    [[TMP1:%.*]] = call float @llvm.sqrt.f32(float [[F:%.*]])
445; LINUX-NEXT:    ret float [[TMP1]]
446; MS32:          [[TMP1:%.*]] = call double @llvm.sqrt.f64(double [[F:%.*]])
447; MS64-NEXT:     [[TMP1:%.*]] = call float @llvm.sqrt.f32(float [[F:%.*]])
448;
449  %conv = fpext float %f to double
450  %call = call double @llvm.sqrt.f64(double %conv)
451  %conv1 = fptrunc double %call to float
452  ret float %conv1
453}
454
455define double @sqrt_int_test2(float %f) {
456; CHECK-LABEL: @sqrt_int_test2(
457; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
458; CHECK-NEXT:    [[CALL:%.*]] = call double @llvm.sqrt.f64(double [[CONV]])
459; CHECK-NEXT:    ret double [[CALL]]
460;
461  %conv = fpext float %f to double
462  %call = call double @llvm.sqrt.f64(double %conv)
463  ret double %call
464}
465
466define float @tan_test1(float %f) {
467; CHECK-LABEL: @tan_test1(
468; LINUX-NEXT:    [[TANF:%.*]] = call fast float @tanf(float [[F:%.*]])
469; LINUX-NEXT:    ret float [[TANF]]
470; MS32:          [[TANF:%.*]] = call fast double @tan(double [[F:%.*]])
471; MS64-NEXT:     [[TANF:%.*]] = call fast float @tanf(float [[F:%.*]])
472;
473  %conv = fpext float %f to double
474  %call = call fast double @tan(double %conv)
475  %conv1 = fptrunc double %call to float
476  ret float %conv1
477}
478
479define double @tan_test2(float %f) {
480; CHECK-LABEL: @tan_test2(
481; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
482; CHECK-NEXT:    [[CALL:%.*]] = call fast double @tan(double [[CONV]])
483; CHECK-NEXT:    ret double [[CALL]]
484;
485  %conv = fpext float %f to double
486  %call = call fast double @tan(double %conv)
487  ret double %call
488}
489define float @tanh_test1(float %f) {
490; CHECK-LABEL: @tanh_test1(
491; LINUX-NEXT:    [[TANHF:%.*]] = call fast float @tanhf(float [[F:%.*]])
492; LINUX-NEXT:    ret float [[TANHF]]
493; MS32:          [[TANHF:%.*]] = call fast double @tanh(double [[F:%.*]])
494; MS64-NEXT:     [[TANHF:%.*]] = call fast float @tanhf(float [[F:%.*]])
495;
496  %conv = fpext float %f to double
497  %call = call fast double @tanh(double %conv)
498  %conv1 = fptrunc double %call to float
499  ret float %conv1
500}
501
502define double @tanh_test2(float %f) {
503; CHECK-LABEL: @tanh_test2(
504; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
505; CHECK-NEXT:    [[CALL:%.*]] = call fast double @tanh(double [[CONV]])
506; CHECK-NEXT:    ret double [[CALL]]
507;
508  %conv = fpext float %f to double
509  %call = call fast double @tanh(double %conv)
510  ret double %call
511}
512
513; 'arcp' on an fmax() is meaningless. This test just proves that
514; flags are propagated for shrunken *binary* double FP calls.
515define float @max1(float %a, float %b) {
516; CHECK-LABEL: @max1(
517; ISC99-NEXT:    [[FMAXF:%.*]] = call nsz arcp float @llvm.maxnum.f32(float [[A:%.*]], float [[B:%.*]])
518; ISC99-NEXT:    ret float [[FMAXF]]
519; ISC89:         [[FMAXF:%.*]] = call arcp double @fmax(double [[A:%.*]], double [[B:%.*]])
520;
521  %c = fpext float %a to double
522  %d = fpext float %b to double
523  %e = call arcp double @fmax(double %c, double %d)
524  %f = fptrunc double %e to float
525  ret float %f
526}
527
528; This is treated as libm 'fmin' - LLVM types do not necessarily
529; correspond to 'C' types, so this is not required to be "fminl".
530
531define float @fake_fmin(float %a, float %b) {
532; CHECK-LABEL: @fake_fmin(
533; ISC99-NEXT:    [[MIN:%.*]] = call nsz float @llvm.minnum.f32(float %a, float %b)
534; ISC99-NEXT:    ret float [[MIN]]
535
536; ISC89-NEXT:    [[C:%.*]] = fpext float [[A:%.*]] to fp128
537; ISC89-NEXT:    [[D:%.*]] = fpext float [[B:%.*]] to fp128
538; ISC89-NEXT:    [[E:%.*]] = call fp128 @fmin(fp128 [[C]], fp128 [[D]])
539; ISC89-NEXT:    [[F:%.*]] = fptrunc fp128 [[E]] to float
540; ISC89-NEXT:    ret float [[F]]
541;
542  %c = fpext float %a to fp128
543  %d = fpext float %b to fp128
544  %e = call fp128 @fmin(fp128 %c, fp128 %d)
545  %f = fptrunc fp128 %e to float
546  ret float %f
547}
548
549declare fp128 @fmin(fp128, fp128)
550
551declare double @fmax(double, double)
552
553declare double @tanh(double)
554declare double @tan(double)
555
556; sqrt is a special case: the shrinking optimization
557; is valid even without unsafe-fp-math.
558declare double @sqrt(double)
559declare double @llvm.sqrt.f64(double)
560
561declare double @sin(double)
562declare double @pow(double, double)
563declare double @log2(double)
564declare double @log1p(double)
565declare double @log10(double)
566declare double @log(double)
567declare double @logb(double)
568declare double @exp10(double)
569declare double @expm1(double)
570declare double @exp(double)
571declare double @cbrt(double)
572declare double @atanh(double)
573declare double @atan(double)
574declare double @acos(double)
575declare double @acosh(double)
576declare double @asin(double)
577declare double @asinh(double)
578
579