aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorYingwei Zheng <dtcxzyw2333@gmail.com>2025-04-02 18:45:33 +0800
committerGitHub <noreply@github.com>2025-04-02 18:45:33 +0800
commitf066d7504e736f7dc8bee3b9c514a86e229fd622 (patch)
tree4083048ab7f947f4032105c2e9fa80c3f9095d22 /llvm/lib/Analysis/ScalarEvolution.cpp
parentef56b5371294d0c4368b52d4f164f6aa07e1aa4d (diff)
downloadllvm-f066d7504e736f7dc8bee3b9c514a86e229fd622.zip
llvm-f066d7504e736f7dc8bee3b9c514a86e229fd622.tar.gz
llvm-f066d7504e736f7dc8bee3b9c514a86e229fd622.tar.bz2
[Reland][SCEV] teach isImpliedViaOperations about samesign (#133711)
This patch relands https://github.com/llvm/llvm-project/pull/124270. Closes https://github.com/llvm/llvm-project/issues/126409. The root cause is that we incorrectly preserve the samesign flag after truncating operands of an icmp: https://alive2.llvm.org/ce/z/4NE9gS --------- Co-authored-by: Ramkumar Ramachandra <ramkumar.ramachandra@codasip.com>
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp39
1 files changed, 21 insertions, 18 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 0e23479..2bf738c 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -11791,8 +11791,10 @@ bool ScalarEvolution::isImpliedCond(CmpPredicate Pred, const SCEV *LHS,
MaxValue)) {
const SCEV *TruncFoundLHS = getTruncateExpr(FoundLHS, NarrowType);
const SCEV *TruncFoundRHS = getTruncateExpr(FoundRHS, NarrowType);
- if (isImpliedCondBalancedTypes(Pred, LHS, RHS, FoundPred, TruncFoundLHS,
- TruncFoundRHS, CtxI))
+ // We cannot preserve samesign after truncation.
+ if (isImpliedCondBalancedTypes(
+ Pred, LHS, RHS, static_cast<ICmpInst::Predicate>(FoundPred),
+ TruncFoundLHS, TruncFoundRHS, CtxI))
return true;
}
}
@@ -11849,15 +11851,13 @@ bool ScalarEvolution::isImpliedCondBalancedTypes(
}
// Check whether the found predicate is the same as the desired predicate.
- // FIXME: use CmpPredicate::getMatching here.
- if (FoundPred == static_cast<CmpInst::Predicate>(Pred))
- return isImpliedCondOperands(Pred, LHS, RHS, FoundLHS, FoundRHS, CtxI);
+ if (auto P = CmpPredicate::getMatching(FoundPred, Pred))
+ return isImpliedCondOperands(*P, LHS, RHS, FoundLHS, FoundRHS, CtxI);
// Check whether swapping the found predicate makes it the same as the
// desired predicate.
- // FIXME: use CmpPredicate::getMatching here.
- if (ICmpInst::getSwappedCmpPredicate(FoundPred) ==
- static_cast<CmpInst::Predicate>(Pred)) {
+ if (auto P = CmpPredicate::getMatching(
+ ICmpInst::getSwappedCmpPredicate(FoundPred), Pred)) {
// We can write the implication
// 0. LHS Pred RHS <- FoundLHS SwapPred FoundRHS
// using one of the following ways:
@@ -11868,22 +11868,23 @@ bool ScalarEvolution::isImpliedCondBalancedTypes(
// Forms 1. and 2. require swapping the operands of one condition. Don't
// do this if it would break canonical constant/addrec ordering.
if (!isa<SCEVConstant>(RHS) && !isa<SCEVAddRecExpr>(LHS))
- return isImpliedCondOperands(FoundPred, RHS, LHS, FoundLHS, FoundRHS,
- CtxI);
+ return isImpliedCondOperands(ICmpInst::getSwappedCmpPredicate(*P), RHS,
+ LHS, FoundLHS, FoundRHS, CtxI);
if (!isa<SCEVConstant>(FoundRHS) && !isa<SCEVAddRecExpr>(FoundLHS))
- return isImpliedCondOperands(Pred, LHS, RHS, FoundRHS, FoundLHS, CtxI);
+ return isImpliedCondOperands(*P, LHS, RHS, FoundRHS, FoundLHS, CtxI);
// There's no clear preference between forms 3. and 4., try both. Avoid
// forming getNotSCEV of pointer values as the resulting subtract is
// not legal.
if (!LHS->getType()->isPointerTy() && !RHS->getType()->isPointerTy() &&
- isImpliedCondOperands(FoundPred, getNotSCEV(LHS), getNotSCEV(RHS),
- FoundLHS, FoundRHS, CtxI))
+ isImpliedCondOperands(ICmpInst::getSwappedCmpPredicate(*P),
+ getNotSCEV(LHS), getNotSCEV(RHS), FoundLHS,
+ FoundRHS, CtxI))
return true;
if (!FoundLHS->getType()->isPointerTy() &&
!FoundRHS->getType()->isPointerTy() &&
- isImpliedCondOperands(Pred, LHS, RHS, getNotSCEV(FoundLHS),
+ isImpliedCondOperands(*P, LHS, RHS, getNotSCEV(FoundLHS),
getNotSCEV(FoundRHS), CtxI))
return true;
@@ -12559,14 +12560,16 @@ bool ScalarEvolution::isImpliedViaOperations(CmpPredicate Pred, const SCEV *LHS,
return false;
// We only want to work with GT comparison so far.
- if (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_SLT) {
+ if (ICmpInst::isLT(Pred)) {
Pred = ICmpInst::getSwappedCmpPredicate(Pred);
std::swap(LHS, RHS);
std::swap(FoundLHS, FoundRHS);
}
+ CmpInst::Predicate P = Pred.getPreferredSignedPredicate();
+
// For unsigned, try to reduce it to corresponding signed comparison.
- if (Pred == ICmpInst::ICMP_UGT)
+ if (P == ICmpInst::ICMP_UGT)
// We can replace unsigned predicate with its signed counterpart if all
// involved values are non-negative.
// TODO: We could have better support for unsigned.
@@ -12579,10 +12582,10 @@ bool ScalarEvolution::isImpliedViaOperations(CmpPredicate Pred, const SCEV *LHS,
FoundRHS) &&
isImpliedCondOperands(ICmpInst::ICMP_SGT, RHS, MinusOne, FoundLHS,
FoundRHS))
- Pred = ICmpInst::ICMP_SGT;
+ P = ICmpInst::ICMP_SGT;
}
- if (Pred != ICmpInst::ICMP_SGT)
+ if (P != ICmpInst::ICMP_SGT)
return false;
auto GetOpFromSExt = [&](const SCEV *S) {