-
Notifications
You must be signed in to change notification settings - Fork 13.7k
[LV] Skip sentinel value for FindLastIV reductions when start value is provably less than IV start. #141788
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[LV] Skip sentinel value for FindLastIV reductions when start value is provably less than IV start. #141788
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -288,6 +288,8 @@ bool RecurrenceDescriptor::AddReductionVar( | |
// The first instruction in the use-def chain of the Phi node that requires | ||
// exact floating point operations. | ||
Instruction *ExactFPMathInst = nullptr; | ||
// Record the sentinel value on demand. | ||
Value *SentinelValue = nullptr; | ||
|
||
// A value in the reduction can be used: | ||
// - By the reduction: | ||
|
@@ -376,6 +378,10 @@ bool RecurrenceDescriptor::AddReductionVar( | |
ExactFPMathInst = ExactFPMathInst == nullptr | ||
? ReduxDesc.getExactFPMathInst() | ||
: ExactFPMathInst; | ||
if (auto *Sentinel = ReduxDesc.getSentinelValue()) { | ||
assert(!SentinelValue && "Sentinel value can only be assigned once"); | ||
SentinelValue = Sentinel; | ||
} | ||
Comment on lines
+381
to
+384
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move to end of block? |
||
if (!ReduxDesc.isRecurrence()) | ||
return false; | ||
// FIXME: FMF is allowed on phi, but propagation is not handled correctly. | ||
|
@@ -596,7 +602,8 @@ bool RecurrenceDescriptor::AddReductionVar( | |
// Save the description of this reduction variable. | ||
RecurrenceDescriptor RD(RdxStart, ExitInstruction, IntermediateStore, Kind, | ||
FMF, ExactFPMathInst, RecurrenceType, IsSigned, | ||
IsOrdered, CastInsts, MinWidthCastToRecurrenceType); | ||
IsOrdered, CastInsts, MinWidthCastToRecurrenceType, | ||
SentinelValue); | ||
RedDes = RD; | ||
|
||
return true; | ||
|
@@ -700,18 +707,18 @@ RecurrenceDescriptor::isFindLastIVPattern(Loop *TheLoop, PHINode *OrigPhi, | |
m_Value(NonRdxPhi))))) | ||
return InstDesc(false, I); | ||
|
||
auto IsIncreasingLoopInduction = [&](Value *V) { | ||
auto IsIncreasingLoopInduction = [&](Value *V) -> std::pair<bool, Value *> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. std::optional<Value *>? |
||
Type *Ty = V->getType(); | ||
if (!SE.isSCEVable(Ty)) | ||
return false; | ||
return {false, nullptr}; | ||
|
||
auto *AR = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(V)); | ||
if (!AR || AR->getLoop() != TheLoop) | ||
return false; | ||
return {false, nullptr}; | ||
|
||
const SCEV *Step = AR->getStepRecurrence(SE); | ||
if (!SE.isKnownPositive(Step)) | ||
return false; | ||
return {false, nullptr}; | ||
|
||
const ConstantRange IVRange = SE.getSignedRange(AR); | ||
unsigned NumBits = Ty->getIntegerBitWidth(); | ||
|
@@ -730,17 +737,32 @@ RecurrenceDescriptor::isFindLastIVPattern(Loop *TheLoop, PHINode *OrigPhi, | |
<< IVRange << "\n"); | ||
// Ensure the induction variable does not wrap around by verifying that its | ||
// range is fully contained within the valid range. | ||
return ValidRange.contains(IVRange); | ||
if (!ValidRange.contains(IVRange)) | ||
return {false, nullptr}; | ||
|
||
// No sentinel is needed if it can be proven that the start value of | ||
// reduction is strictly less than the start value of increasing induction | ||
// variable. | ||
if (auto *ConstIVStart = dyn_cast<SCEVConstant>(AR->getStart())) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. m_scev_APInt()? |
||
Value *RdxStart = | ||
OrigPhi->getIncomingValueForBlock(TheLoop->getLoopPreheader()); | ||
if (auto *ConstRdxStart = dyn_cast<ConstantInt>(RdxStart)) | ||
Comment on lines
+747
to
+749
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. m_APInt()? |
||
if (ConstRdxStart->getValue().slt(ConstIVStart->getAPInt())) | ||
return {true, nullptr}; | ||
} | ||
|
||
return {true, ConstantInt::get(Ty, Sentinel)}; | ||
}; | ||
|
||
// We are looking for selects of the form: | ||
// select(cmp(), phi, increasing_loop_induction) or | ||
// select(cmp(), increasing_loop_induction, phi) | ||
// TODO: Support for monotonically decreasing induction variable | ||
if (!IsIncreasingLoopInduction(NonRdxPhi)) | ||
auto [IsRecurrence, Sentinel] = IsIncreasingLoopInduction(NonRdxPhi); | ||
if (!IsRecurrence) | ||
return InstDesc(false, I); | ||
|
||
return InstDesc(I, RecurKind::FindLastIV); | ||
return InstDesc(I, RecurKind::FindLastIV, Sentinel); | ||
} | ||
|
||
RecurrenceDescriptor::InstDesc | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1247,15 +1247,17 @@ Value *llvm::createFindLastIVReduction(IRBuilderBase &Builder, Value *Src, | |
assert(RecurrenceDescriptor::isFindLastIVRecurrenceKind( | ||
Desc.getRecurrenceKind()) && | ||
"Unexpected reduction kind"); | ||
Value *Sentinel = Desc.getSentinelValue(); | ||
Value *MaxRdx = Src->getType()->isVectorTy() | ||
Value *Result = Src->getType()->isVectorTy() | ||
? Builder.CreateIntMaxReduce(Src, true) | ||
: Src; | ||
// Correct the final reduction result back to the start value if the maximum | ||
// reduction is sentinel value. | ||
Value *Cmp = | ||
Builder.CreateCmp(CmpInst::ICMP_NE, MaxRdx, Sentinel, "rdx.select.cmp"); | ||
return Builder.CreateSelect(Cmp, MaxRdx, Start, "rdx.select"); | ||
if (Value *Sentinel = Desc.getSentinelValue()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Early return? |
||
Value *Cmp = | ||
Builder.CreateCmp(CmpInst::ICMP_NE, Result, Sentinel, "rdx.select.cmp"); | ||
Result = Builder.CreateSelect(Cmp, Result, Start, "rdx.select"); | ||
} | ||
return Result; | ||
} | ||
|
||
Value *llvm::getReductionIdentity(Intrinsic::ID RdxID, Type *Ty, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7568,7 +7568,8 @@ static void fixReductionScalarResumeWhenVectorizingEpilog( | |
"start value"); | ||
MainResumeValue = Cmp->getOperand(0); | ||
} else if (RecurrenceDescriptor::isFindLastIVRecurrenceKind( | ||
RdxDesc.getRecurrenceKind())) { | ||
RdxDesc.getRecurrenceKind()) && | ||
RdxDesc.getSentinelValue()) { | ||
using namespace llvm::PatternMatch; | ||
Value *Cmp, *OrigResumeV, *CmpOp; | ||
bool IsExpectedPattern = | ||
|
@@ -9625,7 +9626,8 @@ void LoopVectorizationPlanner::adjustRecipesForReductions( | |
// Adjust the start value for FindLastIV recurrences to use the sentinel | ||
// value after generating the ResumePhi recipe, which uses the original | ||
// start value. | ||
PhiR->setOperand(0, Plan->getOrAddLiveIn(RdxDesc.getSentinelValue())); | ||
if (auto *Sentinel = RdxDesc.getSentinelValue()) | ||
PhiR->setOperand(0, Plan->getOrAddLiveIn(Sentinel)); | ||
Comment on lines
-9628
to
+9630
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use the same |
||
} | ||
} | ||
for (VPRecipeBase *R : ToDelete) | ||
|
@@ -10114,7 +10116,8 @@ preparePlanForEpilogueVectorLoop(VPlan &Plan, Loop *L, | |
IRBuilder<> Builder(PBB, PBB->getFirstNonPHIIt()); | ||
ResumeV = | ||
Builder.CreateICmpNE(ResumeV, RdxDesc.getRecurrenceStartValue()); | ||
} else if (RecurrenceDescriptor::isFindLastIVRecurrenceKind(RK)) { | ||
} else if (RecurrenceDescriptor::isFindLastIVRecurrenceKind(RK) && | ||
RdxDesc.getSentinelValue()) { | ||
ToFrozen[RdxDesc.getRecurrenceStartValue()] = | ||
cast<PHINode>(ResumeV)->getIncomingValueForBlock( | ||
EPI.MainLoopIterationCountCheck); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think ExactFP is ever used via this constructor call: you can strip it?