[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / double-float-shrink-1.ll
blob330e0abb36b85039a5757ef78837e020b4019cfd
1 ; RUN: opt < %s -instcombine -S -mtriple x86_64-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK,LINUX,ISC99
2 ; RUN: opt < %s -instcombine -S -mtriple x86_64-pc-win32          | FileCheck %s --check-prefixes=CHECK,ISC99
3 ; RUN: opt < %s -instcombine -S -mtriple x86_64-pc-windows-msvc16 | FileCheck %s --check-prefixes=CHECK,MS64,ISC89
4 ; RUN: opt < %s -instcombine -S -mtriple i386-pc-windows-msvc     | FileCheck %s --check-prefixes=CHECK,ISC99
5 ; RUN: opt < %s -instcombine -S -mtriple i686-pc-windows-msvc17   | FileCheck %s --check-prefixes=CHECK,MS32,ISC89
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
13 define 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:%.*]])
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
26 define 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]]
32   %conv = fpext float %f to double
33   %call = call fast double @acos(double %conv)
34   ret double %call
37 define 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:%.*]])
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
49 define 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]]
55   %conv = fpext float %f to double
56   %call = call fast double @acosh(double %conv)
57   ret double %call
60 define 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:%.*]])
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
73 define 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]]
79   %conv = fpext float %f to double
80   %call = call fast double @asin(double %conv)
81   ret double %call
84 define 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:%.*]])
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
96 define 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]]
102   %conv = fpext float %f to double
103   %call = call fast double @asinh(double %conv)
104   ret double %call
107 define 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:%.*]])
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
120 define 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]]
126   %conv = fpext float %f to double
127   %call = call fast double @atan(double %conv)
128   ret double %call
131 define 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:%.*]])
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
143 define 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]]
149   %conv = fpext float %f to double
150   %call = call fast double @atanh(double %conv)
151   ret double %call
154 define 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:%.*]])
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
166 define 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]]
172   %conv = fpext float %f to double
173   %call = call fast  double @cbrt(double %conv)
174   ret double %call
177 define 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:%.*]])
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
190 define 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]]
196   %conv = fpext float %f to double
197   %call = call fast double @exp(double %conv)
198   ret double %call
201 define 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:%.*]])
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
213 define 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]]
219   %conv = fpext float %f to double
220   %call = call fast double @expm1(double %conv)
221   ret double %call
224 ; exp10f() doesn't exist for this triple, so it doesn't shrink.
226 define 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]]
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
239 define 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]]
245   %conv = fpext float %f to double
246   %call = call fast double @exp10(double %conv)
247   ret double %call
250 define float @log_test1(float %f)   {
251 ; CHECK-LABEL: @log_test1(
252 ; LINUX-NEXT:    [[LOGF:%.*]] = call fast float @logf(float [[F:%.*]])
253 ; LINUX-NEXT:    ret float [[LOGF]]
254 ; MS32:          [[LOGF:%.*]] = call fast double @log(double [[F:%.*]])
255 ; MS64-NEXT:     [[LOGF:%.*]] = call fast float @logf(float [[F:%.*]])
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
263 define 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 @log(double [[CONV]])
267 ; CHECK-NEXT:    ret double [[CALL]]
269   %conv = fpext float %f to double
270   %call = call fast double @log(double %conv)
271   ret double %call
274 define float @log10_test1(float %f)   {
275 ; CHECK-LABEL: @log10_test1(
276 ; LINUX-NEXT:    [[LOG10F:%.*]] = call fast float @log10f(float [[F:%.*]])
277 ; LINUX-NEXT:    ret float [[LOG10F]]
278 ; MS32:          [[LOG10F:%.*]] = call fast double @log10(double [[F:%.*]])
279 ; MS64-NEXT:     [[LOG10F:%.*]] = call fast float @log10f(float [[F:%.*]])
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
287 define 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 @log10(double [[CONV]])
291 ; CHECK-NEXT:    ret double [[CALL]]
293   %conv = fpext float %f to double
294   %call = call fast double @log10(double %conv)
295   ret double %call
298 define 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:%.*]])
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
310 define 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]]
316   %conv = fpext float %f to double
317   %call = call fast double @log1p(double %conv)
318   ret double %call
321 define float @log2_test1(float %f)   {
322 ; CHECK-LABEL: @log2_test1(
323 ; ISC99-NEXT:    [[LOG2F:%.*]] = call fast float @log2f(float [[F:%.*]])
324 ; ISC99-NEXT:    ret float [[LOG2F]]
325 ; ISC89:         [[LOG2F:%.*]] = call fast double @log2(double [[F:%.*]])
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
333 define double @log2_test2(float %f)   {
334 ; CHECK-LABEL: @log2_test2(
335 ; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
336 ; CHECK-NEXT:    [[CALL:%.*]] = call fast double @log2(double [[CONV]])
337 ; CHECK-NEXT:    ret double [[CALL]]
339   %conv = fpext float %f to double
340   %call = call fast double @log2(double %conv)
341   ret double %call
344 define float @logb_test1(float %f)   {
345 ; CHECK-LABEL: @logb_test1(
346 ; LINUX-NEXT:    [[LOGBF:%.*]] = call fast float @logbf(float [[F:%.*]])
347 ; LINUX-NEXT:    ret float [[LOGBF]]
348 ; MS32:          [[POWF:%.*]] = call fast double @logb(double [[F:%.*]])
349 ; MS64-NEXT:     [[LOGBF:%.*]] = call fast float @logbf(float [[F:%.*]])
351   %conv = fpext float %f to double
352   %call = call fast double @logb(double %conv)
353   %conv1 = fptrunc double %call to float
354   ret float %conv1
357 define double @logb_test2(float %f)   {
358 ; CHECK-LABEL: @logb_test2(
359 ; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
360 ; CHECK-NEXT:    [[CALL:%.*]] = call fast double @logb(double [[CONV]])
361 ; CHECK-NEXT:    ret double [[CALL]]
363   %conv = fpext float %f to double
364   %call = call fast double @logb(double %conv)
365   ret double %call
368 define float @pow_test1(float %f, float %g)   {
369 ; CHECK-LABEL: @pow_test1(
370 ; LINUX-NEXT:    [[POWF:%.*]] = call fast float @powf(float %f, float %g)
371 ; LINUX-NEXT:    ret float [[POWF]]
372 ; MS32:          [[POWF:%.*]] = call fast double @pow(double %df, double %dg)
373 ; MS64-NEXT:     [[POWF:%.*]] = call fast float @powf(float %f, float %g)
375   %df = fpext float %f to double
376   %dg = fpext float %g to double
377   %call = call fast double @pow(double %df, double %dg)
378   %fr = fptrunc double %call to float
379   ret float %fr
382 define double @pow_test2(float %f, float %g) {
383 ; CHECK-LABEL: @pow_test2(
384 ; CHECK:         [[POW:%.*]] = call fast double @pow(double %df, double %dg)
385 ; CHECK-NEXT:    ret double [[POW]]
387   %df = fpext float %f to double
388   %dg = fpext float %g to double
389   %call = call fast double @pow(double %df, double %dg)
390   ret double %call
393 define float @sin_test1(float %f)   {
394 ; CHECK-LABEL: @sin_test1(
395 ; LINUX-NEXT:    [[SINF:%.*]] = call fast float @sinf(float [[F:%.*]])
396 ; LINUX-NEXT:    ret float [[SINF]]
397 ; MS32:          [[SINF:%.*]] = call fast double @sin(double [[F:%.*]])
398 ; MS64-NEXT:     [[SINF:%.*]] = call fast float @sinf(float [[F:%.*]])
400   %conv = fpext float %f to double
401   %call = call fast double @sin(double %conv)
402   %conv1 = fptrunc double %call to float
403   ret float %conv1
406 define double @sin_test2(float %f) {
407 ; CHECK-LABEL: @sin_test2(
408 ; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
409 ; CHECK-NEXT:    [[CALL:%.*]] = call fast double @sin(double [[CONV]])
410 ; CHECK-NEXT:    ret double [[CALL]]
412   %conv = fpext float %f to double
413   %call = call fast double @sin(double %conv)
414   ret double %call
417 define float @sqrt_test1(float %f) {
418 ; CHECK-LABEL: @sqrt_test1(
419 ; LINUX-NEXT:    [[SQRTF:%.*]] = call float @sqrtf(float [[F:%.*]])
420 ; LINUX-NEXT:    ret float [[SQRTF]]
421 ; MS32:          [[SQRTF:%.*]] = call double @sqrt(double [[F:%.*]])
422 ; MS64-NEXT:     [[SQRTF:%.*]] = call float @sqrtf(float [[F:%.*]])
424   %conv = fpext float %f to double
425   %call = call double @sqrt(double %conv)
426   %conv1 = fptrunc double %call to float
427   ret float %conv1
430 define double @sqrt_test2(float %f) {
431 ; CHECK-LABEL: @sqrt_test2(
432 ; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
433 ; CHECK-NEXT:    [[CALL:%.*]] = call double @sqrt(double [[CONV]])
434 ; CHECK-NEXT:    ret double [[CALL]]
436   %conv = fpext float %f to double
437   %call = call double @sqrt(double %conv)
438   ret double %call
441 define float @sqrt_int_test1(float %f) {
442 ; CHECK-LABEL: @sqrt_int_test1(
443 ; LINUX-NEXT:    [[TMP1:%.*]] = call float @llvm.sqrt.f32(float [[F:%.*]])
444 ; LINUX-NEXT:    ret float [[TMP1]]
445 ; MS32:          [[TMP1:%.*]] = call double @llvm.sqrt.f64(double [[F:%.*]])
446 ; MS64-NEXT:     [[TMP1:%.*]] = call float @llvm.sqrt.f32(float [[F:%.*]])
448   %conv = fpext float %f to double
449   %call = call double @llvm.sqrt.f64(double %conv)
450   %conv1 = fptrunc double %call to float
451   ret float %conv1
454 define double @sqrt_int_test2(float %f) {
455 ; CHECK-LABEL: @sqrt_int_test2(
456 ; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
457 ; CHECK-NEXT:    [[CALL:%.*]] = call double @llvm.sqrt.f64(double [[CONV]])
458 ; CHECK-NEXT:    ret double [[CALL]]
460   %conv = fpext float %f to double
461   %call = call double @llvm.sqrt.f64(double %conv)
462   ret double %call
465 define float @tan_test1(float %f) {
466 ; CHECK-LABEL: @tan_test1(
467 ; LINUX-NEXT:    [[TANF:%.*]] = call fast float @tanf(float [[F:%.*]])
468 ; LINUX-NEXT:    ret float [[TANF]]
469 ; MS32:          [[TANF:%.*]] = call fast double @tan(double [[F:%.*]])
470 ; MS64-NEXT:     [[TANF:%.*]] = call fast float @tanf(float [[F:%.*]])
472   %conv = fpext float %f to double
473   %call = call fast double @tan(double %conv)
474   %conv1 = fptrunc double %call to float
475   ret float %conv1
478 define double @tan_test2(float %f) {
479 ; CHECK-LABEL: @tan_test2(
480 ; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
481 ; CHECK-NEXT:    [[CALL:%.*]] = call fast double @tan(double [[CONV]])
482 ; CHECK-NEXT:    ret double [[CALL]]
484   %conv = fpext float %f to double
485   %call = call fast double @tan(double %conv)
486   ret double %call
488 define float @tanh_test1(float %f) {
489 ; CHECK-LABEL: @tanh_test1(
490 ; LINUX-NEXT:    [[TANHF:%.*]] = call fast float @tanhf(float [[F:%.*]])
491 ; LINUX-NEXT:    ret float [[TANHF]]
492 ; MS32:          [[TANHF:%.*]] = call fast double @tanh(double [[F:%.*]])
493 ; MS64-NEXT:     [[TANHF:%.*]] = call fast float @tanhf(float [[F:%.*]])
495   %conv = fpext float %f to double
496   %call = call fast double @tanh(double %conv)
497   %conv1 = fptrunc double %call to float
498   ret float %conv1
501 define double @tanh_test2(float %f) {
502 ; CHECK-LABEL: @tanh_test2(
503 ; CHECK-NEXT:    [[CONV:%.*]] = fpext float [[F:%.*]] to double
504 ; CHECK-NEXT:    [[CALL:%.*]] = call fast double @tanh(double [[CONV]])
505 ; CHECK-NEXT:    ret double [[CALL]]
507   %conv = fpext float %f to double
508   %call = call fast double @tanh(double %conv)
509   ret double %call
512 ; 'arcp' on an fmax() is meaningless. This test just proves that
513 ; flags are propagated for shrunken *binary* double FP calls.
514 define float @max1(float %a, float %b) {
515 ; CHECK-LABEL: @max1(
516 ; ISC99-NEXT:    [[FMAXF:%.*]] = call nsz arcp float @llvm.maxnum.f32(float [[A:%.*]], float [[B:%.*]])
517 ; ISC99-NEXT:    ret float [[FMAXF]]
518 ; ISC89:         [[FMAXF:%.*]] = call arcp double @fmax(double [[A:%.*]], double [[B:%.*]])
520   %c = fpext float %a to double
521   %d = fpext float %b to double
522   %e = call arcp double @fmax(double %c, double %d)
523   %f = fptrunc double %e to float
524   ret float %f
527 ; This is treated as libm 'fmin' - LLVM types do not necessarily
528 ; correspond to 'C' types, so this is not required to be "fminl".
530 define float @fake_fmin(float %a, float %b) {
531 ; CHECK-LABEL: @fake_fmin(
532 ; CHECK-NEXT:    [[C:%.*]] = fpext float [[A:%.*]] to fp128
533 ; CHECK-NEXT:    [[D:%.*]] = fpext float [[B:%.*]] to fp128
534 ; ISC99-NEXT:    [[E:%.*]] = call nsz fp128 @llvm.minnum.f128(fp128 [[C]], fp128 [[D]])
535 ; ISC89-NEXT:    [[E:%.*]] = call fp128 @fmin(fp128 [[C]], fp128 [[D]])
536 ; CHECK-NEXT:    [[F:%.*]] = fptrunc fp128 [[E]] to float
537 ; CHECK-NEXT:    ret float [[F]]
539   %c = fpext float %a to fp128
540   %d = fpext float %b to fp128
541   %e = call fp128 @fmin(fp128 %c, fp128 %d)
542   %f = fptrunc fp128 %e to float
543   ret float %f
546 declare fp128 @fmin(fp128, fp128)
548 declare double @fmax(double, double)
550 declare double @tanh(double)
551 declare double @tan(double)
553 ; sqrt is a special case: the shrinking optimization
554 ; is valid even without unsafe-fp-math.
555 declare double @sqrt(double)
556 declare double @llvm.sqrt.f64(double)
558 declare double @sin(double)
559 declare double @pow(double, double)
560 declare double @log2(double)
561 declare double @log1p(double)
562 declare double @log10(double)
563 declare double @log(double)
564 declare double @logb(double)
565 declare double @exp10(double)
566 declare double @expm1(double)
567 declare double @exp(double)
568 declare double @cbrt(double)
569 declare double @atanh(double)
570 declare double @atan(double)
571 declare double @acos(double)
572 declare double @acosh(double)
573 declare double @asin(double)
574 declare double @asinh(double)