Skip to content

Commit d478502

Browse files
committed
[VPlan] Ensure that IV resume phi for epilogue is always first. (NFCI)
Update handling of canonical IV resume phi for the epilogue loop to make sure the resume phi for the canonical IV is always the first phi in the scalar preheader. This makes it easier to retrieve it in preparePlanForEpilogueVectorLoop. For now, we keep an assert to make sure we use the same resume phi as before. This will be removed in the future.
1 parent c1add93 commit d478502

File tree

2 files changed

+45
-31
lines changed

2 files changed

+45
-31
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9782,17 +9782,26 @@ static void preparePlanForMainVectorLoop(VPlan &MainPlan, VPlan &EpiPlan) {
97829782
VPBasicBlock *MainScalarPH = MainPlan.getScalarPreheader();
97839783
VPValue *VectorTC = &MainPlan.getVectorTripCount();
97849784
// If there is a suitable resume value for the canonical induction in the
9785-
// scalar (which will become vector) epilogue loop we are done. Otherwise
9786-
// create it below.
9787-
if (any_of(*MainScalarPH, [VectorTC](VPRecipeBase &R) {
9785+
// scalar (which will become vector) epilogue loop, use it and move it to the
9786+
// beginning of the scalar preheader. Otherwise create it below.
9787+
auto ResumePhiIter =
9788+
find_if(MainScalarPH->phis(), [VectorTC](VPRecipeBase &R) {
97889789
return match(&R, m_VPInstruction<Instruction::PHI>(m_Specific(VectorTC),
97899790
m_SpecificInt(0)));
9790-
}))
9791-
return;
9792-
VPBuilder ScalarPHBuilder(MainScalarPH, MainScalarPH->begin());
9793-
ScalarPHBuilder.createScalarPhi(
9794-
{VectorTC, MainPlan.getCanonicalIV()->getStartValue()}, {},
9795-
"vec.epilog.resume.val");
9791+
});
9792+
VPPhi *ResumePhi = nullptr;
9793+
if (ResumePhiIter == MainScalarPH->phis().end()) {
9794+
VPBuilder ScalarPHBuilder(MainScalarPH, MainScalarPH->begin());
9795+
ResumePhi = ScalarPHBuilder.createScalarPhi(
9796+
{VectorTC, MainPlan.getCanonicalIV()->getStartValue()}, {},
9797+
"vec.epilog.resume.val");
9798+
} else {
9799+
ResumePhi = cast<VPPhi>(&*ResumePhiIter);
9800+
if (MainScalarPH->begin() == MainScalarPH->end())
9801+
ResumePhi->moveBefore(*MainScalarPH, MainScalarPH->end());
9802+
else if (&*MainScalarPH->begin() != ResumePhi)
9803+
ResumePhi->moveBefore(*MainScalarPH, MainScalarPH->begin());
9804+
}
97969805
}
97979806

97989807
/// Prepare \p Plan for vectorizing the epilogue loop. That is, re-use expanded
@@ -9813,30 +9822,35 @@ preparePlanForEpilogueVectorLoop(VPlan &Plan, Loop *L,
98139822
// When vectorizing the epilogue loop, the canonical induction start
98149823
// value needs to be changed from zero to the value after the main
98159824
// vector loop. Find the resume value created during execution of the main
9816-
// VPlan.
9825+
// VPlan. It must be the first phi in the loop preheader.
98179826
// FIXME: Improve modeling for canonical IV start values in the epilogue
98189827
// loop.
98199828
using namespace llvm::PatternMatch;
9820-
Type *IdxTy = IV->getScalarType();
9821-
PHINode *EPResumeVal = find_singleton<PHINode>(
9822-
L->getLoopPreheader()->phis(),
9823-
[&EPI, IdxTy](PHINode &P, bool) -> PHINode * {
9824-
if (P.getType() == IdxTy &&
9825-
match(
9826-
P.getIncomingValueForBlock(EPI.MainLoopIterationCountCheck),
9827-
m_SpecificInt(0)) &&
9828-
any_of(P.incoming_values(),
9829-
[&EPI](Value *Inc) {
9830-
return Inc == EPI.VectorTripCount;
9831-
}) &&
9832-
all_of(P.incoming_values(), [&EPI](Value *Inc) {
9833-
return Inc == EPI.VectorTripCount ||
9834-
match(Inc, m_SpecificInt(0));
9835-
}))
9836-
return &P;
9837-
return nullptr;
9838-
});
9839-
assert(EPResumeVal && "must have a resume value for the canonical IV");
9829+
PHINode *EPResumeVal = &*L->getLoopPreheader()->phis().begin();
9830+
assert(EPResumeVal->getType() == IV->getScalarType() &&
9831+
match(EPResumeVal->getIncomingValueForBlock(
9832+
EPI.MainLoopIterationCountCheck),
9833+
m_SpecificInt(0)) &&
9834+
EPResumeVal ==
9835+
find_singleton<PHINode>(
9836+
L->getLoopPreheader()->phis(),
9837+
[&EPI, IV](PHINode &P, bool) -> PHINode * {
9838+
if (P.getType() == IV->getScalarType() &&
9839+
match(P.getIncomingValueForBlock(
9840+
EPI.MainLoopIterationCountCheck),
9841+
m_SpecificInt(0)) &&
9842+
any_of(P.incoming_values(),
9843+
[&EPI](Value *Inc) {
9844+
return Inc == EPI.VectorTripCount;
9845+
}) &&
9846+
all_of(P.incoming_values(), [&EPI](Value *Inc) {
9847+
return Inc == EPI.VectorTripCount ||
9848+
match(Inc, m_SpecificInt(0));
9849+
}))
9850+
return &P;
9851+
return nullptr;
9852+
}) &&
9853+
"Epilogue resume phis do not match!");
98409854
VPValue *VPV = Plan.getOrAddLiveIn(EPResumeVal);
98419855
assert(all_of(IV->users(),
98429856
[](const VPUser *U) {

llvm/test/Transforms/LoopVectorize/epilog-vectorization-reductions.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,8 +606,8 @@ define i64 @test_reduction_with_widen_induction_order_2(ptr %A, i64 %N) {
606606
; CHECK-NEXT: [[MIN_EPILOG_ITERS_CHECK:%.*]] = icmp ult i64 [[N_VEC_REMAINING]], 4
607607
; CHECK-NEXT: br i1 [[MIN_EPILOG_ITERS_CHECK]], label [[VEC_EPILOG_SCALAR_PH]], label [[VEC_EPILOG_PH]]
608608
; CHECK: vec.epilog.ph:
609-
; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi i64 [ [[TMP3]], [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[VECTOR_MAIN_LOOP_ITER_CHECK]] ]
610609
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[VECTOR_MAIN_LOOP_ITER_CHECK]] ]
610+
; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi i64 [ [[TMP3]], [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[VECTOR_MAIN_LOOP_ITER_CHECK]] ]
611611
; CHECK-NEXT: [[N_MOD_VF2:%.*]] = urem i64 [[N]], 4
612612
; CHECK-NEXT: [[N_VEC3:%.*]] = sub i64 [[N]], [[N_MOD_VF2]]
613613
; CHECK-NEXT: [[TMP4:%.*]] = insertelement <4 x i64> zeroinitializer, i64 [[BC_MERGE_RDX]], i32 0

0 commit comments

Comments
 (0)