[llvm] d38c8a7 - ConstantFold logl calls (#94944)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 18 05:27:28 PDT 2024
Author: Matthew Devereau
Date: 2024-06-18T13:27:25+01:00
New Revision: d38c8a7a51227fecdb1f84160f5da4f89c3e25be
URL: https://github.com/llvm/llvm-project/commit/d38c8a7a51227fecdb1f84160f5da4f89c3e25be
DIFF: https://github.com/llvm/llvm-project/commit/d38c8a7a51227fecdb1f84160f5da4f89c3e25be.diff
LOG: 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.
Added:
Modified:
llvm/lib/Analysis/ConstantFolding.cpp
llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index e0f5bf0ab8365..4087cf3dd76b8 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:
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll b/llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll
index da56997f69382..1f8e1d377f93b 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll
@@ -3,6 +3,7 @@
; REQUIRES: has_logf128
declare fp128 @llvm.log.f128(fp128)
+declare fp128 @logl(fp128)
define fp128 @log_e_64(){
; CHECK-LABEL: define fp128 @log_e_64() {
@@ -124,3 +125,49 @@ define <2 x fp128> @log_e_negative_2_vector(){
%A = call <2 x fp128> @llvm.log.v2f128(<2 x fp128> <fp128 0xL0000000000000000C000000000000000, fp128 0xL0000000000000000C000000000000001>)
ret <2 x fp128> %A
}
+
+define fp128 @logl_e_64(){
+; CHECK-LABEL: define fp128 @logl_e_64() {
+; CHECK-NEXT: [[A:%.*]] = call fp128 @logl(fp128 noundef 0xL00000000000000004005000000000000)
+; CHECK-NEXT: ret fp128 0xL300000000000000040010A2B23F3BAB7
+;
+ %A = call fp128 @logl(fp128 noundef 0xL00000000000000004005000000000000)
+ ret fp128 %A
+}
+
+define fp128 @logl_e_0(){
+; CHECK-LABEL: define fp128 @logl_e_0() {
+; CHECK-NEXT: [[A:%.*]] = call fp128 @logl(fp128 noundef 0xL00000000000000000000000000000000)
+; CHECK-NEXT: ret fp128 [[A]]
+;
+ %A = call fp128 @logl(fp128 noundef 0xL00000000000000000000000000000000)
+ ret fp128 %A
+}
+
+define fp128 @logl_e_infinity(){
+; CHECK-LABEL: define fp128 @logl_e_infinity() {
+; CHECK-NEXT: [[A:%.*]] = call fp128 @logl(fp128 noundef 0xL00000000000000007FFF000000000000)
+; CHECK-NEXT: ret fp128 0xL00000000000000007FFF000000000000
+;
+ %A = call fp128 @logl(fp128 noundef 0xL00000000000000007FFF000000000000)
+ ret fp128 %A
+}
+
+define fp128 @logl_e_nan(){
+; CHECK-LABEL: define fp128 @logl_e_nan() {
+; CHECK-NEXT: [[A:%.*]] = call fp128 @logl(fp128 noundef 0xL00000000000000007FFF000000000001)
+; CHECK-NEXT: ret fp128 [[A]]
+;
+ %A = call fp128 @logl(fp128 noundef 0xL00000000000000007FFF000000000001)
+ ret fp128 %A
+}
+
+
+define fp128 @logl_e_negative_2(){
+; CHECK-LABEL: define fp128 @logl_e_negative_2() {
+; CHECK-NEXT: [[A:%.*]] = call fp128 @logl(fp128 noundef 0xL0000000000000000C000000000000000)
+; CHECK-NEXT: ret fp128 [[A]]
+;
+ %A = call fp128 @logl(fp128 noundef 0xL0000000000000000C000000000000000)
+ ret fp128 %A
+}
More information about the llvm-commits
mailing list