if (isLoopEntryGuardedByCond(L, Cond, getMinusSCEV(OrigStart, Stride), OrigRHS))
BECount = BECountIfBackedgeTaken;
else {
+ auto canProveRHSGreaterThanEqualStart = [&]() {
+ auto CondGE = IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE;
+ if (isLoopEntryGuardedByCond(L, CondGE, OrigRHS, OrigStart))
+ return true;
+
+ // (RHS > Start - 1) implies RHS >= Start.
+ // * "RHS >= Start" is trivially equivalent to "RHS > Start - 1" if
+ // "Start - 1" doesn't overflow.
+ // * For signed comparison, if Start - 1 does overflow, it's equal
+ // to INT_MAX, and "RHS >s INT_MAX" is trivially false.
+ // * For unsigned comparison, if Start - 1 does overflow, it's equal
+ // to UINT_MAX, and "RHS >u UINT_MAX" is trivially false.
+ //
+ // FIXME: Should isLoopEntryGuardedByCond do this for us?
+ auto CondGT = IsSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
+ auto *StartMinusOne = getAddExpr(OrigStart,
+ getMinusOne(OrigStart->getType()));
+ return isLoopEntryGuardedByCond(L, CondGT, OrigRHS, StartMinusOne);
+ };
+
// If we know that RHS >= Start in the context of loop, then we know that
// max(RHS, Start) = RHS at this point.
- if (isLoopEntryGuardedByCond(
- L, IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE, OrigRHS, OrigStart))
+ if (canProveRHSGreaterThanEqualStart())
End = RHS;
else
End = IsSigned ? getSMaxExpr(RHS, Start) : getUMaxExpr(RHS, Start);