mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 10:16:07 +00:00
SCEV: migrate to CmpPredicate (NFC) (#122907)
In preparation to teach implied-cond functions about samesign, migrate integer-compare predicates that flow through to the functions from CmpInst::Predicate to CmpPredicate.
This commit is contained in:
parent
48757e02ba
commit
60dc450078
@ -776,18 +776,17 @@ public:
|
||||
/// Test whether entry to the loop is protected by a conditional between LHS
|
||||
/// and RHS. This is used to help avoid max expressions in loop trip
|
||||
/// counts, and to eliminate casts.
|
||||
bool isLoopEntryGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
|
||||
bool isLoopEntryGuardedByCond(const Loop *L, CmpPredicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS);
|
||||
|
||||
/// Test whether entry to the basic block is protected by a conditional
|
||||
/// between LHS and RHS.
|
||||
bool isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
|
||||
ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS);
|
||||
bool isBasicBlockEntryGuardedByCond(const BasicBlock *BB, CmpPredicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS);
|
||||
|
||||
/// Test whether the backedge of the loop is protected by a conditional
|
||||
/// between LHS and RHS. This is used to eliminate casts.
|
||||
bool isLoopBackedgeGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
|
||||
bool isLoopBackedgeGuardedByCond(const Loop *L, CmpPredicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS);
|
||||
|
||||
/// A version of getTripCountFromExitCount below which always picks an
|
||||
@ -1082,36 +1081,34 @@ public:
|
||||
/// so we can assert on that.
|
||||
/// e. Return true if isLoopEntryGuardedByCond(Pred, E(LHS), E(RHS)) &&
|
||||
/// isLoopBackedgeGuardedByCond(Pred, B(LHS), B(RHS))
|
||||
bool isKnownViaInduction(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS);
|
||||
bool isKnownViaInduction(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS);
|
||||
|
||||
/// Test if the given expression is known to satisfy the condition described
|
||||
/// by Pred, LHS, and RHS.
|
||||
bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS);
|
||||
bool isKnownPredicate(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS);
|
||||
|
||||
/// Check whether the condition described by Pred, LHS, and RHS is true or
|
||||
/// false. If we know it, return the evaluation of this condition. If neither
|
||||
/// is proved, return std::nullopt.
|
||||
std::optional<bool> evaluatePredicate(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS);
|
||||
std::optional<bool> evaluatePredicate(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS);
|
||||
|
||||
/// Test if the given expression is known to satisfy the condition described
|
||||
/// by Pred, LHS, and RHS in the given Context.
|
||||
bool isKnownPredicateAt(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS, const Instruction *CtxI);
|
||||
bool isKnownPredicateAt(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS,
|
||||
const Instruction *CtxI);
|
||||
|
||||
/// Check whether the condition described by Pred, LHS, and RHS is true or
|
||||
/// false in the given \p Context. If we know it, return the evaluation of
|
||||
/// this condition. If neither is proved, return std::nullopt.
|
||||
std::optional<bool> evaluatePredicateAt(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS,
|
||||
std::optional<bool> evaluatePredicateAt(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS,
|
||||
const Instruction *CtxI);
|
||||
|
||||
/// 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);
|
||||
bool isKnownOnEveryIteration(CmpPredicate Pred, const SCEVAddRecExpr *LHS,
|
||||
const SCEV *RHS);
|
||||
|
||||
/// Information about the number of loop iterations for which a loop exit's
|
||||
/// branch condition evaluates to the not-taken path. This is a temporary
|
||||
@ -1213,7 +1210,7 @@ public:
|
||||
/// available at L's entry. Otherwise, return std::nullopt. The predicate
|
||||
/// should be the loop's exit condition.
|
||||
std::optional<LoopInvariantPredicate>
|
||||
getLoopInvariantExitCondDuringFirstIterations(ICmpInst::Predicate Pred,
|
||||
getLoopInvariantExitCondDuringFirstIterations(CmpPredicate Pred,
|
||||
const SCEV *LHS,
|
||||
const SCEV *RHS, const Loop *L,
|
||||
const Instruction *CtxI,
|
||||
@ -1221,14 +1218,14 @@ public:
|
||||
|
||||
std::optional<LoopInvariantPredicate>
|
||||
getLoopInvariantExitCondDuringFirstIterationsImpl(
|
||||
ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
|
||||
CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
|
||||
const Instruction *CtxI, const SCEV *MaxIter);
|
||||
|
||||
/// Simplify LHS and RHS in a comparison with predicate Pred. Return true
|
||||
/// iff any changes were made. If the operands are provably equal or
|
||||
/// unequal, LHS and RHS are set to the same value and Pred is set to either
|
||||
/// ICMP_EQ or ICMP_NE.
|
||||
bool SimplifyICmpOperands(ICmpInst::Predicate &Pred, const SCEV *&LHS,
|
||||
bool SimplifyICmpOperands(CmpPredicate &Pred, const SCEV *&LHS,
|
||||
const SCEV *&RHS, unsigned Depth = 0);
|
||||
|
||||
/// Return the "disposition" of the given SCEV with respect to the given
|
||||
@ -1904,7 +1901,7 @@ private:
|
||||
/// as opposed to the ICmpInst itself. Note that the prior version can
|
||||
/// return more precise results in some cases and is preferred when caller
|
||||
/// has a materialized ICmp.
|
||||
ExitLimit computeExitLimitFromICmp(const Loop *L, ICmpInst::Predicate Pred,
|
||||
ExitLimit computeExitLimitFromICmp(const Loop *L, CmpPredicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS,
|
||||
bool IsSubExpr,
|
||||
bool AllowPredicates = false);
|
||||
@ -1977,7 +1974,7 @@ private:
|
||||
/// whenever the given FoundCondValue value evaluates to true in given
|
||||
/// Context. If Context is nullptr, then the found predicate is true
|
||||
/// everywhere. LHS and FoundLHS may have different type width.
|
||||
bool isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS,
|
||||
bool isImpliedCond(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS,
|
||||
const Value *FoundCondValue, bool Inverse,
|
||||
const Instruction *Context = nullptr);
|
||||
|
||||
@ -1985,9 +1982,8 @@ private:
|
||||
/// whenever the given FoundCondValue value evaluates to true in given
|
||||
/// Context. If Context is nullptr, then the found predicate is true
|
||||
/// everywhere. LHS and FoundLHS must have same type width.
|
||||
bool isImpliedCondBalancedTypes(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS,
|
||||
ICmpInst::Predicate FoundPred,
|
||||
bool isImpliedCondBalancedTypes(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS, CmpPredicate FoundPred,
|
||||
const SCEV *FoundLHS, const SCEV *FoundRHS,
|
||||
const Instruction *CtxI);
|
||||
|
||||
@ -1995,8 +1991,8 @@ private:
|
||||
/// whenever the condition described by FoundPred, FoundLHS, FoundRHS is
|
||||
/// true in given Context. If Context is nullptr, then the found predicate is
|
||||
/// true everywhere.
|
||||
bool isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS,
|
||||
ICmpInst::Predicate FoundPred, const SCEV *FoundLHS,
|
||||
bool isImpliedCond(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS,
|
||||
CmpPredicate FoundPred, const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS,
|
||||
const Instruction *Context = nullptr);
|
||||
|
||||
@ -2004,7 +2000,7 @@ private:
|
||||
/// whenever the condition described by Pred, FoundLHS, and FoundRHS is
|
||||
/// true in given Context. If Context is nullptr, then the found predicate is
|
||||
/// true everywhere.
|
||||
bool isImpliedCondOperands(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
bool isImpliedCondOperands(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS, const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS,
|
||||
const Instruction *Context = nullptr);
|
||||
@ -2013,20 +2009,19 @@ private:
|
||||
/// whenever the condition described by Pred, FoundLHS, and FoundRHS is
|
||||
/// true. Here LHS is an operation that includes FoundLHS as one of its
|
||||
/// arguments.
|
||||
bool isImpliedViaOperations(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS,
|
||||
const SCEV *FoundLHS, const SCEV *FoundRHS,
|
||||
unsigned Depth = 0);
|
||||
bool isImpliedViaOperations(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS, const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS, unsigned Depth = 0);
|
||||
|
||||
/// Test whether the condition described by Pred, LHS, and RHS is true.
|
||||
/// Use only simple non-recursive types of checks, such as range analysis etc.
|
||||
bool isKnownViaNonRecursiveReasoning(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS);
|
||||
bool isKnownViaNonRecursiveReasoning(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS);
|
||||
|
||||
/// Test whether the condition described by Pred, LHS, and RHS is true
|
||||
/// whenever the condition described by Pred, FoundLHS, and FoundRHS is
|
||||
/// true.
|
||||
bool isImpliedCondOperandsHelper(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
bool isImpliedCondOperandsHelper(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS, const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS);
|
||||
|
||||
@ -2034,15 +2029,14 @@ private:
|
||||
/// whenever the condition described by Pred, FoundLHS, and FoundRHS is
|
||||
/// true. Utility function used by isImpliedCondOperands. Tries to get
|
||||
/// cases like "X `sgt` 0 => X - 1 `sgt` -1".
|
||||
bool isImpliedCondOperandsViaRanges(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS,
|
||||
ICmpInst::Predicate FoundPred,
|
||||
bool isImpliedCondOperandsViaRanges(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS, CmpPredicate FoundPred,
|
||||
const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS);
|
||||
|
||||
/// Return true if the condition denoted by \p LHS \p Pred \p RHS is implied
|
||||
/// by a call to @llvm.experimental.guard in \p BB.
|
||||
bool isImpliedViaGuard(const BasicBlock *BB, ICmpInst::Predicate Pred,
|
||||
bool isImpliedViaGuard(const BasicBlock *BB, CmpPredicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS);
|
||||
|
||||
/// Test whether the condition described by Pred, LHS, and RHS is true
|
||||
@ -2051,9 +2045,8 @@ private:
|
||||
///
|
||||
/// This routine tries to rule out certain kinds of integer overflow, and
|
||||
/// then tries to reason about arithmetic properties of the predicates.
|
||||
bool isImpliedCondOperandsViaNoOverflow(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS,
|
||||
const SCEV *FoundLHS,
|
||||
bool isImpliedCondOperandsViaNoOverflow(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS, const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS);
|
||||
|
||||
/// Test whether the condition described by Pred, LHS, and RHS is true
|
||||
@ -2062,8 +2055,8 @@ private:
|
||||
///
|
||||
/// This routine tries to weaken the known condition basing on fact that
|
||||
/// FoundLHS is an AddRec.
|
||||
bool isImpliedCondOperandsViaAddRecStart(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS,
|
||||
bool isImpliedCondOperandsViaAddRecStart(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS,
|
||||
const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS,
|
||||
const Instruction *CtxI);
|
||||
@ -2075,8 +2068,7 @@ private:
|
||||
/// This routine tries to figure out predicate for Phis which are SCEVUnknown
|
||||
/// if it is true for every possible incoming value from their respective
|
||||
/// basic blocks.
|
||||
bool isImpliedViaMerge(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS,
|
||||
bool isImpliedViaMerge(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS,
|
||||
const SCEV *FoundLHS, const SCEV *FoundRHS,
|
||||
unsigned Depth);
|
||||
|
||||
@ -2085,7 +2077,7 @@ private:
|
||||
/// true.
|
||||
///
|
||||
/// This routine tries to reason about shifts.
|
||||
bool isImpliedCondOperandsViaShift(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
bool isImpliedCondOperandsViaShift(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS, const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS);
|
||||
|
||||
@ -2097,20 +2089,20 @@ private:
|
||||
|
||||
/// Test if the given expression is known to satisfy the condition described
|
||||
/// by Pred and the known constant ranges of LHS and RHS.
|
||||
bool isKnownPredicateViaConstantRanges(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS);
|
||||
bool isKnownPredicateViaConstantRanges(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS);
|
||||
|
||||
/// Try to prove the condition described by "LHS Pred RHS" by ruling out
|
||||
/// integer overflow.
|
||||
///
|
||||
/// For instance, this will return true for "A s< (A + C)<nsw>" if C is
|
||||
/// positive.
|
||||
bool isKnownPredicateViaNoOverflow(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
bool isKnownPredicateViaNoOverflow(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS);
|
||||
|
||||
/// Try to split Pred LHS RHS into logical conjunctions (and's) and try to
|
||||
/// prove them individually.
|
||||
bool isKnownPredicateViaSplitting(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
bool isKnownPredicateViaSplitting(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS);
|
||||
|
||||
/// Try to match the Expr as "(L + R)<Flags>".
|
||||
|
@ -9171,11 +9171,11 @@ ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimitFromICmp(
|
||||
const Loop *L, ICmpInst *ExitCond, bool ExitIfTrue, bool ControlsOnlyExit,
|
||||
bool AllowPredicates) {
|
||||
// If the condition was exit on true, convert the condition to exit on false
|
||||
ICmpInst::Predicate Pred;
|
||||
CmpPredicate Pred;
|
||||
if (!ExitIfTrue)
|
||||
Pred = ExitCond->getPredicate();
|
||||
Pred = ExitCond->getCmpPredicate();
|
||||
else
|
||||
Pred = ExitCond->getInversePredicate();
|
||||
Pred = ExitCond->getInverseCmpPredicate();
|
||||
const ICmpInst::Predicate OriginalPred = Pred;
|
||||
|
||||
const SCEV *LHS = getSCEV(ExitCond->getOperand(0));
|
||||
@ -9196,7 +9196,7 @@ ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimitFromICmp(
|
||||
ExitCond->getOperand(1), L, OriginalPred);
|
||||
}
|
||||
ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimitFromICmp(
|
||||
const Loop *L, ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS,
|
||||
const Loop *L, CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS,
|
||||
bool ControlsOnlyExit, bool AllowPredicates) {
|
||||
|
||||
// Try to evaluate any dependencies out of the loop.
|
||||
@ -9208,7 +9208,7 @@ ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimitFromICmp(
|
||||
if (isLoopInvariant(LHS, L) && !isLoopInvariant(RHS, L)) {
|
||||
// If there is a loop-invariant, force it into the RHS.
|
||||
std::swap(LHS, RHS);
|
||||
Pred = ICmpInst::getSwappedPredicate(Pred);
|
||||
Pred = ICmpInst::getSwappedCmpPredicate(Pred);
|
||||
}
|
||||
|
||||
bool ControllingFiniteLoop = ControlsOnlyExit && loopHasNoAbnormalExits(L) &&
|
||||
@ -10757,9 +10757,8 @@ static bool MatchBinarySub(const SCEV *S, const SCEV *&LHS, const SCEV *&RHS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScalarEvolution::SimplifyICmpOperands(ICmpInst::Predicate &Pred,
|
||||
const SCEV *&LHS, const SCEV *&RHS,
|
||||
unsigned Depth) {
|
||||
bool ScalarEvolution::SimplifyICmpOperands(CmpPredicate &Pred, const SCEV *&LHS,
|
||||
const SCEV *&RHS, unsigned Depth) {
|
||||
bool Changed = false;
|
||||
// Simplifies ICMP to trivial true or false by turning it into '0 == 0' or
|
||||
// '0 != 0'.
|
||||
@ -10782,7 +10781,7 @@ bool ScalarEvolution::SimplifyICmpOperands(ICmpInst::Predicate &Pred,
|
||||
}
|
||||
// Otherwise swap the operands to put the constant on the right.
|
||||
std::swap(LHS, RHS);
|
||||
Pred = ICmpInst::getSwappedPredicate(Pred);
|
||||
Pred = ICmpInst::getSwappedCmpPredicate(Pred);
|
||||
Changed = true;
|
||||
}
|
||||
|
||||
@ -10793,7 +10792,7 @@ bool ScalarEvolution::SimplifyICmpOperands(ICmpInst::Predicate &Pred,
|
||||
const Loop *L = AR->getLoop();
|
||||
if (isLoopInvariant(LHS, L) && properlyDominates(LHS, L->getHeader())) {
|
||||
std::swap(LHS, RHS);
|
||||
Pred = ICmpInst::getSwappedPredicate(Pred);
|
||||
Pred = ICmpInst::getSwappedCmpPredicate(Pred);
|
||||
Changed = true;
|
||||
}
|
||||
}
|
||||
@ -10998,8 +10997,8 @@ ScalarEvolution::SplitIntoInitAndPostInc(const Loop *L, const SCEV *S) {
|
||||
return { Start, PostInc };
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isKnownViaInduction(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS) {
|
||||
bool ScalarEvolution::isKnownViaInduction(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS) {
|
||||
// First collect all loops.
|
||||
SmallPtrSet<const Loop *, 8> LoopsUsed;
|
||||
getUsedLoops(LHS, LoopsUsed);
|
||||
@ -11048,8 +11047,8 @@ bool ScalarEvolution::isKnownViaInduction(ICmpInst::Predicate Pred,
|
||||
isLoopEntryGuardedByCond(MDL, Pred, SplitLHS.first, SplitRHS.first);
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isKnownPredicate(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS) {
|
||||
bool ScalarEvolution::isKnownPredicate(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS) {
|
||||
// Canonicalize the inputs first.
|
||||
(void)SimplifyICmpOperands(Pred, LHS, RHS);
|
||||
|
||||
@ -11063,18 +11062,18 @@ bool ScalarEvolution::isKnownPredicate(ICmpInst::Predicate Pred,
|
||||
return isKnownViaNonRecursiveReasoning(Pred, LHS, RHS);
|
||||
}
|
||||
|
||||
std::optional<bool> ScalarEvolution::evaluatePredicate(ICmpInst::Predicate Pred,
|
||||
std::optional<bool> ScalarEvolution::evaluatePredicate(CmpPredicate Pred,
|
||||
const SCEV *LHS,
|
||||
const SCEV *RHS) {
|
||||
if (isKnownPredicate(Pred, LHS, RHS))
|
||||
return true;
|
||||
if (isKnownPredicate(ICmpInst::getInversePredicate(Pred), LHS, RHS))
|
||||
if (isKnownPredicate(ICmpInst::getInverseCmpPredicate(Pred), LHS, RHS))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isKnownPredicateAt(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS,
|
||||
bool ScalarEvolution::isKnownPredicateAt(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS,
|
||||
const Instruction *CtxI) {
|
||||
// TODO: Analyze guards and assumes from Context's block.
|
||||
return isKnownPredicate(Pred, LHS, RHS) ||
|
||||
@ -11082,7 +11081,7 @@ bool ScalarEvolution::isKnownPredicateAt(ICmpInst::Predicate Pred,
|
||||
}
|
||||
|
||||
std::optional<bool>
|
||||
ScalarEvolution::evaluatePredicateAt(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
ScalarEvolution::evaluatePredicateAt(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS, const Instruction *CtxI) {
|
||||
std::optional<bool> KnownWithoutContext = evaluatePredicate(Pred, LHS, RHS);
|
||||
if (KnownWithoutContext)
|
||||
@ -11090,14 +11089,13 @@ ScalarEvolution::evaluatePredicateAt(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
|
||||
if (isBasicBlockEntryGuardedByCond(CtxI->getParent(), Pred, LHS, RHS))
|
||||
return true;
|
||||
if (isBasicBlockEntryGuardedByCond(CtxI->getParent(),
|
||||
ICmpInst::getInversePredicate(Pred),
|
||||
LHS, RHS))
|
||||
if (isBasicBlockEntryGuardedByCond(
|
||||
CtxI->getParent(), ICmpInst::getInverseCmpPredicate(Pred), LHS, RHS))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isKnownOnEveryIteration(ICmpInst::Predicate Pred,
|
||||
bool ScalarEvolution::isKnownOnEveryIteration(CmpPredicate Pred,
|
||||
const SCEVAddRecExpr *LHS,
|
||||
const SCEV *RHS) {
|
||||
const Loop *L = LHS->getLoop();
|
||||
@ -11256,7 +11254,7 @@ ScalarEvolution::getLoopInvariantPredicate(ICmpInst::Predicate Pred,
|
||||
|
||||
std::optional<ScalarEvolution::LoopInvariantPredicate>
|
||||
ScalarEvolution::getLoopInvariantExitCondDuringFirstIterations(
|
||||
ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
|
||||
CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
|
||||
const Instruction *CtxI, const SCEV *MaxIter) {
|
||||
if (auto LIP = getLoopInvariantExitCondDuringFirstIterationsImpl(
|
||||
Pred, LHS, RHS, L, CtxI, MaxIter))
|
||||
@ -11276,7 +11274,7 @@ ScalarEvolution::getLoopInvariantExitCondDuringFirstIterations(
|
||||
|
||||
std::optional<ScalarEvolution::LoopInvariantPredicate>
|
||||
ScalarEvolution::getLoopInvariantExitCondDuringFirstIterationsImpl(
|
||||
ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
|
||||
CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
|
||||
const Instruction *CtxI, const SCEV *MaxIter) {
|
||||
// Try to prove the following set of facts:
|
||||
// - The predicate is monotonic in the iteration space.
|
||||
@ -11292,7 +11290,7 @@ ScalarEvolution::getLoopInvariantExitCondDuringFirstIterationsImpl(
|
||||
return std::nullopt;
|
||||
|
||||
std::swap(LHS, RHS);
|
||||
Pred = ICmpInst::getSwappedPredicate(Pred);
|
||||
Pred = ICmpInst::getSwappedCmpPredicate(Pred);
|
||||
}
|
||||
|
||||
auto *AR = dyn_cast<SCEVAddRecExpr>(LHS);
|
||||
@ -11329,7 +11327,7 @@ ScalarEvolution::getLoopInvariantExitCondDuringFirstIterationsImpl(
|
||||
ICmpInst::Predicate NoOverflowPred =
|
||||
CmpInst::isSigned(Pred) ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
|
||||
if (Step == MinusOne)
|
||||
NoOverflowPred = CmpInst::getSwappedPredicate(NoOverflowPred);
|
||||
NoOverflowPred = ICmpInst::getSwappedCmpPredicate(NoOverflowPred);
|
||||
const SCEV *Start = AR->getStart();
|
||||
if (!isKnownPredicateAt(NoOverflowPred, Start, Last, CtxI))
|
||||
return std::nullopt;
|
||||
@ -11338,8 +11336,9 @@ ScalarEvolution::getLoopInvariantExitCondDuringFirstIterationsImpl(
|
||||
return ScalarEvolution::LoopInvariantPredicate(Pred, Start, RHS);
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isKnownPredicateViaConstantRanges(
|
||||
ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS) {
|
||||
bool ScalarEvolution::isKnownPredicateViaConstantRanges(CmpPredicate Pred,
|
||||
const SCEV *LHS,
|
||||
const SCEV *RHS) {
|
||||
if (HasSameValue(LHS, RHS))
|
||||
return ICmpInst::isTrueWhenEqual(Pred);
|
||||
|
||||
@ -11380,7 +11379,7 @@ bool ScalarEvolution::isKnownPredicateViaConstantRanges(
|
||||
return CheckRanges(UL, UR);
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isKnownPredicateViaNoOverflow(ICmpInst::Predicate Pred,
|
||||
bool ScalarEvolution::isKnownPredicateViaNoOverflow(CmpPredicate Pred,
|
||||
const SCEV *LHS,
|
||||
const SCEV *RHS) {
|
||||
// Match X to (A + C1)<ExpectedFlags> and Y to (A + C2)<ExpectedFlags>, where
|
||||
@ -11473,7 +11472,7 @@ bool ScalarEvolution::isKnownPredicateViaNoOverflow(ICmpInst::Predicate Pred,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isKnownPredicateViaSplitting(ICmpInst::Predicate Pred,
|
||||
bool ScalarEvolution::isKnownPredicateViaSplitting(CmpPredicate Pred,
|
||||
const SCEV *LHS,
|
||||
const SCEV *RHS) {
|
||||
if (Pred != ICmpInst::ICMP_ULT || ProvingSplitPredicate)
|
||||
@ -11495,8 +11494,7 @@ bool ScalarEvolution::isKnownPredicateViaSplitting(ICmpInst::Predicate Pred,
|
||||
isKnownPredicate(CmpInst::ICMP_SLT, LHS, RHS);
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isImpliedViaGuard(const BasicBlock *BB,
|
||||
ICmpInst::Predicate Pred,
|
||||
bool ScalarEvolution::isImpliedViaGuard(const BasicBlock *BB, CmpPredicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS) {
|
||||
// No need to even try if we know the module has no guards.
|
||||
if (!HasGuards)
|
||||
@ -11515,10 +11513,10 @@ bool ScalarEvolution::isImpliedViaGuard(const BasicBlock *BB,
|
||||
/// isLoopBackedgeGuardedByCond - Test whether the backedge of the loop is
|
||||
/// protected by a conditional between LHS and RHS. This is used to
|
||||
/// to eliminate casts.
|
||||
bool
|
||||
ScalarEvolution::isLoopBackedgeGuardedByCond(const Loop *L,
|
||||
ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS) {
|
||||
bool ScalarEvolution::isLoopBackedgeGuardedByCond(const Loop *L,
|
||||
CmpPredicate Pred,
|
||||
const SCEV *LHS,
|
||||
const SCEV *RHS) {
|
||||
// Interpret a null as meaning no loop, where there is obviously no guard
|
||||
// (interprocedural conditions notwithstanding). Do not bother about
|
||||
// unreachable loops.
|
||||
@ -11622,7 +11620,7 @@ ScalarEvolution::isLoopBackedgeGuardedByCond(const Loop *L,
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
|
||||
ICmpInst::Predicate Pred,
|
||||
CmpPredicate Pred,
|
||||
const SCEV *LHS,
|
||||
const SCEV *RHS) {
|
||||
// Do not bother proving facts for unreachable code.
|
||||
@ -11642,8 +11640,7 @@ bool ScalarEvolution::isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
|
||||
bool ProvedNonStrictComparison = false;
|
||||
bool ProvedNonEquality = false;
|
||||
|
||||
auto SplitAndProve =
|
||||
[&](std::function<bool(ICmpInst::Predicate)> Fn) -> bool {
|
||||
auto SplitAndProve = [&](std::function<bool(CmpPredicate)> Fn) -> bool {
|
||||
if (!ProvedNonStrictComparison)
|
||||
ProvedNonStrictComparison = Fn(NonStrictPredicate);
|
||||
if (!ProvedNonEquality)
|
||||
@ -11654,7 +11651,7 @@ bool ScalarEvolution::isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
|
||||
};
|
||||
|
||||
if (ProvingStrictComparison) {
|
||||
auto ProofFn = [&](ICmpInst::Predicate P) {
|
||||
auto ProofFn = [&](CmpPredicate P) {
|
||||
return isKnownViaNonRecursiveReasoning(P, LHS, RHS);
|
||||
};
|
||||
if (SplitAndProve(ProofFn))
|
||||
@ -11667,7 +11664,7 @@ bool ScalarEvolution::isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
|
||||
if (isImpliedCond(Pred, LHS, RHS, Condition, Inverse, CtxI))
|
||||
return true;
|
||||
if (ProvingStrictComparison) {
|
||||
auto ProofFn = [&](ICmpInst::Predicate P) {
|
||||
auto ProofFn = [&](CmpPredicate P) {
|
||||
return isImpliedCond(P, LHS, RHS, Condition, Inverse, CtxI);
|
||||
};
|
||||
if (SplitAndProve(ProofFn))
|
||||
@ -11721,8 +11718,7 @@ bool ScalarEvolution::isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L,
|
||||
ICmpInst::Predicate Pred,
|
||||
bool ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L, CmpPredicate Pred,
|
||||
const SCEV *LHS,
|
||||
const SCEV *RHS) {
|
||||
// Interpret a null as meaning no loop, where there is obviously no guard
|
||||
@ -11742,7 +11738,7 @@ bool ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L,
|
||||
return isBasicBlockEntryGuardedByCond(L->getHeader(), Pred, LHS, RHS);
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
bool ScalarEvolution::isImpliedCond(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS,
|
||||
const Value *FoundCondValue, bool Inverse,
|
||||
const Instruction *CtxI) {
|
||||
@ -11774,11 +11770,11 @@ bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
|
||||
// Now that we found a conditional branch that dominates the loop or controls
|
||||
// the loop latch. Check to see if it is the comparison we are looking for.
|
||||
ICmpInst::Predicate FoundPred;
|
||||
CmpPredicate FoundPred;
|
||||
if (Inverse)
|
||||
FoundPred = ICI->getInversePredicate();
|
||||
FoundPred = ICI->getInverseCmpPredicate();
|
||||
else
|
||||
FoundPred = ICI->getPredicate();
|
||||
FoundPred = ICI->getCmpPredicate();
|
||||
|
||||
const SCEV *FoundLHS = getSCEV(ICI->getOperand(0));
|
||||
const SCEV *FoundRHS = getSCEV(ICI->getOperand(1));
|
||||
@ -11786,9 +11782,8 @@ bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
return isImpliedCond(Pred, LHS, RHS, FoundPred, FoundLHS, FoundRHS, CtxI);
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS,
|
||||
ICmpInst::Predicate FoundPred,
|
||||
bool ScalarEvolution::isImpliedCond(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS, CmpPredicate FoundPred,
|
||||
const SCEV *FoundLHS, const SCEV *FoundRHS,
|
||||
const Instruction *CtxI) {
|
||||
// Balance the types.
|
||||
@ -11842,9 +11837,8 @@ bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isImpliedCondBalancedTypes(
|
||||
ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS,
|
||||
ICmpInst::Predicate FoundPred, const SCEV *FoundLHS, const SCEV *FoundRHS,
|
||||
const Instruction *CtxI) {
|
||||
CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS, CmpPredicate FoundPred,
|
||||
const SCEV *FoundLHS, const SCEV *FoundRHS, const Instruction *CtxI) {
|
||||
assert(getTypeSizeInBits(LHS->getType()) ==
|
||||
getTypeSizeInBits(FoundLHS->getType()) &&
|
||||
"Types should be balanced!");
|
||||
@ -11861,20 +11855,23 @@ bool ScalarEvolution::isImpliedCondBalancedTypes(
|
||||
if (LHS == FoundRHS || RHS == FoundLHS) {
|
||||
if (isa<SCEVConstant>(RHS)) {
|
||||
std::swap(FoundLHS, FoundRHS);
|
||||
FoundPred = ICmpInst::getSwappedPredicate(FoundPred);
|
||||
FoundPred = ICmpInst::getSwappedCmpPredicate(FoundPred);
|
||||
} else {
|
||||
std::swap(LHS, RHS);
|
||||
Pred = ICmpInst::getSwappedPredicate(Pred);
|
||||
Pred = ICmpInst::getSwappedCmpPredicate(Pred);
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether the found predicate is the same as the desired predicate.
|
||||
if (FoundPred == Pred)
|
||||
// FIXME: use CmpPredicate::getMatching here.
|
||||
if (FoundPred == static_cast<CmpInst::Predicate>(Pred))
|
||||
return isImpliedCondOperands(Pred, LHS, RHS, FoundLHS, FoundRHS, CtxI);
|
||||
|
||||
// Check whether swapping the found predicate makes it the same as the
|
||||
// desired predicate.
|
||||
if (ICmpInst::getSwappedPredicate(FoundPred) == Pred) {
|
||||
// FIXME: use CmpPredicate::getMatching here.
|
||||
if (ICmpInst::getSwappedCmpPredicate(FoundPred) ==
|
||||
static_cast<CmpInst::Predicate>(Pred)) {
|
||||
// We can write the implication
|
||||
// 0. LHS Pred RHS <- FoundLHS SwapPred FoundRHS
|
||||
// using one of the following ways:
|
||||
@ -11921,12 +11918,12 @@ bool ScalarEvolution::isImpliedCondBalancedTypes(
|
||||
return isImpliedCondOperands(Pred, LHS, RHS, FoundLHS, FoundRHS, CtxI);
|
||||
// Create local copies that we can freely swap and canonicalize our
|
||||
// conditions to "le/lt".
|
||||
ICmpInst::Predicate CanonicalPred = Pred, CanonicalFoundPred = FoundPred;
|
||||
CmpPredicate CanonicalPred = Pred, CanonicalFoundPred = FoundPred;
|
||||
const SCEV *CanonicalLHS = LHS, *CanonicalRHS = RHS,
|
||||
*CanonicalFoundLHS = FoundLHS, *CanonicalFoundRHS = FoundRHS;
|
||||
if (ICmpInst::isGT(CanonicalPred) || ICmpInst::isGE(CanonicalPred)) {
|
||||
CanonicalPred = ICmpInst::getSwappedPredicate(CanonicalPred);
|
||||
CanonicalFoundPred = ICmpInst::getSwappedPredicate(CanonicalFoundPred);
|
||||
CanonicalPred = ICmpInst::getSwappedCmpPredicate(CanonicalPred);
|
||||
CanonicalFoundPred = ICmpInst::getSwappedCmpPredicate(CanonicalFoundPred);
|
||||
std::swap(CanonicalLHS, CanonicalRHS);
|
||||
std::swap(CanonicalFoundLHS, CanonicalFoundRHS);
|
||||
}
|
||||
@ -12009,14 +12006,14 @@ bool ScalarEvolution::isImpliedCondBalancedTypes(
|
||||
// `LHS < RHS` and `LHS <= RHS` are handled in the same way as `RHS > LHS` and `RHS >= LHS` respectively.
|
||||
case ICmpInst::ICMP_SLE:
|
||||
case ICmpInst::ICMP_ULE:
|
||||
if (isImpliedCondOperands(CmpInst::getSwappedPredicate(Pred), RHS,
|
||||
if (isImpliedCondOperands(ICmpInst::getSwappedCmpPredicate(Pred), RHS,
|
||||
LHS, V, getConstant(SharperMin), CtxI))
|
||||
return true;
|
||||
[[fallthrough]];
|
||||
|
||||
case ICmpInst::ICMP_SLT:
|
||||
case ICmpInst::ICMP_ULT:
|
||||
if (isImpliedCondOperands(CmpInst::getSwappedPredicate(Pred), RHS,
|
||||
if (isImpliedCondOperands(ICmpInst::getSwappedCmpPredicate(Pred), RHS,
|
||||
LHS, V, getConstant(Min), CtxI))
|
||||
return true;
|
||||
break;
|
||||
@ -12176,8 +12173,8 @@ ScalarEvolution::computeConstantDifference(const SCEV *More, const SCEV *Less) {
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isImpliedCondOperandsViaAddRecStart(
|
||||
ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS,
|
||||
const SCEV *FoundLHS, const SCEV *FoundRHS, const Instruction *CtxI) {
|
||||
CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS, const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS, const Instruction *CtxI) {
|
||||
// Try to recognize the following pattern:
|
||||
//
|
||||
// FoundRHS = ...
|
||||
@ -12220,9 +12217,11 @@ bool ScalarEvolution::isImpliedCondOperandsViaAddRecStart(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isImpliedCondOperandsViaNoOverflow(
|
||||
ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS,
|
||||
const SCEV *FoundLHS, const SCEV *FoundRHS) {
|
||||
bool ScalarEvolution::isImpliedCondOperandsViaNoOverflow(CmpPredicate Pred,
|
||||
const SCEV *LHS,
|
||||
const SCEV *RHS,
|
||||
const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS) {
|
||||
if (Pred != CmpInst::ICMP_SLT && Pred != CmpInst::ICMP_ULT)
|
||||
return false;
|
||||
|
||||
@ -12299,9 +12298,8 @@ bool ScalarEvolution::isImpliedCondOperandsViaNoOverflow(
|
||||
getConstant(FoundRHSLimit));
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isImpliedViaMerge(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS,
|
||||
const SCEV *FoundLHS,
|
||||
bool ScalarEvolution::isImpliedViaMerge(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS, const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS, unsigned Depth) {
|
||||
const PHINode *LPhi = nullptr, *RPhi = nullptr;
|
||||
|
||||
@ -12349,7 +12347,7 @@ bool ScalarEvolution::isImpliedViaMerge(ICmpInst::Predicate Pred,
|
||||
std::swap(LHS, RHS);
|
||||
std::swap(FoundLHS, FoundRHS);
|
||||
std::swap(LPhi, RPhi);
|
||||
Pred = ICmpInst::getSwappedPredicate(Pred);
|
||||
Pred = ICmpInst::getSwappedCmpPredicate(Pred);
|
||||
}
|
||||
|
||||
assert(LPhi && "LPhi should definitely be a SCEVUnknown Phi!");
|
||||
@ -12413,7 +12411,7 @@ bool ScalarEvolution::isImpliedViaMerge(ICmpInst::Predicate Pred,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isImpliedCondOperandsViaShift(ICmpInst::Predicate Pred,
|
||||
bool ScalarEvolution::isImpliedCondOperandsViaShift(CmpPredicate Pred,
|
||||
const SCEV *LHS,
|
||||
const SCEV *RHS,
|
||||
const SCEV *FoundLHS,
|
||||
@ -12423,7 +12421,7 @@ bool ScalarEvolution::isImpliedCondOperandsViaShift(ICmpInst::Predicate Pred,
|
||||
if (RHS == FoundRHS) {
|
||||
std::swap(LHS, RHS);
|
||||
std::swap(FoundLHS, FoundRHS);
|
||||
Pred = ICmpInst::getSwappedPredicate(Pred);
|
||||
Pred = ICmpInst::getSwappedCmpPredicate(Pred);
|
||||
}
|
||||
if (LHS != FoundLHS)
|
||||
return false;
|
||||
@ -12455,8 +12453,8 @@ bool ScalarEvolution::isImpliedCondOperandsViaShift(ICmpInst::Predicate Pred,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isImpliedCondOperands(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS,
|
||||
bool ScalarEvolution::isImpliedCondOperands(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS,
|
||||
const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS,
|
||||
const Instruction *CtxI) {
|
||||
@ -12489,8 +12487,8 @@ static bool IsMinMaxConsistingOf(const SCEV *MaybeMinMaxExpr,
|
||||
}
|
||||
|
||||
static bool IsKnownPredicateViaAddRecStart(ScalarEvolution &SE,
|
||||
ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS) {
|
||||
CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS) {
|
||||
// If both sides are affine addrecs for the same loop, with equal
|
||||
// steps, and we know the recurrences don't wrap, then we only
|
||||
// need to check the predicate on the starting values.
|
||||
@ -12522,8 +12520,7 @@ static bool IsKnownPredicateViaAddRecStart(ScalarEvolution &SE,
|
||||
|
||||
/// Is LHS `Pred` RHS true on the virtue of LHS or RHS being a Min or Max
|
||||
/// expression?
|
||||
static bool IsKnownPredicateViaMinOrMax(ScalarEvolution &SE,
|
||||
ICmpInst::Predicate Pred,
|
||||
static bool IsKnownPredicateViaMinOrMax(ScalarEvolution &SE, CmpPredicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS) {
|
||||
switch (Pred) {
|
||||
default:
|
||||
@ -12554,8 +12551,8 @@ static bool IsKnownPredicateViaMinOrMax(ScalarEvolution &SE,
|
||||
llvm_unreachable("covered switch fell through?!");
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isImpliedViaOperations(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS,
|
||||
bool ScalarEvolution::isImpliedViaOperations(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS,
|
||||
const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS,
|
||||
unsigned Depth) {
|
||||
@ -12571,7 +12568,7 @@ bool ScalarEvolution::isImpliedViaOperations(ICmpInst::Predicate Pred,
|
||||
|
||||
// We only want to work with GT comparison so far.
|
||||
if (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_SLT) {
|
||||
Pred = CmpInst::getSwappedPredicate(Pred);
|
||||
Pred = ICmpInst::getSwappedCmpPredicate(Pred);
|
||||
std::swap(LHS, RHS);
|
||||
std::swap(FoundLHS, FoundRHS);
|
||||
}
|
||||
@ -12722,8 +12719,8 @@ bool ScalarEvolution::isImpliedViaOperations(ICmpInst::Predicate Pred,
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isKnownPredicateExtendIdiom(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS) {
|
||||
static bool isKnownPredicateExtendIdiom(CmpPredicate Pred, const SCEV *LHS,
|
||||
const SCEV *RHS) {
|
||||
// zext x u<= sext x, sext x s<= zext x
|
||||
const SCEV *Op;
|
||||
switch (Pred) {
|
||||
@ -12749,9 +12746,9 @@ static bool isKnownPredicateExtendIdiom(ICmpInst::Predicate Pred,
|
||||
llvm_unreachable("unhandled case");
|
||||
}
|
||||
|
||||
bool
|
||||
ScalarEvolution::isKnownViaNonRecursiveReasoning(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS) {
|
||||
bool ScalarEvolution::isKnownViaNonRecursiveReasoning(CmpPredicate Pred,
|
||||
const SCEV *LHS,
|
||||
const SCEV *RHS) {
|
||||
return isKnownPredicateExtendIdiom(Pred, LHS, RHS) ||
|
||||
isKnownPredicateViaConstantRanges(Pred, LHS, RHS) ||
|
||||
IsKnownPredicateViaMinOrMax(*this, Pred, LHS, RHS) ||
|
||||
@ -12759,13 +12756,14 @@ ScalarEvolution::isKnownViaNonRecursiveReasoning(ICmpInst::Predicate Pred,
|
||||
isKnownPredicateViaNoOverflow(Pred, LHS, RHS);
|
||||
}
|
||||
|
||||
bool
|
||||
ScalarEvolution::isImpliedCondOperandsHelper(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS,
|
||||
const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS) {
|
||||
bool ScalarEvolution::isImpliedCondOperandsHelper(CmpPredicate Pred,
|
||||
const SCEV *LHS,
|
||||
const SCEV *RHS,
|
||||
const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS) {
|
||||
switch (Pred) {
|
||||
default: llvm_unreachable("Unexpected ICmpInst::Predicate value!");
|
||||
default:
|
||||
llvm_unreachable("Unexpected CmpPredicate value!");
|
||||
case ICmpInst::ICMP_EQ:
|
||||
case ICmpInst::ICMP_NE:
|
||||
if (HasSameValue(LHS, FoundLHS) && HasSameValue(RHS, FoundRHS))
|
||||
@ -12804,12 +12802,9 @@ ScalarEvolution::isImpliedCondOperandsHelper(ICmpInst::Predicate Pred,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScalarEvolution::isImpliedCondOperandsViaRanges(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS,
|
||||
const SCEV *RHS,
|
||||
ICmpInst::Predicate FoundPred,
|
||||
const SCEV *FoundLHS,
|
||||
const SCEV *FoundRHS) {
|
||||
bool ScalarEvolution::isImpliedCondOperandsViaRanges(
|
||||
CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS, CmpPredicate FoundPred,
|
||||
const SCEV *FoundLHS, const SCEV *FoundRHS) {
|
||||
if (!isa<SCEVConstant>(RHS) || !isa<SCEVConstant>(FoundRHS))
|
||||
// The restriction on `FoundRHS` be lifted easily -- it exists only to
|
||||
// reduce the compile time impact of this optimization.
|
||||
@ -14338,11 +14333,11 @@ void ScalarEvolution::getReachableBlocks(
|
||||
if (auto *Cmp = dyn_cast<ICmpInst>(Cond)) {
|
||||
const SCEV *L = getSCEV(Cmp->getOperand(0));
|
||||
const SCEV *R = getSCEV(Cmp->getOperand(1));
|
||||
if (isKnownPredicateViaConstantRanges(Cmp->getPredicate(), L, R)) {
|
||||
if (isKnownPredicateViaConstantRanges(Cmp->getCmpPredicate(), L, R)) {
|
||||
Worklist.push_back(TrueBB);
|
||||
continue;
|
||||
}
|
||||
if (isKnownPredicateViaConstantRanges(Cmp->getInversePredicate(), L,
|
||||
if (isKnownPredicateViaConstantRanges(Cmp->getInverseCmpPredicate(), L,
|
||||
R)) {
|
||||
Worklist.push_back(FalseBB);
|
||||
continue;
|
||||
|
Loading…
x
Reference in New Issue
Block a user