aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
authorMatthew Devereau <matthew.devereau@arm.com>2024-06-18 13:27:25 +0100
committerGitHub <noreply@github.com>2024-06-18 13:27:25 +0100
commitd38c8a7a51227fecdb1f84160f5da4f89c3e25be (patch)
tree9d2b275f110f232a7f77717dc7246a87db962ead /llvm/lib/Analysis/ConstantFolding.cpp
parentd97951e57a9b47fc3febff130217da62071aa44b (diff)
downloadllvm-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.cpp43
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: