aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
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: