diff options
author | Matthew Devereau <matthew.devereau@arm.com> | 2024-06-18 13:27:25 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-18 13:27:25 +0100 |
commit | d38c8a7a51227fecdb1f84160f5da4f89c3e25be (patch) | |
tree | 9d2b275f110f232a7f77717dc7246a87db962ead /llvm/lib/Analysis/ConstantFolding.cpp | |
parent | d97951e57a9b47fc3febff130217da62071aa44b (diff) | |
download | llvm-d38c8a7a51227fecdb1f84160f5da4f89c3e25be.zip llvm-d38c8a7a51227fecdb1f84160f5da4f89c3e25be.tar.gz llvm-d38c8a7a51227fecdb1f84160f5da4f89c3e25be.tar.bz2 |
ConstantFold logl calls (#94944)
This is a follow up patch from #90611 which folds logl calls in the same
manner as log.f128 calls. logl suffers from the same problem as logf128
of having slow calls to fp128 log functions which can be constant
folded. However, logl is emitted with -fmath-errno and log.f128 is
emitted by -fno-math-errno by certain intrinsics.
Diffstat (limited to 'llvm/lib/Analysis/ConstantFolding.cpp')
-rw-r--r-- | llvm/lib/Analysis/ConstantFolding.cpp | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index e0f5bf0..4087cf3 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -1678,9 +1678,9 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) { Name == "floor" || Name == "floorf" || Name == "fmod" || Name == "fmodf"; case 'l': - return Name == "log" || Name == "logf" || - Name == "log2" || Name == "log2f" || - Name == "log10" || Name == "log10f"; + return Name == "log" || Name == "logf" || Name == "log2" || + Name == "log2f" || Name == "log10" || Name == "log10f" || + Name == "logl"; case 'n': return Name == "nearbyint" || Name == "nearbyintf"; case 'p': @@ -1743,6 +1743,14 @@ Constant *GetConstantFoldFPValue(double V, Type *Ty) { llvm_unreachable("Can only constant fold half/float/double"); } +#if defined(HAS_IEE754_FLOAT128) +Constant *GetConstantFoldFPValue128(__float128 V, Type *Ty) { + if (Ty->isFP128Ty()) + return ConstantFP::get(Ty, V); + llvm_unreachable("Can only constant fold fp128"); +} +#endif + /// Clear the floating-point exception state. inline void llvm_fenv_clearexcept() { #if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT @@ -1775,6 +1783,20 @@ Constant *ConstantFoldFP(double (*NativeFP)(double), const APFloat &V, return GetConstantFoldFPValue(Result, Ty); } +#if defined(HAS_IEE754_FLOAT128) +Constant *ConstantFoldFP128(long double (*NativeFP)(long double), + const APFloat &V, Type *Ty) { + llvm_fenv_clearexcept(); + __float128 Result = NativeFP(V.convertToQuad()); + if (llvm_fenv_testexcept()) { + llvm_fenv_clearexcept(); + return nullptr; + } + + return GetConstantFoldFPValue128(Result, Ty); +} +#endif + Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double), const APFloat &V, const APFloat &W, Type *Ty) { llvm_fenv_clearexcept(); @@ -2096,12 +2118,15 @@ static Constant *ConstantFoldScalarCall1(StringRef Name, #if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128) if (Ty->isFP128Ty()) { - switch (IntrinsicID) { - default: - return nullptr; - case Intrinsic::log: - return ConstantFP::get(Ty, logf128(Op->getValueAPF().convertToQuad())); + if (IntrinsicID == Intrinsic::log) { + __float128 Result = logf128(Op->getValueAPF().convertToQuad()); + return GetConstantFoldFPValue128(Result, Ty); } + + LibFunc Fp128Func = NotLibFunc; + if (TLI->getLibFunc(Name, Fp128Func) && TLI->has(Fp128Func) && + Fp128Func == LibFunc_logl) + return ConstantFoldFP128(logf128, Op->getValueAPF(), Ty); } #endif @@ -2365,6 +2390,8 @@ static Constant *ConstantFoldScalarCall1(StringRef Name, // TODO: What about hosts that lack a C99 library? return ConstantFoldFP(log10, APF, Ty); break; + case LibFunc_logl: + return nullptr; case LibFunc_nearbyint: case LibFunc_nearbyintf: case LibFunc_rint: |