Skip to content

Commit 0b6c41f

Browse files
committed
Refactor the identification method for FindLastIV pattern.
This patch applys range analysis. It will exclude cases where the range of induction variable cannot be fully contained within [<sentinel value> + 1, <minimum value of recurrence type>) This approach also handles truncated induction variable cases well.
1 parent 47258cf commit 0b6c41f

File tree

2 files changed

+598
-21
lines changed

2 files changed

+598
-21
lines changed

llvm/lib/Analysis/IVDescriptors.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -710,27 +710,36 @@ RecurrenceDescriptor::isFindLastIVPattern(Loop *Loop, PHINode *OrigPhi,
710710
return InstDesc(false, I);
711711

712712
auto IsIncreasingLoopInduction = [&SE, &Loop](Value *V) {
713-
auto *Phi = dyn_cast<PHINode>(V);
714-
if (!Phi)
715-
return false;
716-
717713
if (!SE)
718714
return false;
719715

720-
InductionDescriptor ID;
721-
if (!InductionDescriptor::isInductionPHI(Phi, Loop, SE, ID))
716+
Type *Ty = V->getType();
717+
if (!SE->isSCEVable(Ty))
722718
return false;
723719

724-
const SCEVAddRecExpr *AR = cast<SCEVAddRecExpr>(SE->getSCEV(Phi));
725-
if (!AR->hasNoSignedWrap())
720+
auto *AR = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(V));
721+
if (!AR)
726722
return false;
727723

728-
ConstantInt *IVStartValue = dyn_cast<ConstantInt>(ID.getStartValue());
729-
if (!IVStartValue || IVStartValue->isMinSignedValue())
724+
const SCEV *Step = AR->getStepRecurrence(*SE);
725+
if (!SE->isKnownPositive(Step))
730726
return false;
731727

732-
const SCEV *Step = ID.getStep();
733-
return SE->isKnownPositive(Step);
728+
const ConstantRange IVRange = SE->getSignedRange(AR);
729+
unsigned NumBits = Ty->getIntegerBitWidth();
730+
// Keep the minmum value of the recurrence type as the sentinel value.
731+
// The maximum acceptable range for the increasing induction variable,
732+
// called the valid range, will be defined as
733+
// [<sentinel value> + 1, SignedMin(<recurrence type>))
734+
// TODO: This range restriction can be lifted by adding an additional
735+
// virtual OR reduction.
736+
const APInt Sentinel = APInt::getSignedMinValue(NumBits);
737+
const ConstantRange ValidRange = ConstantRange::getNonEmpty(
738+
Sentinel + 1, APInt::getSignedMinValue(NumBits));
739+
LLVM_DEBUG(dbgs() << "LV: FindLastIV valid range is " << ValidRange
740+
<< ", and the signed range of " << *AR << " is "
741+
<< IVRange << "\n");
742+
return ValidRange.contains(IVRange);
734743
};
735744

736745
// We are looking for selects of the form:

0 commit comments

Comments
 (0)