Skip to content

Commit

Permalink
SCEV: migrate to CmpPredicate (NFC) (llvm#122907)
Browse files Browse the repository at this point in the history
In preparation to teach implied-cond functions about samesign, migrate
integer-compare predicates that flow through to the functions from
CmpInst::Predicate to CmpPredicate.
  • Loading branch information
artagnon authored Jan 14, 2025
1 parent 48757e0 commit 60dc450
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 153 deletions.
94 changes: 43 additions & 51 deletions llvm/include/llvm/Analysis/ScalarEvolution.h
Original file line number Diff line number Diff line change
Expand Up @@ -776,18 +776,17 @@ class ScalarEvolution {
/// 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
Expand Down Expand Up @@ -1082,36 +1081,34 @@ class ScalarEvolution {
/// 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
Expand Down Expand Up @@ -1213,22 +1210,22 @@ class ScalarEvolution {
/// 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,
const SCEV *MaxIter);

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
Expand Down Expand Up @@ -1904,7 +1901,7 @@ class ScalarEvolution {
/// 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);
Expand Down Expand Up @@ -1977,34 +1974,33 @@ class ScalarEvolution {
/// 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);

/// Test whether the condition described by Pred, LHS, and RHS is true
/// 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);

/// Test whether the condition described by Pred, LHS, and RHS is true
/// 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);

/// Test whether the condition described by Pred, LHS, and RHS is true
/// 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);
Expand All @@ -2013,36 +2009,34 @@ class ScalarEvolution {
/// 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);

/// Test whether the condition described by Pred, LHS, and RHS is true
/// 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
Expand All @@ -2051,9 +2045,8 @@ class ScalarEvolution {
///
/// 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
Expand All @@ -2062,8 +2055,8 @@ class ScalarEvolution {
///
/// 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);
Expand All @@ -2075,8 +2068,7 @@ class ScalarEvolution {
/// 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);

Expand All @@ -2085,7 +2077,7 @@ class ScalarEvolution {
/// 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);

Expand All @@ -2097,20 +2089,20 @@ class ScalarEvolution {

/// 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>".
Expand Down
Loading

0 comments on commit 60dc450

Please sign in to comment.