Skip to content

Commit

Permalink
[IRCE][NFC] Refactor parseRangeCheckICmp to compute SCEVs instead of …
Browse files Browse the repository at this point in the history
…Values

The motivation is to make an opportunity to compute and return
expressions after parsing ICmp into a range check (e.g. Length + 1).

Patch by Aleksandr Popov!

Differential Revision: https://reviews.llvm.org/D148205
  • Loading branch information
xortator committed Apr 14, 2023
1 parent 854686f commit a39b807
Showing 1 changed file with 18 additions and 21 deletions.
39 changes: 18 additions & 21 deletions llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class InductiveRangeCheck {
Use *CheckUse = nullptr;

static bool parseRangeCheckICmp(Loop *L, ICmpInst *ICI, ScalarEvolution &SE,
Value *&Index, Value *&Length);
const SCEV *&Index, const SCEV *&End);

static void
extractRangeChecksFromCond(Loop *L, ScalarEvolution &SE, Use &ConditionUse,
Expand Down Expand Up @@ -284,13 +284,13 @@ INITIALIZE_PASS_END(IRCELegacyPass, "irce", "Inductive range check elimination",
false, false)

/// Parse a single ICmp instruction, `ICI`, into a range check. If `ICI` cannot
/// be interpreted as a range check, return false and set `Index` and `Length`
/// to `nullptr`. Otherwise set `Index` to the value being range checked, and
/// set `Length` to the upper limit `Index` is being range checked.
bool
InductiveRangeCheck::parseRangeCheckICmp(Loop *L, ICmpInst *ICI,
ScalarEvolution &SE, Value *&Index,
Value *&Length) {
/// be interpreted as a range check, return false and set `Index` and `End`
/// to `nullptr`. Otherwise set `Index` to the SCEV being range checked, and
/// set `End` to the upper limit `Index` is being range checked.
bool InductiveRangeCheck::parseRangeCheckICmp(Loop *L, ICmpInst *ICI,
ScalarEvolution &SE,
const SCEV *&Index,
const SCEV *&End) {
auto IsLoopInvariant = [&SE, L](Value *V) {
return SE.isLoopInvariant(SE.getSCEV(V), L);
};
Expand All @@ -308,7 +308,7 @@ InductiveRangeCheck::parseRangeCheckICmp(Loop *L, ICmpInst *ICI,
[[fallthrough]];
case ICmpInst::ICMP_SGE:
if (match(RHS, m_ConstantInt<0>())) {
Index = LHS;
Index = SE.getSCEV(LHS);
return true; // Lower.
}
return false;
Expand All @@ -318,13 +318,13 @@ InductiveRangeCheck::parseRangeCheckICmp(Loop *L, ICmpInst *ICI,
[[fallthrough]];
case ICmpInst::ICMP_SGT:
if (match(RHS, m_ConstantInt<-1>())) {
Index = LHS;
Index = SE.getSCEV(LHS);
return true; // Lower.
}

if (IsLoopInvariant(LHS)) {
Index = RHS;
Length = LHS;
Index = SE.getSCEV(RHS);
End = SE.getSCEV(LHS);
return true; // Upper.
}
return false;
Expand All @@ -334,8 +334,8 @@ InductiveRangeCheck::parseRangeCheckICmp(Loop *L, ICmpInst *ICI,
[[fallthrough]];
case ICmpInst::ICMP_UGT:
if (IsLoopInvariant(LHS)) {
Index = RHS;
Length = LHS;
Index = SE.getSCEV(RHS);
End = SE.getSCEV(LHS);
return true; // Both lower and upper.
}
return false;
Expand Down Expand Up @@ -365,23 +365,20 @@ void InductiveRangeCheck::extractRangeChecksFromCond(
if (!ICI)
return;

Value *Length = nullptr, *Index;
if (!parseRangeCheckICmp(L, ICI, SE, Index, Length))
const SCEV *End = nullptr, *Index = nullptr;
if (!parseRangeCheckICmp(L, ICI, SE, Index, End))
return;

const auto *IndexAddRec = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(Index));
const auto *IndexAddRec = dyn_cast<SCEVAddRecExpr>(Index);
bool IsAffineIndex =
IndexAddRec && (IndexAddRec->getLoop() == L) && IndexAddRec->isAffine();

if (!IsAffineIndex)
return;

const SCEV *End = nullptr;
// We strengthen "0 <= I" to "0 <= I < INT_SMAX" and "I < L" to "0 <= I < L".
// We can potentially do much better here.
if (Length)
End = SE.getSCEV(Length);
else {
if (!End) {
// So far we can only reach this point for Signed range check. This may
// change in future. In this case we will need to pick Unsigned max for the
// unsigned range check.
Expand Down

0 comments on commit a39b807

Please sign in to comment.