@@ -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) {
0 commit comments