diff options
author | Yingwei Zheng <dtcxzyw2333@gmail.com> | 2024-02-14 20:53:16 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-14 20:53:16 +0800 |
commit | 16a0629e7c16cc1ec1a5066c57be3044a1e00395 (patch) | |
tree | b3559eded97c709c0bb9c46bbb568a9360fc1469 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | c5e13840fdc20adce51673a63d5703bf1ed02aba (diff) | |
download | llvm-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.cpp | 11 |
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(); } } |