From 7b851310dcf46e8f486b7e4c71e2280431f51201 Mon Sep 17 00:00:00 2001 From: c8ef Date: Sat, 19 Oct 2024 09:28:21 +0800 Subject: [PATCH 1/4] constant fold ilogb --- llvm/lib/Analysis/ConstantFolding.cpp | 21 ++- llvm/test/Transforms/InstCombine/ilogb.ll | 203 ++++++++++++++++++++++ 2 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Transforms/InstCombine/ilogb.ll diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 74df67a4ff9b4..d9eea2cc2915b 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -1677,6 +1677,8 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) { return Name == "fabs" || Name == "fabsf" || Name == "floor" || Name == "floorf" || Name == "fmod" || Name == "fmodf"; + case 'i': + return Name == "ilogb" || Name == "ilogbf"; case 'l': return Name == "log" || Name == "logf" || Name == "logl" || Name == "log2" || Name == "log2f" || Name == "log10" || @@ -1772,6 +1774,17 @@ inline bool llvm_fenv_testexcept() { return false; } +Constant *ConstantFoldInt(int (*NativeFP)(double), const APFloat &V, Type *Ty) { + llvm_fenv_clearexcept(); + int Result = NativeFP(V.convertToDouble()); + if (llvm_fenv_testexcept()) { + llvm_fenv_clearexcept(); + return nullptr; + } + + return ConstantInt::get(Ty, Result, true); +} + Constant *ConstantFoldFP(double (*NativeFP)(double), const APFloat &V, Type *Ty) { llvm_fenv_clearexcept(); @@ -2131,7 +2144,8 @@ static Constant *ConstantFoldScalarCall1(StringRef Name, } #endif - if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy()) + if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy() && + !Ty->isIntegerTy()) return nullptr; // Use internal versions of these intrinsics. @@ -2391,6 +2405,11 @@ static Constant *ConstantFoldScalarCall1(StringRef Name, // TODO: What about hosts that lack a C99 library? return ConstantFoldFP(log10, APF, Ty); break; + case LibFunc_ilogb: + case LibFunc_ilogbf: + if (!APF.isZero() && TLI->has(Func)) + return ConstantFoldInt(ilogb, APF, Ty); + break; case LibFunc_logb: case LibFunc_logbf: if (!APF.isZero() && TLI->has(Func)) diff --git a/llvm/test/Transforms/InstCombine/ilogb.ll b/llvm/test/Transforms/InstCombine/ilogb.ll new file mode 100644 index 0000000000000..e30791fe68e7b --- /dev/null +++ b/llvm/test/Transforms/InstCombine/ilogb.ll @@ -0,0 +1,203 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +define i32 @ilogbf_const1() { +; CHECK-LABEL: define i32 @ilogbf_const1() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogbf(float 7.000000e+00) +; CHECK-NEXT: ret i32 2 +; + %r = call i32 @ilogbf(float 7.000000e+00) + ret i32 %r +} + +define i32 @ilogb_const1() { +; CHECK-LABEL: define i32 @ilogb_const1() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogb(double -7.000000e+00) +; CHECK-NEXT: ret i32 2 +; + %r = call i32 @ilogb(double -7.000000e+00) + ret i32 %r +} + +define i32 @ilogbf_const2() { +; CHECK-LABEL: define i32 @ilogbf_const2() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogbf(float 5.000000e-01) +; CHECK-NEXT: ret i32 -1 +; + %r = call i32 @ilogbf(float 5.000000e-01) + ret i32 %r +} + +define i32 @ilogb_const2() { +; CHECK-LABEL: define i32 @ilogb_const2() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogb(double -5.000000e-01) +; CHECK-NEXT: ret i32 -1 +; + %r = call i32 @ilogb(double -5.000000e-01) + ret i32 %r +} + +define i32 @ilogbf_zero() { +; CHECK-LABEL: define i32 @ilogbf_zero() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogbf(float 0.000000e+00) +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogbf(float 0.000000e+00) + ret i32 %r +} + +define i32 @ilogb_zero() { +; CHECK-LABEL: define i32 @ilogb_zero() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogb(double 0.000000e+00) +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogb(double 0.000000e+00) + ret i32 %r +} + +define i32 @ilogbf_neg_zero() { +; CHECK-LABEL: define i32 @ilogbf_neg_zero() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogbf(float -0.000000e+00) +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogbf(float -0.000000e+00) + ret i32 %r +} + +define i32 @ilogb_neg_zero() { +; CHECK-LABEL: define i32 @ilogb_neg_zero() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogb(double -0.000000e+00) +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogb(double -0.000000e+00) + ret i32 %r +} + +define i32 @ilogbf_inf() { +; CHECK-LABEL: define i32 @ilogbf_inf() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogbf(float 0x7FF0000000000000) +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogbf(float 0x7FF0000000000000) + ret i32 %r +} + +define i32 @ilogb_inf() { +; CHECK-LABEL: define i32 @ilogb_inf() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogb(double 0x7FF0000000000000) +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogb(double 0x7FF0000000000000) + ret i32 %r +} + +define i32 @ilogbf_nan() { +; CHECK-LABEL: define i32 @ilogbf_nan() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogbf(float 0x7FF8000000000000) +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogbf(float 0x7FF8000000000000) + ret i32 %r +} + +define i32 @ilogb_nan() { +; CHECK-LABEL: define i32 @ilogb_nan() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogb(double 0x7FF8000000000000) +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogb(double 0x7FF8000000000000) + ret i32 %r +} + +define i32 @ilogbf_zero_readnone() { +; CHECK-LABEL: define i32 @ilogbf_zero_readnone() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogbf(float 0.000000e+00) #[[ATTR0:[0-9]+]] +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogbf(float 0.000000e+00) readnone + ret i32 %r +} + +define i32 @ilogb_zero_readnone() { +; CHECK-LABEL: define i32 @ilogb_zero_readnone() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogb(double 0.000000e+00) #[[ATTR0]] +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogb(double 0.000000e+00) readnone + ret i32 %r +} + +define i32 @ilogbf_neg_zero_readnone() { +; CHECK-LABEL: define i32 @ilogbf_neg_zero_readnone() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogbf(float -0.000000e+00) #[[ATTR0]] +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogbf(float -0.000000e+00) readnone + ret i32 %r +} + +define i32 @ilogb_neg_zero_readnone() { +; CHECK-LABEL: define i32 @ilogb_neg_zero_readnone() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogb(double -0.000000e+00) #[[ATTR0]] +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogb(double -0.000000e+00) readnone + ret i32 %r +} + +define i32 @ilogbf_inf_readnone() { +; CHECK-LABEL: define i32 @ilogbf_inf_readnone() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogbf(float 0x7FF0000000000000) #[[ATTR0]] +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogbf(float 0x7FF0000000000000) readnone + ret i32 %r +} + +define i32 @ilogb_inf_readnone() { +; CHECK-LABEL: define i32 @ilogb_inf_readnone() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogb(double 0x7FF0000000000000) #[[ATTR0]] +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogb(double 0x7FF0000000000000) readnone + ret i32 %r +} + +define i32 @ilogbf_nan_readnone() { +; CHECK-LABEL: define i32 @ilogbf_nan_readnone() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogbf(float 0x7FF8000000000000) #[[ATTR0]] +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogbf(float 0x7FF8000000000000) readnone + ret i32 %r +} + +define i32 @ilogb_nan_readnone() { +; CHECK-LABEL: define i32 @ilogb_nan_readnone() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogb(double 0x7FF8000000000000) #[[ATTR0]] +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogb(double 0x7FF8000000000000) readnone + ret i32 %r +} + +define i32 @ilogbf_poison() { +; CHECK-LABEL: define i32 @ilogbf_poison() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogbf(float poison) +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogbf(float poison) + ret i32 %r +} + +define i32 @ilogb_poison() { +; CHECK-LABEL: define i32 @ilogb_poison() { +; CHECK-NEXT: [[R:%.*]] = call i32 @ilogb(double poison) +; CHECK-NEXT: ret i32 [[R]] +; + %r = call i32 @ilogb(double poison) + ret i32 %r +} + +declare i32 @ilogbf(float) +declare i32 @ilogb(double) From c2d1a1616bd5e2f2b7f3333f93799881c34da21f Mon Sep 17 00:00:00 2001 From: c8ef Date: Sat, 19 Oct 2024 13:02:29 +0800 Subject: [PATCH 2/4] address review comments --- llvm/lib/Analysis/ConstantFolding.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index d9eea2cc2915b..c0104d2bc2611 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -1774,17 +1774,6 @@ inline bool llvm_fenv_testexcept() { return false; } -Constant *ConstantFoldInt(int (*NativeFP)(double), const APFloat &V, Type *Ty) { - llvm_fenv_clearexcept(); - int Result = NativeFP(V.convertToDouble()); - if (llvm_fenv_testexcept()) { - llvm_fenv_clearexcept(); - return nullptr; - } - - return ConstantInt::get(Ty, Result, true); -} - Constant *ConstantFoldFP(double (*NativeFP)(double), const APFloat &V, Type *Ty) { llvm_fenv_clearexcept(); @@ -2408,7 +2397,7 @@ static Constant *ConstantFoldScalarCall1(StringRef Name, case LibFunc_ilogb: case LibFunc_ilogbf: if (!APF.isZero() && TLI->has(Func)) - return ConstantFoldInt(ilogb, APF, Ty); + return ConstantInt::get(Ty, ilogb(APF), true); break; case LibFunc_logb: case LibFunc_logbf: From 5f1f69368e1f17ff9e32428f36cf34ffb6255ae5 Mon Sep 17 00:00:00 2001 From: c8ef Date: Sat, 19 Oct 2024 21:34:42 +0800 Subject: [PATCH 3/4] try deleting check --- llvm/lib/Analysis/ConstantFolding.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index c0104d2bc2611..2a345c2f36d4b 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -2133,12 +2133,7 @@ static Constant *ConstantFoldScalarCall1(StringRef Name, } #endif - if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy() && - !Ty->isIntegerTy()) - return nullptr; - // Use internal versions of these intrinsics. - if (IntrinsicID == Intrinsic::nearbyint || IntrinsicID == Intrinsic::rint) { U.roundToIntegral(APFloat::rmNearestTiesToEven); return ConstantFP::get(Ty->getContext(), U); From 6a3f80fd26b7976a771382a6363cbb0b7ba15e88 Mon Sep 17 00:00:00 2001 From: c8ef Date: Sat, 19 Oct 2024 22:25:36 +0800 Subject: [PATCH 4/4] Revert "try deleting check" This reverts commit 5f1f69368e1f17ff9e32428f36cf34ffb6255ae5. --- llvm/lib/Analysis/ConstantFolding.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 2a345c2f36d4b..c0104d2bc2611 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -2133,7 +2133,12 @@ static Constant *ConstantFoldScalarCall1(StringRef Name, } #endif + if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy() && + !Ty->isIntegerTy()) + return nullptr; + // Use internal versions of these intrinsics. + if (IntrinsicID == Intrinsic::nearbyint || IntrinsicID == Intrinsic::rint) { U.roundToIntegral(APFloat::rmNearestTiesToEven); return ConstantFP::get(Ty->getContext(), U);