Index: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h =================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h @@ -834,6 +834,11 @@ bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS); + /// Test if the condition described by Pred, LHS, RHS is known to be true on + /// every iteration of the loop of the recurrency LHS. + bool isKnownOnEveryIteration(ICmpInst::Predicate Pred, + const SCEVAddRecExpr *LHS, const SCEV *RHS); + /// Return true if, for all loop invariant X, the predicate "LHS `Pred` X" /// is monotonically increasing or decreasing. In the former case set /// `Increasing` to true and in the latter case set `Increasing` to false. Index: llvm/trunk/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp @@ -1732,9 +1732,7 @@ const SCEV *N = getConstant(APInt::getMinValue(BitWidth) - getUnsignedRangeMax(Step)); if (isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_ULT, AR, N) || - (isLoopEntryGuardedByCond(L, ICmpInst::ICMP_ULT, Start, N) && - isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_ULT, - AR->getPostIncExpr(*this), N))) { + isKnownOnEveryIteration(ICmpInst::ICMP_ULT, AR, N)) { // Cache knowledge of AR NUW, which is propagated to this // AddRec. const_cast(AR)->setNoWrapFlags(SCEV::FlagNUW); @@ -1749,9 +1747,7 @@ const SCEV *N = getConstant(APInt::getMaxValue(BitWidth) - getSignedRangeMin(Step)); if (isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_UGT, AR, N) || - (isLoopEntryGuardedByCond(L, ICmpInst::ICMP_UGT, Start, N) && - isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_UGT, - AR->getPostIncExpr(*this), N))) { + isKnownOnEveryIteration(ICmpInst::ICMP_UGT, AR, N)) { // Cache knowledge of AR NW, which is propagated to this // AddRec. Negative step causes unsigned wrap, but it // still can't self-wrap. @@ -1994,9 +1990,7 @@ getSignedOverflowLimitForStep(Step, &Pred, this); if (OverflowLimit && (isLoopBackedgeGuardedByCond(L, Pred, AR, OverflowLimit) || - (isLoopEntryGuardedByCond(L, Pred, Start, OverflowLimit) && - isLoopBackedgeGuardedByCond(L, Pred, AR->getPostIncExpr(*this), - OverflowLimit)))) { + isKnownOnEveryIteration(Pred, AR, OverflowLimit))) { // Cache knowledge of AR NSW, then propagate NSW to the wide AddRec. const_cast(AR)->setNoWrapFlags(SCEV::FlagNSW); return getAddRecExpr( @@ -8677,17 +8671,16 @@ if (LAR) { const Loop *L = LAR->getLoop(); if (isAvailableAtLoopEntry(RHS, L) && - isLoopEntryGuardedByCond(L, Pred, LAR->getStart(), RHS) && - isLoopBackedgeGuardedByCond(L, Pred, LAR->getPostIncExpr(*this), RHS)) { + isKnownOnEveryIteration(Pred, LAR, RHS)) { if (!RAR) return true; LeftGuarded = true; } } if (RAR) { const Loop *L = RAR->getLoop(); + auto SwappedPred = ICmpInst::getSwappedPredicate(Pred); if (isAvailableAtLoopEntry(LHS, L) && - isLoopEntryGuardedByCond(L, Pred, LHS, RAR->getStart()) && - isLoopBackedgeGuardedByCond(L, Pred, LHS, RAR->getPostIncExpr(*this))) { + isKnownOnEveryIteration(SwappedPred, RAR, LHS)) { if (!LAR) return true; RightGuarded = true; } @@ -8702,6 +8695,14 @@ return isKnownViaNonRecursiveReasoning(Pred, LHS, RHS); } +bool ScalarEvolution::isKnownOnEveryIteration(ICmpInst::Predicate Pred, + const SCEVAddRecExpr *LHS, + const SCEV *RHS) { + const Loop *L = LHS->getLoop(); + return isLoopEntryGuardedByCond(L, Pred, LHS->getStart(), RHS) && + isLoopBackedgeGuardedByCond(L, Pred, LHS->getPostIncExpr(*this), RHS); +} + bool ScalarEvolution::isMonotonicPredicate(const SCEVAddRecExpr *LHS, ICmpInst::Predicate Pred, bool &Increasing) {