diff options
author | Yingwei Zheng <dtcxzyw2333@gmail.com> | 2025-04-02 18:45:33 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-02 18:45:33 +0800 |
commit | f066d7504e736f7dc8bee3b9c514a86e229fd622 (patch) | |
tree | 4083048ab7f947f4032105c2e9fa80c3f9095d22 /llvm/lib/Analysis/ScalarEvolution.cpp | |
parent | ef56b5371294d0c4368b52d4f164f6aa07e1aa4d (diff) | |
download | llvm-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.cpp | 39 |
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) { |