Skip to content

Commit ba97834

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 7e8bf11 commit ba97834

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
@@ -712,27 +712,36 @@ RecurrenceDescriptor::isFindLastIVPattern(Loop *Loop, PHINode *OrigPhi,
712712
return InstDesc(false, I);
713713

714714
auto IsIncreasingLoopInduction = [&SE, &Loop](Value *V) {
715-
auto *Phi = dyn_cast<PHINode>(V);
716-
if (!Phi)
717-
return false;
718-
719715
if (!SE)
720716
return false;
721717

722-
InductionDescriptor ID;
723-
if (!InductionDescriptor::isInductionPHI(Phi, Loop, SE, ID))
718+
Type *Ty = V->getType();
719+
if (!SE->isSCEVable(Ty))
724720
return false;
725721

726-
const SCEVAddRecExpr *AR = cast<SCEVAddRecExpr>(SE->getSCEV(Phi));
727-
if (!AR->hasNoSignedWrap())
722+
auto *AR = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(V));
723+
if (!AR)
728724
return false;
729725

730-
ConstantInt *IVStartValue = dyn_cast<ConstantInt>(ID.getStartValue());
731-
if (!IVStartValue || IVStartValue->isMinSignedValue())
726+
const SCEV *Step = AR->getStepRecurrence(*SE);
727+
if (!SE->isKnownPositive(Step))
732728
return false;
733729

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

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

0 commit comments

Comments
 (0)