diff options
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 47 |
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; } |