@@ -9782,17 +9782,26 @@ static void preparePlanForMainVectorLoop(VPlan &MainPlan, VPlan &EpiPlan) {
9782
9782
VPBasicBlock *MainScalarPH = MainPlan.getScalarPreheader ();
9783
9783
VPValue *VectorTC = &MainPlan.getVectorTripCount ();
9784
9784
// 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) {
9788
9789
return match (&R, m_VPInstruction<Instruction::PHI>(m_Specific (VectorTC),
9789
9790
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
+ }
9796
9805
}
9797
9806
9798
9807
// / Prepare \p Plan for vectorizing the epilogue loop. That is, re-use expanded
@@ -9813,30 +9822,35 @@ preparePlanForEpilogueVectorLoop(VPlan &Plan, Loop *L,
9813
9822
// When vectorizing the epilogue loop, the canonical induction start
9814
9823
// value needs to be changed from zero to the value after the main
9815
9824
// 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.
9817
9826
// FIXME: Improve modeling for canonical IV start values in the epilogue
9818
9827
// loop.
9819
9828
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!" );
9840
9854
VPValue *VPV = Plan.getOrAddLiveIn (EPResumeVal);
9841
9855
assert (all_of (IV->users (),
9842
9856
[](const VPUser *U) {
0 commit comments