[llvm] [SCEV] Prove predicate via nuw AddRec value at max iteration (PR #210844)
Abhay Kanhere via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 30 14:47:43 PDT 2026
================
@@ -13255,6 +13258,50 @@ static bool isKnownPredicateExtendIdiom(CmpPredicate Pred, const SCEV *LHS,
llvm_unreachable("unhandled case");
}
+// Prove LHS Pred RHS by replacing an affine nuw AddRec LHS with its value at
+// the maximum iteration count and comparing that loop-invariant bound against
+// RHS. nuw makes the AddRec unsigned non-decreasing, so its max is at that
+// iteration regardless of the step's sign.
+bool ScalarEvolution::isKnownPredicateViaMaxValue(CmpPredicate Pred,
+ SCEVUse LHS, SCEVUse RHS) {
+ if (Pred == ICmpInst::ICMP_UGE || Pred == ICmpInst::ICMP_UGT) {
+ std::swap(LHS, RHS);
+ Pred = ICmpInst::getSwappedCmpPredicate(Pred);
+ }
+ if (Pred != ICmpInst::ICMP_ULE && Pred != ICmpInst::ICMP_ULT)
+ return false;
+ const auto *AR = dyn_cast<SCEVAddRecExpr>(LHS);
+ if (!AR || !AR->isAffine() || !AR->hasNoUnsignedWrap() ||
+ !AR->getType()->isIntegerTy())
+ return false;
+ const Loop *L = AR->getLoop();
+ if (!isLoopInvariant(RHS, L))
+ return false;
+
+ // The symbolic max BTC is only an upper bound on the trip count, so a nuw
+ // AddRec evaluated there can still unsigned-wrap. Widen and require
+ // start + BTC*step to provably not overflow.
+ const SCEV *BTC = getSymbolicMaxBackedgeTakenCount(L);
+ if (isa<SCEVCouldNotCompute>(BTC))
+ return false;
+ BTC = applyLoopGuards(BTC, L);
+
+ const SCEV *Start = AR->getStart();
+ const SCEV *Step = AR->getStepRecurrence(*this);
+ Type *WideTy = getWiderType(BTC->getType(), AR->getType());
----------------
AbhayKanhere wrote:
Changes to ensure we don't assume no-wrap - we compute in wider type ensuring no wrap - also check for overflow to ensure we dont wrap.
https://github.com/llvm/llvm-project/pull/210844
More information about the llvm-commits
mailing list