aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorYingwei Zheng <dtcxzyw2333@gmail.com>2024-02-14 20:53:16 +0800
committerGitHub <noreply@github.com>2024-02-14 20:53:16 +0800
commit16a0629e7c16cc1ec1a5066c57be3044a1e00395 (patch)
treeb3559eded97c709c0bb9c46bbb568a9360fc1469 /llvm/lib/Analysis/ValueTracking.cpp
parentc5e13840fdc20adce51673a63d5703bf1ed02aba (diff)
downloadllvm-16a0629e7c16cc1ec1a5066c57be3044a1e00395.zip
llvm-16a0629e7c16cc1ec1a5066c57be3044a1e00395.tar.gz
llvm-16a0629e7c16cc1ec1a5066c57be3044a1e00395.tar.bz2
[ValueTracking] Compute known FPClass from signbit idiom (#80740)
This patch improves `computeKnownFPClass` by using context-sensitive information from `DomConditionCache`. The motivation of this patch is to optimize the following case found in [fmt/format.h](https://github.com/fmtlib/fmt/blob/e17bc67547a66cdd378ca6a90c56b865d30d6168/include/fmt/format.h#L3555-L3566): ``` define float @test(float %x, i1 %cond) { %i32 = bitcast float %x to i32 %cmp = icmp slt i32 %i32, 0 br i1 %cmp, label %if.then1, label %if.else if.then1: %fneg = fneg float %x br label %if.end if.else: br i1 %cond, label %if.then2, label %if.end if.then2: br label %if.end if.end: %value = phi float [ %fneg, %if.then1 ], [ %x, %if.then2 ], [ %x, %if.else ] %ret = call float @llvm.fabs.f32(float %value) ret float %ret } ``` We can prove the sign bit of %value is always zero. Then the fabs can be eliminated. This pattern also exists in cpython/duckdb/oiio/openexr. Compile-time impact: https://llvm-compile-time-tracker.com/compare.php?from=f82e0809ba12170e2f648f8a1ac01e78ef06c958&to=041218bf5491996edd828cc15b3aec5a59ddc636&stat=instructions:u |stage1-O3|stage1-ReleaseThinLTO|stage1-ReleaseLTO-g|stage1-O0-g|stage2-O3|stage2-O0-g|stage2-clang| |--|--|--|--|--|--|--| |-0.00%|+0.01%|+0.00%|-0.03%|+0.00%|+0.00%|+0.02%|
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp11
1 files changed, 10 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 6c42fac..cc1d5b7 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4272,7 +4272,7 @@ static void computeKnownFPClassFromCond(const Value *V, Value *Cond,
Value *LHS;
uint64_t ClassVal = 0;
const APFloat *CRHS;
- // TODO: handle sign-bit check idiom
+ const APInt *RHS;
if (match(Cond, m_FCmp(Pred, m_Value(LHS), m_APFloat(CRHS)))) {
auto [CmpVal, MaskIfTrue, MaskIfFalse] = fcmpImpliesClass(
Pred, *CxtI->getParent()->getParent(), LHS, *CRHS, LHS != V);
@@ -4282,6 +4282,15 @@ static void computeKnownFPClassFromCond(const Value *V, Value *Cond,
m_Value(LHS), m_ConstantInt(ClassVal)))) {
FPClassTest Mask = static_cast<FPClassTest>(ClassVal);
KnownFromContext.knownNot(CondIsTrue ? ~Mask : Mask);
+ } else if (match(Cond, m_ICmp(Pred, m_ElementWiseBitCast(m_Value(LHS)),
+ m_APInt(RHS)))) {
+ bool TrueIfSigned;
+ if (!isSignBitCheck(Pred, *RHS, TrueIfSigned))
+ return;
+ if (TrueIfSigned == CondIsTrue)
+ KnownFromContext.signBitMustBeOne();
+ else
+ KnownFromContext.signBitMustBeZero();
}
}