llvm.org GIT mirror llvm / 0997635
[ConstantFolding] Add folding for various math '__<func>_finite' routines generated from -ffast-math Patch by Chris Chrulski Differential Revision: https://reviews.llvm.org/D31788 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302956 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Kaylor 3 years ago
2 changed file(s) with 152 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
14371437 Name == "sinf" || Name == "sinhf" || Name == "sqrtf";
14381438 case 't':
14391439 return Name == "tan" || Name == "tanh" || Name == "tanf" || Name == "tanhf";
1440 case '_':
1441
1442 // Check for various function names that get used for the math functions
1443 // when the header files are preprocessed with the macro
1444 // __FINITE_MATH_ONLY__ enabled.
1445 // The '12' here is the length of the shortest name that can match.
1446 // We need to check the size before looking at Name[1] and Name[2]
1447 // so we may as well check a limit that will eliminate mismatches.
1448 if (Name.size() < 12 || Name[1] != '_')
1449 return false;
1450 switch (Name[2]) {
1451 default:
1452 return false;
1453 case 'a':
1454 return Name == "__acos_finite" || Name == "__acosf_finite" ||
1455 Name == "__asin_finite" || Name == "__asinf_finite" ||
1456 Name == "__atan2_finite" || Name == "__atan2f_finite";
1457 case 'c':
1458 return Name == "__cosh_finite" || Name == "__coshf_finite";
1459 case 'e':
1460 return Name == "__exp_finite" || Name == "__expf_finite" ||
1461 Name == "__exp2_finite" || Name == "__exp2f_finite";
1462 case 'l':
1463 return Name == "__log_finite" || Name == "__logf_finite" ||
1464 Name == "__log10_finite" || Name == "__log10f_finite";
1465 case 'p':
1466 return Name == "__pow_finite" || Name == "__powf_finite";
1467 case 's':
1468 return Name == "__sinh_finite" || Name == "__sinhf_finite";
1469 }
14401470 }
14411471 }
14421472
16361666 if (!TLI)
16371667 return nullptr;
16381668
1639 switch (Name[0]) {
1669 char NameKeyChar = Name[0];
1670 if (Name[0] == '_' && Name.size() > 2 && Name[1] == '_')
1671 NameKeyChar = Name[2];
1672
1673 switch (NameKeyChar) {
16401674 case 'a':
16411675 if ((Name == "acos" && TLI->has(LibFunc_acos)) ||
1642 (Name == "acosf" && TLI->has(LibFunc_acosf)))
1676 (Name == "acosf" && TLI->has(LibFunc_acosf)) ||
1677 (Name == "__acos_finite" && TLI->has(LibFunc_acos_finite)) ||
1678 (Name == "__acosf_finite" && TLI->has(LibFunc_acosf_finite)))
16431679 return ConstantFoldFP(acos, V, Ty);
16441680 else if ((Name == "asin" && TLI->has(LibFunc_asin)) ||
1645 (Name == "asinf" && TLI->has(LibFunc_asinf)))
1681 (Name == "asinf" && TLI->has(LibFunc_asinf)) ||
1682 (Name == "__asin_finite" && TLI->has(LibFunc_asin_finite)) ||
1683 (Name == "__asinf_finite" && TLI->has(LibFunc_asinf_finite)))
16461684 return ConstantFoldFP(asin, V, Ty);
16471685 else if ((Name == "atan" && TLI->has(LibFunc_atan)) ||
16481686 (Name == "atanf" && TLI->has(LibFunc_atanf)))
16561694 (Name == "cosf" && TLI->has(LibFunc_cosf)))
16571695 return ConstantFoldFP(cos, V, Ty);
16581696 else if ((Name == "cosh" && TLI->has(LibFunc_cosh)) ||
1659 (Name == "coshf" && TLI->has(LibFunc_coshf)))
1697 (Name == "coshf" && TLI->has(LibFunc_coshf)) ||
1698 (Name == "__cosh_finite" && TLI->has(LibFunc_cosh_finite)) ||
1699 (Name == "__coshf_finite" && TLI->has(LibFunc_coshf_finite)))
16601700 return ConstantFoldFP(cosh, V, Ty);
16611701 break;
16621702 case 'e':
16631703 if ((Name == "exp" && TLI->has(LibFunc_exp)) ||
1664 (Name == "expf" && TLI->has(LibFunc_expf)))
1704 (Name == "expf" && TLI->has(LibFunc_expf)) ||
1705 (Name == "__exp_finite" && TLI->has(LibFunc_exp_finite)) ||
1706 (Name == "__expf_finite" && TLI->has(LibFunc_expf_finite)))
16651707 return ConstantFoldFP(exp, V, Ty);
16661708 if ((Name == "exp2" && TLI->has(LibFunc_exp2)) ||
1667 (Name == "exp2f" && TLI->has(LibFunc_exp2f)))
1709 (Name == "exp2f" && TLI->has(LibFunc_exp2f)) ||
1710 (Name == "__exp2_finite" && TLI->has(LibFunc_exp2_finite)) ||
1711 (Name == "__exp2f_finite" && TLI->has(LibFunc_exp2f_finite)))
16681712 // Constant fold exp2(x) as pow(2,x) in case the host doesn't have a
16691713 // C99 library.
16701714 return ConstantFoldBinaryFP(pow, 2.0, V, Ty);
16791723 break;
16801724 case 'l':
16811725 if ((Name == "log" && V > 0 && TLI->has(LibFunc_log)) ||
1682 (Name == "logf" && V > 0 && TLI->has(LibFunc_logf)))
1726 (Name == "logf" && V > 0 && TLI->has(LibFunc_logf)) ||
1727 (Name == "__log_finite" && V > 0 &&
1728 TLI->has(LibFunc_log_finite)) ||
1729 (Name == "__logf_finite" && V > 0 &&
1730 TLI->has(LibFunc_logf_finite)))
16831731 return ConstantFoldFP(log, V, Ty);
16841732 else if ((Name == "log10" && V > 0 && TLI->has(LibFunc_log10)) ||
1685 (Name == "log10f" && V > 0 && TLI->has(LibFunc_log10f)))
1733 (Name == "log10f" && V > 0 && TLI->has(LibFunc_log10f)) ||
1734 (Name == "__log10_finite" && V > 0 &&
1735 TLI->has(LibFunc_log10_finite)) ||
1736 (Name == "__log10f_finite" && V > 0 &&
1737 TLI->has(LibFunc_log10f_finite)))
16861738 return ConstantFoldFP(log10, V, Ty);
16871739 break;
16881740 case 'r':
16941746 (Name == "sinf" && TLI->has(LibFunc_sinf)))
16951747 return ConstantFoldFP(sin, V, Ty);
16961748 else if ((Name == "sinh" && TLI->has(LibFunc_sinh)) ||
1697 (Name == "sinhf" && TLI->has(LibFunc_sinhf)))
1749 (Name == "sinhf" && TLI->has(LibFunc_sinhf)) ||
1750 (Name == "__sinh_finite" && TLI->has(LibFunc_sinh_finite)) ||
1751 (Name == "__sinhf_finite" && TLI->has(LibFunc_sinhf_finite)))
16981752 return ConstantFoldFP(sinh, V, Ty);
16991753 else if ((Name == "sqrt" && V >= 0 && TLI->has(LibFunc_sqrt)) ||
17001754 (Name == "sqrtf" && V >= 0 && TLI->has(LibFunc_sqrtf)))
18121866 if (!TLI)
18131867 return nullptr;
18141868 if ((Name == "pow" && TLI->has(LibFunc_pow)) ||
1815 (Name == "powf" && TLI->has(LibFunc_powf)))
1869 (Name == "powf" && TLI->has(LibFunc_powf)) ||
1870 (Name == "__pow_finite" && TLI->has(LibFunc_pow_finite)) ||
1871 (Name == "__powf_finite" && TLI->has(LibFunc_powf_finite)))
18161872 return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);
18171873 if ((Name == "fmod" && TLI->has(LibFunc_fmod)) ||
18181874 (Name == "fmodf" && TLI->has(LibFunc_fmodf)))
18191875 return ConstantFoldBinaryFP(fmod, Op1V, Op2V, Ty);
18201876 if ((Name == "atan2" && TLI->has(LibFunc_atan2)) ||
1821 (Name == "atan2f" && TLI->has(LibFunc_atan2f)))
1877 (Name == "atan2f" && TLI->has(LibFunc_atan2f)) ||
1878 (Name == "__atan2_finite" && TLI->has(LibFunc_atan2_finite)) ||
1879 (Name == "__atan2f_finite" && TLI->has(LibFunc_atan2f_finite)))
18221880 return ConstantFoldBinaryFP(atan2, Op1V, Op2V, Ty);
18231881 } else if (auto *Op2C = dyn_cast(Operands[1])) {
18241882 if (IntrinsicID == Intrinsic::powi && Ty->isHalfTy())
0 ; RUN: opt < %s -constprop -S | FileCheck %s
1
2 ; Test to verify constant folding can occur when math
3 ; routines are mapped to the ___finite versions
4 ; of functions due to __FINITE_MATH_ONLY__ being
5 ; enabled on headers. All calls should constant
6 ; fold away in this test.
7
8 declare double @__acos_finite(double) #0
9 declare float @__acosf_finite(float) #0
10 declare double @__asin_finite(double) #0
11 declare float @__asinf_finite(float) #0
12 declare double @__atan2_finite(double, double) #0
13 declare float @__atan2f_finite(float, float) #0
14 declare double @__cosh_finite(double) #0
15 declare float @__coshf_finite(float) #0
16 declare double @__exp2_finite(double) #0
17 declare float @__exp2f_finite(float) #0
18 declare double @__exp_finite(double) #0
19 declare float @__expf_finite(float) #0
20 declare double @__log10_finite(double) #0
21 declare float @__log10f_finite(float) #0
22 declare double @__log_finite(double) #0
23 declare float @__logf_finite(float) #0
24 declare double @__pow_finite(double, double) #0
25 declare float @__powf_finite(float, float) #0
26 declare double @__sinh_finite(double) #0
27 declare float @__sinhf_finite(float) #0
28
29 attributes #0 = { nounwind readnone }
30
31 define void @T() {
32 ; CHECK-LABEL: @T(
33
34 ; CHECK-NOT: call
35 ; CHECK: ret
36
37 %slot = alloca double
38 %slotf = alloca float
39
40 %ACOS = call fast double @__acos_finite(double 1.000000e+00)
41 store double %ACOS, double* %slot
42 %ASIN = call fast double @__asin_finite(double 1.000000e+00)
43 store double %ASIN, double* %slot
44 %ATAN2 = call fast double @__atan2_finite(double 3.000000e+00, double 4.000000e+00)
45 store double %ATAN2, double* %slot
46 %COSH = call fast double @__cosh_finite(double 3.000000e+00)
47 store double %COSH, double* %slot
48 %EXP = call fast double @__exp_finite(double 3.000000e+00)
49 store double %EXP, double* %slot
50 %EXP2 = call fast double @__exp2_finite(double 3.000000e+00)
51 store double %EXP2, double* %slot
52 %LOG = call fast double @__log_finite(double 3.000000e+00)
53 store double %LOG, double* %slot
54 %LOG10 = call fast double @__log10_finite(double 3.000000e+00)
55 store double %LOG10, double* %slot
56 %POW = call fast double @__pow_finite(double 1.000000e+00, double 4.000000e+00)
57 store double %POW, double* %slot
58 %SINH = call fast double @__sinh_finite(double 3.000000e+00)
59 store double %SINH, double* %slot
60
61 %ACOSF = call fast float @__acosf_finite(float 1.000000e+00)
62 store float %ACOSF, float* %slotf
63 %ASINF = call fast float @__asinf_finite(float 1.000000e+00)
64 store float %ASINF, float* %slotf
65 %ATAN2F = call fast float @__atan2f_finite(float 3.000000e+00, float 4.000000e+00)
66 store float %ATAN2F, float* %slotf
67 %COSHF = call fast float @__coshf_finite(float 3.000000e+00)
68 store float %COSHF, float* %slotf
69 %EXPF = call fast float @__expf_finite(float 3.000000e+00)
70 store float %EXPF, float* %slotf
71 %EXP2F = call fast float @__exp2f_finite(float 3.000000e+00)
72 store float %EXP2F, float* %slotf
73 %LOGF = call fast float @__logf_finite(float 3.000000e+00)
74 store float %LOGF, float* %slotf
75 %LOG10F = call fast float @__log10f_finite(float 3.000000e+00)
76 store float %LOG10F, float* %slotf
77 %POWF = call fast float @__powf_finite(float 3.000000e+00, float 4.000000e+00)
78 store float %POWF, float* %slotf
79 %SINHF = call fast float @__sinhf_finite(float 3.000000e+00)
80 store float %SINHF, float* %slotf
81 ret void
82 }