aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp47
1 files changed, 28 insertions, 19 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 29fd9ff..4f4f040 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -9101,9 +9101,7 @@ ScalarEvolution::computeExitLimitFromICmp(const Loop *L,
bool ControllingFiniteLoop =
ControlsExit && loopHasNoAbnormalExits(L) && loopIsFiniteByAssumption(L);
// Simplify the operands before analyzing them.
- (void)SimplifyICmpOperands(Pred, LHS, RHS, /*Depth=*/0,
- (EnableFiniteLoopControl ? ControllingFiniteLoop
- : false));
+ (void)SimplifyICmpOperands(Pred, LHS, RHS, /*Depth=*/0);
// If we have a comparison of a chrec against a constant, try to use value
// ranges to answer this query.
@@ -9176,17 +9174,35 @@ ScalarEvolution::computeExitLimitFromICmp(const Loop *L,
if (EL.hasAnyInfo()) return EL;
break;
}
+ case ICmpInst::ICMP_SLE:
+ case ICmpInst::ICMP_ULE:
+ // Since the loop is finite, an invariant RHS cannot include the boundary
+ // value, otherwise it would loop forever.
+ if (!EnableFiniteLoopControl || !ControllingFiniteLoop ||
+ !isLoopInvariant(RHS, L))
+ break;
+ RHS = getAddExpr(getOne(RHS->getType()), RHS);
+ [[fallthrough]];
case ICmpInst::ICMP_SLT:
case ICmpInst::ICMP_ULT: { // while (X < Y)
- bool IsSigned = Pred == ICmpInst::ICMP_SLT;
+ bool IsSigned = ICmpInst::isSigned(Pred);
ExitLimit EL = howManyLessThans(LHS, RHS, L, IsSigned, ControlsExit,
AllowPredicates);
if (EL.hasAnyInfo()) return EL;
break;
}
+ case ICmpInst::ICMP_SGE:
+ case ICmpInst::ICMP_UGE:
+ // Since the loop is finite, an invariant RHS cannot include the boundary
+ // value, otherwise it would loop forever.
+ if (!EnableFiniteLoopControl || !ControllingFiniteLoop ||
+ !isLoopInvariant(RHS, L))
+ break;
+ RHS = getAddExpr(getMinusOne(RHS->getType()), RHS);
+ [[fallthrough]];
case ICmpInst::ICMP_SGT:
case ICmpInst::ICMP_UGT: { // while (X > Y)
- bool IsSigned = Pred == ICmpInst::ICMP_SGT;
+ bool IsSigned = ICmpInst::isSigned(Pred);
ExitLimit EL =
howManyGreaterThans(LHS, RHS, L, IsSigned, ControlsExit,
AllowPredicates);
@@ -10582,8 +10598,7 @@ static bool HasSameValue(const SCEV *A, const SCEV *B) {
bool ScalarEvolution::SimplifyICmpOperands(ICmpInst::Predicate &Pred,
const SCEV *&LHS, const SCEV *&RHS,
- unsigned Depth,
- bool ControllingFiniteLoop) {
+ unsigned Depth) {
bool Changed = false;
// Simplifies ICMP to trivial true or false by turning it into '0 == 0' or
// '0 != 0'.
@@ -10712,15 +10727,10 @@ bool ScalarEvolution::SimplifyICmpOperands(ICmpInst::Predicate &Pred,
}
// If possible, canonicalize GE/LE comparisons to GT/LT comparisons, by
- // adding or subtracting 1 from one of the operands. This can be done for
- // one of two reasons:
- // 1) The range of the RHS does not include the (signed/unsigned) boundaries
- // 2) The loop is finite, with this comparison controlling the exit. Since the
- // loop is finite, the bound cannot include the corresponding boundary
- // (otherwise it would loop forever).
+ // adding or subtracting 1 from one of the operands.
switch (Pred) {
case ICmpInst::ICMP_SLE:
- if (ControllingFiniteLoop || !getSignedRangeMax(RHS).isMaxSignedValue()) {
+ if (!getSignedRangeMax(RHS).isMaxSignedValue()) {
RHS = getAddExpr(getConstant(RHS->getType(), 1, true), RHS,
SCEV::FlagNSW);
Pred = ICmpInst::ICMP_SLT;
@@ -10733,7 +10743,7 @@ bool ScalarEvolution::SimplifyICmpOperands(ICmpInst::Predicate &Pred,
}
break;
case ICmpInst::ICMP_SGE:
- if (ControllingFiniteLoop || !getSignedRangeMin(RHS).isMinSignedValue()) {
+ if (!getSignedRangeMin(RHS).isMinSignedValue()) {
RHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), RHS,
SCEV::FlagNSW);
Pred = ICmpInst::ICMP_SGT;
@@ -10746,7 +10756,7 @@ bool ScalarEvolution::SimplifyICmpOperands(ICmpInst::Predicate &Pred,
}
break;
case ICmpInst::ICMP_ULE:
- if (ControllingFiniteLoop || !getUnsignedRangeMax(RHS).isMaxValue()) {
+ if (!getUnsignedRangeMax(RHS).isMaxValue()) {
RHS = getAddExpr(getConstant(RHS->getType(), 1, true), RHS,
SCEV::FlagNUW);
Pred = ICmpInst::ICMP_ULT;
@@ -10758,7 +10768,7 @@ bool ScalarEvolution::SimplifyICmpOperands(ICmpInst::Predicate &Pred,
}
break;
case ICmpInst::ICMP_UGE:
- if (ControllingFiniteLoop || !getUnsignedRangeMin(RHS).isMinValue()) {
+ if (!getUnsignedRangeMin(RHS).isMinValue()) {
RHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), RHS);
Pred = ICmpInst::ICMP_UGT;
Changed = true;
@@ -10778,8 +10788,7 @@ bool ScalarEvolution::SimplifyICmpOperands(ICmpInst::Predicate &Pred,
// Recursively simplify until we either hit a recursion limit or nothing
// changes.
if (Changed)
- return SimplifyICmpOperands(Pred, LHS, RHS, Depth + 1,
- ControllingFiniteLoop);
+ return SimplifyICmpOperands(Pred, LHS, RHS, Depth + 1);
return Changed;
}