Skip to content

Commit 10f9da0

Browse files
committed
[VPlan] Manage Sentinel value for FindLastIV in VPlan.
Similar to modeling the start value as operand, also model the sentinel value as operand explicitly. This makes all require information for code-gen available directly in VPlan.
1 parent b68565b commit 10f9da0

File tree

5 files changed

+45
-14
lines changed

5 files changed

+45
-14
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7517,9 +7517,11 @@ static void fixReductionScalarResumeWhenVectorizingEpilog(
75177517
using namespace llvm::PatternMatch;
75187518
Value *Cmp, *OrigResumeV, *CmpOp;
75197519
bool IsExpectedPattern =
7520-
match(MainResumeValue, m_Select(m_OneUse(m_Value(Cmp)),
7521-
m_Specific(RdxDesc.getSentinelValue()),
7522-
m_Value(OrigResumeV))) &&
7520+
match(MainResumeValue,
7521+
m_Select(
7522+
m_OneUse(m_Value(Cmp)),
7523+
m_Specific(EpiRedResult->getOperand(2)->getLiveInIRValue()),
7524+
m_Value(OrigResumeV))) &&
75237525
(match(Cmp, m_SpecificICmp(ICmpInst::ICMP_EQ, m_Specific(OrigResumeV),
75247526
m_Value(CmpOp))) &&
75257527
(match(CmpOp,
@@ -9509,9 +9511,11 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
95099511
if (RecurrenceDescriptor::isFindLastIVRecurrenceKind(
95109512
RdxDesc.getRecurrenceKind())) {
95119513
VPValue *Start = PhiR->getStartValue();
9512-
FinalReductionResult =
9513-
Builder.createNaryOp(VPInstruction::ComputeFindLastIVResult,
9514-
{PhiR, Start, NewExitingVPV}, ExitDL);
9514+
FinalReductionResult = Builder.createNaryOp(
9515+
VPInstruction::ComputeFindLastIVResult,
9516+
{PhiR, Start, Plan->getOrAddLiveIn(RdxDesc.getSentinelValue()),
9517+
NewExitingVPV},
9518+
ExitDL);
95159519
} else {
95169520
VPIRFlags Flags = RecurrenceDescriptor::isFloatingPointRecurrenceKind(
95179521
RdxDesc.getRecurrenceKind())
@@ -10040,6 +10044,14 @@ preparePlanForEpilogueVectorLoop(VPlan &Plan, Loop *L,
1004010044
Value *ResumeV = nullptr;
1004110045
// TODO: Move setting of resume values to prepareToExecute.
1004210046
if (auto *ReductionPhi = dyn_cast<VPReductionPHIRecipe>(&R)) {
10047+
auto *RdxResult =
10048+
cast<VPInstruction>(*find_if(ReductionPhi->users(), [](VPUser *U) {
10049+
auto *VPI = dyn_cast<VPInstruction>(U);
10050+
return VPI &&
10051+
(VPI->getOpcode() == VPInstruction::ComputeReductionResult ||
10052+
VPI->getOpcode() == VPInstruction::ComputeFindLastIVResult);
10053+
}));
10054+
1004310055
ResumeV = cast<PHINode>(ReductionPhi->getUnderlyingInstr())
1004410056
->getIncomingValueForBlock(L->getLoopPreheader());
1004510057
const RecurrenceDescriptor &RdxDesc =
@@ -10068,8 +10080,8 @@ preparePlanForEpilogueVectorLoop(VPlan &Plan, Loop *L,
1006810080
IRBuilder<> Builder(ResumeBB, ResumeBB->getFirstNonPHIIt());
1006910081
Value *Cmp = Builder.CreateICmpEQ(
1007010082
ResumeV, ToFrozen[RdxDesc.getRecurrenceStartValue()]);
10071-
ResumeV =
10072-
Builder.CreateSelect(Cmp, RdxDesc.getSentinelValue(), ResumeV);
10083+
ResumeV = Builder.CreateSelect(
10084+
Cmp, RdxResult->getOperand(2)->getLiveInIRValue(), ResumeV);
1007310085
}
1007410086
} else {
1007510087
// Retrieve the induction resume values for wide inductions from

llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,25 @@ m_VPInstruction(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2) {
318318
{Op0, Op1, Op2});
319319
}
320320

321+
template <typename Op0_t, typename Op1_t, typename Op2_t, typename Op3_t,
322+
unsigned Opcode, bool Commutative, typename... RecipeTys>
323+
using Recipe4Op_match = Recipe_match<std::tuple<Op0_t, Op1_t, Op2_t, Op3_t>,
324+
Opcode, Commutative, RecipeTys...>;
325+
326+
template <typename Op0_t, typename Op1_t, typename Op2_t, typename Op3_t,
327+
unsigned Opcode>
328+
using VPInstruction4Op_match =
329+
Recipe4Op_match<Op0_t, Op1_t, Op2_t, Op3_t, Opcode, /*Commutative*/ false,
330+
VPInstruction>;
331+
332+
template <unsigned Opcode, typename Op0_t, typename Op1_t, typename Op2_t,
333+
typename Op3_t>
334+
inline VPInstruction4Op_match<Op0_t, Op1_t, Op2_t, Op3_t, Opcode>
335+
m_VPInstruction(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2,
336+
const Op3_t &Op3) {
337+
return VPInstruction4Op_match<Op0_t, Op1_t, Op2_t, Op3_t, Opcode>(
338+
{Op0, Op1, Op2, Op3});
339+
}
321340
template <typename Op0_t>
322341
inline UnaryVPInstruction_match<Op0_t, VPInstruction::Not>
323342
m_Not(const Op0_t &Op0) {

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -618,16 +618,16 @@ Value *VPInstruction::generate(VPTransformState &State) {
618618

619619
// The recipe's operands are the reduction phi, followed by one operand for
620620
// each part of the reduction.
621-
unsigned UF = getNumOperands() - 2;
622-
Value *ReducedPartRdx = State.get(getOperand(2));
621+
unsigned UF = getNumOperands() - 3;
622+
Value *ReducedPartRdx = State.get(getOperand(3));
623623
for (unsigned Part = 1; Part < UF; ++Part) {
624624
ReducedPartRdx = createMinMaxOp(Builder, RecurKind::SMax, ReducedPartRdx,
625-
State.get(getOperand(2 + Part)));
625+
State.get(getOperand(3 + Part)));
626626
}
627627

628628
return createFindLastIVReduction(Builder, ReducedPartRdx,
629629
State.get(getOperand(1), true),
630-
RdxDesc.getSentinelValue());
630+
getOperand(2)->getLiveInIRValue());
631631
}
632632
case VPInstruction::ComputeReductionResult: {
633633
// FIXME: The cross-recipe dependency on VPReductionPHIRecipe is temporary

llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ void UnrollState::unrollBlock(VPBlockBase *VPB) {
330330
if (match(&R, m_VPInstruction<VPInstruction::ComputeReductionResult>(
331331
m_VPValue(), m_VPValue(Op1))) ||
332332
match(&R, m_VPInstruction<VPInstruction::ComputeFindLastIVResult>(
333-
m_VPValue(), m_VPValue(), m_VPValue(Op1)))) {
333+
m_VPValue(), m_VPValue(), m_VPValue(), m_VPValue(Op1)))) {
334334
addUniformForAllParts(cast<VPInstruction>(&R));
335335
for (unsigned Part = 1; Part != UF; ++Part)
336336
R.addOperand(getValueForPart(Op1, Part));

llvm/test/Transforms/LoopVectorize/vplan-printing-reductions.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ define i64 @find_last_iv(ptr %a, i64 %n, i64 %start) {
237237
; CHECK-NEXT: Successor(s): middle.block
238238
; CHECK-EMPTY:
239239
; CHECK-NEXT: middle.block:
240-
; CHECK-NEXT: EMIT vp<[[RDX_RES:%.+]]> = compute-find-last-iv-result ir<%rdx>, ir<%start>, ir<%cond>
240+
; CHECK-NEXT: EMIT vp<[[RDX_RES:%.+]]> = compute-find-last-iv-result ir<%rdx>, ir<%start>, ir<-9223372036854775808>, ir<%cond>
241241
; CHECK-NEXT: EMIT vp<[[EXT:%.+]]> = extract-last-element vp<[[RDX_RES]]>
242242
; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq ir<%n>, vp<{{.+}}>
243243
; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>

0 commit comments

Comments
 (0)