Skip to content

Commit 9165993

Browse files
committed
[VPlan] Update induction resume values in VPlan.
Updated ILV.crateInductionResumeValues to directly update the VPIRInstructiosn wrapping the original phis with the created resume values. This is the first step towards modeling them completely in VPlan. Subsequent patches will move creation of the resume values completely into VPlan. Builds on top of #109975, which is included in this PR.
1 parent ff9cac1 commit 9165993

File tree

51 files changed

+888
-854
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+888
-854
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 93 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -467,11 +467,12 @@ class InnerLoopVectorizer {
467467
ElementCount MinProfitableTripCount,
468468
unsigned UnrollFactor, LoopVectorizationLegality *LVL,
469469
LoopVectorizationCostModel *CM, BlockFrequencyInfo *BFI,
470-
ProfileSummaryInfo *PSI, GeneratedRTChecks &RTChecks)
470+
ProfileSummaryInfo *PSI, GeneratedRTChecks &RTChecks,
471+
VPlan &Plan)
471472
: OrigLoop(OrigLoop), PSE(PSE), LI(LI), DT(DT), TLI(TLI), TTI(TTI),
472473
AC(AC), ORE(ORE), VF(VecWidth), UF(UnrollFactor),
473474
Builder(PSE.getSE()->getContext()), Legal(LVL), Cost(CM), BFI(BFI),
474-
PSI(PSI), RTChecks(RTChecks) {
475+
PSI(PSI), RTChecks(RTChecks), Plan(Plan) {
475476
// Query this against the original loop and save it here because the profile
476477
// of the original loop header may change as the transformation happens.
477478
OptForSizeBasedOnProfile = llvm::shouldOptimizeForSize(
@@ -522,7 +523,7 @@ class InnerLoopVectorizer {
522523
/// and the resume values can come from an additional bypass block, the \p
523524
/// AdditionalBypass pair provides information about the bypass block and the
524525
/// end value on the edge from bypass to this loop.
525-
PHINode *createInductionResumeValue(
526+
void createInductionResumeValue(
526527
PHINode *OrigPhi, const InductionDescriptor &ID, Value *Step,
527528
ArrayRef<BasicBlock *> BypassBlocks,
528529
std::pair<BasicBlock *, Value *> AdditionalBypass = {nullptr, nullptr});
@@ -535,6 +536,11 @@ class InnerLoopVectorizer {
535536
/// count of the original loop for both main loop and epilogue vectorization.
536537
void setTripCount(Value *TC) { TripCount = TC; }
537538

539+
std::pair<BasicBlock *, Value *>
540+
getInductionBypassValue(PHINode *OrigPhi) const {
541+
return InductionBypassValues.find(OrigPhi)->second;
542+
}
543+
538544
protected:
539545
friend class LoopVectorizationPlanner;
540546

@@ -674,6 +680,11 @@ class InnerLoopVectorizer {
674680
/// Structure to hold information about generated runtime checks, responsible
675681
/// for cleaning the checks, if vectorization turns out unprofitable.
676682
GeneratedRTChecks &RTChecks;
683+
684+
/// Mapping of induction phis to their bypass values and bypass blocks.
685+
DenseMap<PHINode *, std::pair<BasicBlock *, Value *>> InductionBypassValues;
686+
687+
VPlan &Plan;
677688
};
678689

679690
/// Encapsulate information regarding vectorization of a loop and its epilogue.
@@ -715,10 +726,10 @@ class InnerLoopAndEpilogueVectorizer : public InnerLoopVectorizer {
715726
OptimizationRemarkEmitter *ORE, EpilogueLoopVectorizationInfo &EPI,
716727
LoopVectorizationLegality *LVL, llvm::LoopVectorizationCostModel *CM,
717728
BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI,
718-
GeneratedRTChecks &Checks)
729+
GeneratedRTChecks &Checks, VPlan &Plan)
719730
: InnerLoopVectorizer(OrigLoop, PSE, LI, DT, TLI, TTI, AC, ORE,
720731
EPI.MainLoopVF, EPI.MainLoopVF, EPI.MainLoopUF, LVL,
721-
CM, BFI, PSI, Checks),
732+
CM, BFI, PSI, Checks, Plan),
722733
EPI(EPI) {}
723734

724735
// Override this function to handle the more complex control flow around the
@@ -755,9 +766,9 @@ class EpilogueVectorizerMainLoop : public InnerLoopAndEpilogueVectorizer {
755766
OptimizationRemarkEmitter *ORE, EpilogueLoopVectorizationInfo &EPI,
756767
LoopVectorizationLegality *LVL, llvm::LoopVectorizationCostModel *CM,
757768
BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI,
758-
GeneratedRTChecks &Check)
769+
GeneratedRTChecks &Check, VPlan &Plan)
759770
: InnerLoopAndEpilogueVectorizer(OrigLoop, PSE, LI, DT, TLI, TTI, AC, ORE,
760-
EPI, LVL, CM, BFI, PSI, Check) {}
771+
EPI, LVL, CM, BFI, PSI, Check, Plan) {}
761772
/// Implements the interface for creating a vectorized skeleton using the
762773
/// *main loop* strategy (ie the first pass of vplan execution).
763774
std::pair<BasicBlock *, Value *>
@@ -789,9 +800,9 @@ class EpilogueVectorizerEpilogueLoop : public InnerLoopAndEpilogueVectorizer {
789800
OptimizationRemarkEmitter *ORE, EpilogueLoopVectorizationInfo &EPI,
790801
LoopVectorizationLegality *LVL, llvm::LoopVectorizationCostModel *CM,
791802
BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI,
792-
GeneratedRTChecks &Checks)
803+
GeneratedRTChecks &Checks, VPlan &Plan)
793804
: InnerLoopAndEpilogueVectorizer(OrigLoop, PSE, LI, DT, TLI, TTI, AC, ORE,
794-
EPI, LVL, CM, BFI, PSI, Checks) {
805+
EPI, LVL, CM, BFI, PSI, Checks, Plan) {
795806
TripCount = EPI.TripCount;
796807
}
797808
/// Implements the interface for creating a vectorized skeleton using the
@@ -2586,7 +2597,18 @@ void InnerLoopVectorizer::createVectorLoopSkeleton(StringRef Prefix) {
25862597
nullptr, Twine(Prefix) + "scalar.ph");
25872598
}
25882599

2589-
PHINode *InnerLoopVectorizer::createInductionResumeValue(
2600+
static void addOperandToPhiInVPIRBasicBlock(VPIRBasicBlock *VPBB, PHINode *P,
2601+
VPValue *Op) {
2602+
for (VPRecipeBase &R : *VPBB) {
2603+
auto *IRI = cast<VPIRInstruction>(&R);
2604+
if (&IRI->getInstruction() == P) {
2605+
IRI->addOperand(Op);
2606+
break;
2607+
}
2608+
}
2609+
}
2610+
2611+
void InnerLoopVectorizer::createInductionResumeValue(
25902612
PHINode *OrigPhi, const InductionDescriptor &II, Value *Step,
25912613
ArrayRef<BasicBlock *> BypassBlocks,
25922614
std::pair<BasicBlock *, Value *> AdditionalBypass) {
@@ -2621,27 +2643,28 @@ PHINode *InnerLoopVectorizer::createInductionResumeValue(
26212643
}
26222644
}
26232645

2624-
// Create phi nodes to merge from the backedge-taken check block.
2625-
PHINode *BCResumeVal =
2626-
PHINode::Create(OrigPhi->getType(), 3, "bc.resume.val",
2627-
LoopScalarPreHeader->getFirstNonPHIIt());
2628-
// Copy original phi DL over to the new one.
2629-
BCResumeVal->setDebugLoc(OrigPhi->getDebugLoc());
2646+
VPBasicBlock *MiddleVPBB =
2647+
cast<VPBasicBlock>(Plan.getVectorLoopRegion()->getSingleSuccessor());
26302648

2631-
// The new PHI merges the original incoming value, in case of a bypass,
2632-
// or the value at the end of the vectorized loop.
2633-
BCResumeVal->addIncoming(EndValue, LoopMiddleBlock);
2649+
VPBasicBlock *ScalarPHVPBB = nullptr;
2650+
if (MiddleVPBB->getNumSuccessors() == 2) {
2651+
// Order is strict: first is the exit block, second is the scalar preheader.
2652+
ScalarPHVPBB = cast<VPBasicBlock>(MiddleVPBB->getSuccessors()[1]);
2653+
} else {
2654+
ScalarPHVPBB = cast<VPBasicBlock>(MiddleVPBB->getSingleSuccessor());
2655+
}
26342656

2635-
// Fix the scalar body counter (PHI node).
2636-
// The old induction's phi node in the scalar body needs the truncated
2637-
// value.
2638-
for (BasicBlock *BB : BypassBlocks)
2639-
BCResumeVal->addIncoming(II.getStartValue(), BB);
2657+
VPBuilder ScalarPHBuilder(ScalarPHVPBB);
2658+
auto *ResumePhiRecipe = ScalarPHBuilder.createNaryOp(
2659+
VPInstruction::ResumePhi,
2660+
{Plan.getOrAddLiveIn(EndValue), Plan.getOrAddLiveIn(II.getStartValue())},
2661+
OrigPhi->getDebugLoc(), "bc.resume.val");
26402662

2641-
if (AdditionalBypass.first)
2642-
BCResumeVal->setIncomingValueForBlock(AdditionalBypass.first,
2643-
EndValueFromAdditionalBypass);
2644-
return BCResumeVal;
2663+
auto *ScalarLoopHeader =
2664+
cast<VPIRBasicBlock>(ScalarPHVPBB->getSingleSuccessor());
2665+
addOperandToPhiInVPIRBasicBlock(ScalarLoopHeader, OrigPhi, ResumePhiRecipe);
2666+
InductionBypassValues[OrigPhi] = {AdditionalBypass.first,
2667+
EndValueFromAdditionalBypass};
26452668
}
26462669

26472670
/// Return the expanded step for \p ID using \p ExpandedSCEVs to look up SCEV
@@ -2674,10 +2697,8 @@ void InnerLoopVectorizer::createInductionResumeValues(
26742697
for (const auto &InductionEntry : Legal->getInductionVars()) {
26752698
PHINode *OrigPhi = InductionEntry.first;
26762699
const InductionDescriptor &II = InductionEntry.second;
2677-
PHINode *BCResumeVal = createInductionResumeValue(
2678-
OrigPhi, II, getExpandedStep(II, ExpandedSCEVs), LoopBypassBlocks,
2679-
AdditionalBypass);
2680-
OrigPhi->setIncomingValueForBlock(LoopScalarPreHeader, BCResumeVal);
2700+
createInductionResumeValue(OrigPhi, II, getExpandedStep(II, ExpandedSCEVs),
2701+
LoopBypassBlocks, AdditionalBypass);
26812702
}
26822703
}
26832704

@@ -7805,6 +7826,25 @@ EpilogueVectorizerMainLoop::createEpilogueVectorizedLoopSkeleton(
78057826
// the second pass for the scalar loop. The induction resume values for the
78067827
// inductions in the epilogue loop are created before executing the plan for
78077828
// the epilogue loop.
7829+
for (VPRecipeBase &R :
7830+
Plan.getVectorLoopRegion()->getEntryBasicBlock()->phis()) {
7831+
// Create induction resume values for both widened pointer and
7832+
// integer/fp inductions and update the start value of the induction
7833+
// recipes to use the resume value.
7834+
PHINode *IndPhi = nullptr;
7835+
const InductionDescriptor *ID;
7836+
if (auto *Ind = dyn_cast<VPWidenPointerInductionRecipe>(&R)) {
7837+
IndPhi = cast<PHINode>(Ind->getUnderlyingValue());
7838+
ID = &Ind->getInductionDescriptor();
7839+
} else if (auto *WidenInd = dyn_cast<VPWidenIntOrFpInductionRecipe>(&R)) {
7840+
IndPhi = WidenInd->getPHINode();
7841+
ID = &WidenInd->getInductionDescriptor();
7842+
} else
7843+
continue;
7844+
7845+
createInductionResumeValue(IndPhi, *ID, getExpandedStep(*ID, ExpandedSCEVs),
7846+
LoopBypassBlocks);
7847+
}
78087848

78097849
return {LoopVectorPreHeader, nullptr};
78107850
}
@@ -8963,14 +9003,9 @@ static void addLiveOutsForFirstOrderRecurrences(
89639003
VPInstruction::ResumePhi, {Resume, FOR->getStartValue()}, {},
89649004
"scalar.recur.init");
89659005
auto *FORPhi = cast<PHINode>(FOR->getUnderlyingInstr());
8966-
for (VPRecipeBase &R :
8967-
*cast<VPIRBasicBlock>(ScalarPHVPBB->getSingleSuccessor())) {
8968-
auto *IRI = cast<VPIRInstruction>(&R);
8969-
if (&IRI->getInstruction() == FORPhi) {
8970-
IRI->addOperand(ResumePhiRecipe);
8971-
break;
8972-
}
8973-
}
9006+
addOperandToPhiInVPIRBasicBlock(
9007+
cast<VPIRBasicBlock>(ScalarPHVPBB->getSingleSuccessor()), FORPhi,
9008+
ResumePhiRecipe);
89749009

89759010
// Now update VPIRInstructions modeling LCSSA phis in the exit block.
89769011
// Extract the penultimate value of the recurrence and use it as operand for
@@ -9707,7 +9742,7 @@ static bool processLoopInVPlanNativePath(
97079742
GeneratedRTChecks Checks(PSE, DT, LI, TTI, F->getDataLayout(),
97089743
AddBranchWeights);
97099744
InnerLoopVectorizer LB(L, PSE, LI, DT, TLI, TTI, AC, ORE, VF.Width,
9710-
VF.Width, 1, LVL, &CM, BFI, PSI, Checks);
9745+
VF.Width, 1, LVL, &CM, BFI, PSI, Checks, BestPlan);
97119746
LLVM_DEBUG(dbgs() << "Vectorizing outer loop in \""
97129747
<< L->getHeader()->getParent()->getName() << "\"\n");
97139748
LVP.executePlan(VF.Width, 1, BestPlan, LB, DT, false);
@@ -10195,11 +10230,11 @@ bool LoopVectorizePass::processLoop(Loop *L) {
1019510230
assert(IC > 1 && "interleave count should not be 1 or 0");
1019610231
// If we decided that it is not legal to vectorize the loop, then
1019710232
// interleave it.
10233+
VPlan &BestPlan = LVP.getPlanFor(VF.Width);
1019810234
InnerLoopVectorizer Unroller(
1019910235
L, PSE, LI, DT, TLI, TTI, AC, ORE, ElementCount::getFixed(1),
10200-
ElementCount::getFixed(1), IC, &LVL, &CM, BFI, PSI, Checks);
10236+
ElementCount::getFixed(1), IC, &LVL, &CM, BFI, PSI, Checks, BestPlan);
1020110237

10202-
VPlan &BestPlan = LVP.getPlanFor(VF.Width);
1020310238
LVP.executePlan(VF.Width, IC, BestPlan, Unroller, DT, false);
1020410239

1020510240
ORE->emit([&]() {
@@ -10221,10 +10256,11 @@ bool LoopVectorizePass::processLoop(Loop *L) {
1022110256
// to be vectorized by executing the plan (potentially with a different
1022210257
// factor) again shortly afterwards.
1022310258
EpilogueLoopVectorizationInfo EPI(VF.Width, IC, EpilogueVF.Width, 1);
10259+
std::unique_ptr<VPlan> BestMainPlan(BestPlan.duplicate());
1022410260
EpilogueVectorizerMainLoop MainILV(L, PSE, LI, DT, TLI, TTI, AC, ORE,
10225-
EPI, &LVL, &CM, BFI, PSI, Checks);
10261+
EPI, &LVL, &CM, BFI, PSI, Checks,
10262+
*BestMainPlan);
1022610263

10227-
std::unique_ptr<VPlan> BestMainPlan(BestPlan.duplicate());
1022810264
auto ExpandedSCEVs = LVP.executePlan(EPI.MainLoopVF, EPI.MainLoopUF,
1022910265
*BestMainPlan, MainILV, DT, true);
1023010266
++LoopsVectorized;
@@ -10233,11 +10269,11 @@ bool LoopVectorizePass::processLoop(Loop *L) {
1023310269
// edges from the first pass.
1023410270
EPI.MainLoopVF = EPI.EpilogueVF;
1023510271
EPI.MainLoopUF = EPI.EpilogueUF;
10272+
VPlan &BestEpiPlan = LVP.getPlanFor(EPI.EpilogueVF);
1023610273
EpilogueVectorizerEpilogueLoop EpilogILV(L, PSE, LI, DT, TLI, TTI, AC,
1023710274
ORE, EPI, &LVL, &CM, BFI, PSI,
10238-
Checks);
10275+
Checks, BestEpiPlan);
1023910276

10240-
VPlan &BestEpiPlan = LVP.getPlanFor(EPI.EpilogueVF);
1024110277
VPRegionBlock *VectorLoop = BestEpiPlan.getVectorLoopRegion();
1024210278
VPBasicBlock *Header = VectorLoop->getEntryBasicBlock();
1024310279
Header->setName("vec.epilog.vector.body");
@@ -10286,23 +10322,16 @@ bool LoopVectorizePass::processLoop(Loop *L) {
1028610322
RdxDesc.getRecurrenceStartValue());
1028710323
}
1028810324
} else {
10289-
// Create induction resume values for both widened pointer and
10290-
// integer/fp inductions and update the start value of the induction
10291-
// recipes to use the resume value.
10325+
// Retrive the induction resume values for wide inductions from
10326+
// their original phi nodes in the scalar loop
1029210327
PHINode *IndPhi = nullptr;
10293-
const InductionDescriptor *ID;
1029410328
if (auto *Ind = dyn_cast<VPWidenPointerInductionRecipe>(&R)) {
1029510329
IndPhi = cast<PHINode>(Ind->getUnderlyingValue());
10296-
ID = &Ind->getInductionDescriptor();
1029710330
} else {
1029810331
auto *WidenInd = cast<VPWidenIntOrFpInductionRecipe>(&R);
1029910332
IndPhi = WidenInd->getPHINode();
10300-
ID = &WidenInd->getInductionDescriptor();
1030110333
}
10302-
10303-
ResumeV = MainILV.createInductionResumeValue(
10304-
IndPhi, *ID, getExpandedStep(*ID, ExpandedSCEVs),
10305-
{EPI.MainLoopIterationCountCheck});
10334+
ResumeV = IndPhi->getIncomingValueForBlock(L->getLoopPreheader());
1030610335
}
1030710336
assert(ResumeV && "Must have a resume value");
1030810337
VPValue *StartVal = BestEpiPlan.getOrAddLiveIn(ResumeV);
@@ -10314,13 +10343,19 @@ bool LoopVectorizePass::processLoop(Loop *L) {
1031410343
LVP.executePlan(EPI.EpilogueVF, EPI.EpilogueUF, BestEpiPlan, EpilogILV,
1031510344
DT, true, &ExpandedSCEVs);
1031610345
++LoopsEpilogueVectorized;
10346+
BasicBlock *PH = L->getLoopPreheader();
1031710347

10348+
for (const auto &[IVPhi, _] : LVL.getInductionVars()) {
10349+
auto *Inc = cast<PHINode>(IVPhi->getIncomingValueForBlock(PH));
10350+
const auto &[BB, V] = EpilogILV.getInductionBypassValue(IVPhi);
10351+
Inc->setIncomingValueForBlock(BB, V);
10352+
}
1031810353
if (!MainILV.areSafetyChecksAdded())
1031910354
DisableRuntimeUnroll = true;
1032010355
} else {
1032110356
InnerLoopVectorizer LB(L, PSE, LI, DT, TLI, TTI, AC, ORE, VF.Width,
1032210357
VF.MinProfitableTripCount, IC, &LVL, &CM, BFI,
10323-
PSI, Checks);
10358+
PSI, Checks, BestPlan);
1032410359
LVP.executePlan(VF.Width, IC, BestPlan, LB, DT, false);
1032510360
++LoopsVectorized;
1032610361

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,8 @@ Value *VPInstruction::generate(VPTransformState &State) {
641641
State.CFG
642642
.VPBB2IRBB[cast<VPBasicBlock>(getParent()->getSinglePredecessor())];
643643
NewPhi->addIncoming(IncomingFromVPlanPred, VPlanPred);
644-
for (auto *OtherPred : predecessors(Builder.GetInsertBlock())) {
644+
for (auto *OtherPred :
645+
reverse(to_vector(predecessors(Builder.GetInsertBlock())))) {
645646
assert(OtherPred != VPlanPred &&
646647
"VPlan predecessors should not be connected yet");
647648
NewPhi->addIncoming(IncomingFromOtherPreds, OtherPred);

llvm/test/Transforms/LoopVectorize/AArch64/call-costs.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ define void @fshl_operand_first_order_recurrence(ptr %dst, ptr noalias %src) {
3535
; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <2 x i64> [[WIDE_LOAD1]], i32 1
3636
; CHECK-NEXT: br i1 false, label %[[EXIT:.*]], label %[[SCALAR_PH]]
3737
; CHECK: [[SCALAR_PH]]:
38-
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 100, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
3938
; CHECK-NEXT: [[SCALAR_RECUR_INIT:%.*]] = phi i64 [ [[VECTOR_RECUR_EXTRACT]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
39+
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 100, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
4040
; CHECK-NEXT: br label %[[LOOP:.*]]
4141
; CHECK: [[LOOP]]:
4242
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]

llvm/test/Transforms/LoopVectorize/AArch64/epilog-vectorization-widen-inductions.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,10 @@ define void @test_widen_induction_variable_start(ptr %A, i64 %N, i64 %start) {
205205
; CHECK: vector.ph:
206206
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
207207
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
208+
; CHECK-NEXT: [[IND_END:%.*]] = add i64 [[START]], [[N_VEC]]
208209
; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[START]], i64 0
209210
; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i64> [[DOTSPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer
210211
; CHECK-NEXT: [[INDUCTION:%.*]] = add <2 x i64> [[DOTSPLAT]], <i64 0, i64 1>
211-
; CHECK-NEXT: [[IND_END:%.*]] = add i64 [[START]], [[N_VEC]]
212212
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
213213
; CHECK: vector.body:
214214
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
@@ -433,7 +433,7 @@ define void @test_widen_extended_induction(ptr %dst) {
433433
; CHECK: vec.epilog.middle.block:
434434
; CHECK-NEXT: br i1 true, label [[EXIT]], label [[VEC_EPILOG_SCALAR_PH]]
435435
; CHECK: vec.epilog.scalar.ph:
436-
; CHECK-NEXT: [[BC_RESUME_VAL1:%.*]] = phi i8 [ 16, [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ 16, [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[VECTOR_SCEVCHECK]] ], [ 0, [[ITER_CHECK:%.*]] ]
436+
; CHECK-NEXT: [[BC_RESUME_VAL1:%.*]] = phi i8 [ 16, [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ 16, [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[ITER_CHECK:%.*]] ], [ 0, [[VECTOR_SCEVCHECK]] ]
437437
; CHECK-NEXT: br label [[LOOP:%.*]]
438438
; CHECK: loop:
439439
; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[BC_RESUME_VAL1]], [[VEC_EPILOG_SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]

llvm/test/Transforms/LoopVectorize/AArch64/first-order-recurrence-fold-tail.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ define i32 @test_phi_iterator_invalidation(ptr %A, ptr noalias %B) {
7373
; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <4 x i16> [[TMP24]], i32 3
7474
; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[SCALAR_PH]]
7575
; CHECK: scalar.ph:
76-
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1004, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
77-
; CHECK-NEXT: [[SCALAR_RECUR_INIT:%.*]] = phi i16 [ [[VECTOR_RECUR_EXTRACT]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ]
76+
; CHECK-NEXT: [[SCALAR_RECUR_INIT:%.*]] = phi i16 [ [[VECTOR_RECUR_EXTRACT]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
77+
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1004, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ]
7878
; CHECK-NEXT: br label [[LOOP:%.*]]
7979
; CHECK: loop:
8080
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]

0 commit comments

Comments
 (0)