aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorYingwei Zheng <dtcxzyw2333@gmail.com>2024-10-17 00:27:21 +0800
committerGitHub <noreply@github.com>2024-10-17 00:27:21 +0800
commitaad3a1630e385a6834f92a5f1d6045451ba21e4e (patch)
treea7df76128a6f2a45339ca2ad0bca936a3a3f9f17 /llvm/lib/Analysis/ValueTracking.cpp
parent35e937b4de1890186347a382f7727ba86441dbda (diff)
downloadllvm-aad3a1630e385a6834f92a5f1d6045451ba21e4e.zip
llvm-aad3a1630e385a6834f92a5f1d6045451ba21e4e.tar.gz
llvm-aad3a1630e385a6834f92a5f1d6045451ba21e4e.tar.bz2
[ValueTracking] Respect `samesign` flag in `isKnownInversion` (#112390)
In https://github.com/llvm/llvm-project/pull/93591 we introduced `isKnownInversion` and assumes `X` is poison implies `Y` is poison because they share common operands. But after introducing `samesign` this assumption no longer hold if `X` is an icmp has `samesign` flag. Alive2 link: https://alive2.llvm.org/ce/z/rj3EwQ (Please run it locally with this patch and https://github.com/AliveToolkit/alive2/pull/1098). This approach is the most conservative way in my mind to address this problem. If `X` has `samesign` flag, it will check if `Y` also has this flag and make sure constant RHS operands have the same sign. Fixes https://github.com/llvm/llvm-project/issues/112350.
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp9
1 files changed, 9 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index eb8d170..e9ed8b3 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -8522,6 +8522,10 @@ bool llvm::isKnownInversion(const Value *X, const Value *Y) {
!match(Y, m_c_ICmp(Pred2, m_Specific(A), m_Value(C))))
return false;
+ // They must both have samesign flag or not.
+ if (cast<ICmpInst>(X)->hasSameSign() != cast<ICmpInst>(Y)->hasSameSign())
+ return false;
+
if (B == C)
return Pred1 == ICmpInst::getInversePredicate(Pred2);
@@ -8530,6 +8534,11 @@ bool llvm::isKnownInversion(const Value *X, const Value *Y) {
if (!match(B, m_APInt(RHSC1)) || !match(C, m_APInt(RHSC2)))
return false;
+ // Sign bits of two RHSCs should match.
+ if (cast<ICmpInst>(X)->hasSameSign() &&
+ RHSC1->isNonNegative() != RHSC2->isNonNegative())
+ return false;
+
const auto CR1 = ConstantRange::makeExactICmpRegion(Pred1, *RHSC1);
const auto CR2 = ConstantRange::makeExactICmpRegion(Pred2, *RHSC2);