@@ -8630,11 +8630,12 @@ static void addCanonicalIVRecipes(VPlan &Plan, Type *IdxTy, bool HasNUW,
86308630 {CanonicalIVIncrement, &Plan.getVectorTripCount ()}, DL);
86318631}
86328632
8633- // Collect (ExitPhi, ExitingValue) pairs phis in the original exit block that
8634- // are modeled in VPlan. Some exiting values are not modeled explicitly yet and
8635- // won't be included. Those are un-truncated VPWidenIntOrFpInductionRecipe,
8636- // VPWidenPointerInductionRecipe and induction increments.
8637- static MapVector<PHINode *, VPValue *> collectUsersInExitBlock (
8633+ // Collect VPIRInstructions for phis in the original exit block that are modeled
8634+ // in VPlan and add the exiting VPValue as operand. Some exiting values are not
8635+ // modeled explicitly yet and won't be included. Those are un-truncated
8636+ // VPWidenIntOrFpInductionRecipe, VPWidenPointerInductionRecipe and induction
8637+ // increments.
8638+ static SetVector<VPIRInstruction *> collectUsersInExitBlock (
86388639 Loop *OrigLoop, VPRecipeBuilder &Builder, VPlan &Plan,
86398640 const MapVector<PHINode *, InductionDescriptor> &Inductions) {
86408641 auto *MiddleVPBB =
@@ -8644,13 +8645,17 @@ static MapVector<PHINode *, VPValue *> collectUsersInExitBlock(
86448645 // from scalar loop only.
86458646 if (MiddleVPBB->getNumSuccessors () != 2 )
86468647 return {};
8647- MapVector<PHINode *, VPValue *> ExitingValuesToFix;
8648- BasicBlock *ExitBB =
8649- cast<VPIRBasicBlock>(MiddleVPBB->getSuccessors ()[0 ])->getIRBasicBlock ();
8648+ SetVector<VPIRInstruction *> ExitUsersToFix;
8649+ VPBasicBlock *ExitVPBB = cast<VPIRBasicBlock>(MiddleVPBB->getSuccessors ()[0 ]);
86508650 BasicBlock *ExitingBB = OrigLoop->getExitingBlock ();
8651- for (PHINode &ExitPhi : ExitBB->phis ()) {
8652- Value *IncomingValue =
8653- ExitPhi.getIncomingValueForBlock (ExitingBB);
8651+ for (VPRecipeBase &R : *ExitVPBB) {
8652+ auto *ExitIRI = dyn_cast<VPIRInstruction>(&R);
8653+ if (!ExitIRI)
8654+ continue ;
8655+ auto *ExitPhi = dyn_cast<PHINode>(&ExitIRI->getInstruction ());
8656+ if (!ExitPhi)
8657+ break ;
8658+ Value *IncomingValue = ExitPhi->getIncomingValueForBlock (ExitingBB);
86548659 VPValue *V = Builder.getVPValueOrAddLiveIn (IncomingValue);
86558660 // Exit values for inductions are computed and updated outside of VPlan and
86568661 // independent of induction recipes.
@@ -8666,17 +8671,18 @@ static MapVector<PHINode *, VPValue *> collectUsersInExitBlock(
86668671 return P && Inductions.contains (P);
86678672 })))
86688673 continue ;
8669- ExitingValuesToFix.insert ({&ExitPhi, V});
8674+ ExitUsersToFix.insert (ExitIRI);
8675+ ExitIRI->addOperand (V);
86708676 }
8671- return ExitingValuesToFix ;
8677+ return ExitUsersToFix ;
86728678}
86738679
8674- // Add exit values to \p Plan. Extracts and VPLiveOuts are added for each entry
8675- // in \p ExitingValuesToFix .
8680+ // Add exit values to \p Plan. Extracts are added for each entry in \p
8681+ // ExitUsersToFix if needed and their operands are updated .
86768682static void
86778683addUsersInExitBlock (VPlan &Plan,
8678- MapVector<PHINode *, VPValue * > &ExitingValuesToFix ) {
8679- if (ExitingValuesToFix .empty ())
8684+ const SetVector<VPIRInstruction * > &ExitUsersToFix ) {
8685+ if (ExitUsersToFix .empty ())
86808686 return ;
86818687
86828688 auto *MiddleVPBB =
@@ -8685,18 +8691,19 @@ addUsersInExitBlock(VPlan &Plan,
86858691 cast<VPIRBasicBlock>(MiddleVPBB->getSuccessors ()[0 ])->getIRBasicBlock ();
86868692 VPBuilder B (MiddleVPBB, MiddleVPBB->getFirstNonPhi ());
86878693
8688- // Introduce VPUsers modeling the exit values.
8689- for (const auto &[ExitPhi, V] : ExitingValuesToFix) {
8694+ // Introduce extract for exiting values and update the VPIRInstructions
8695+ // modeling the corresponding LCSSA phis.
8696+ for (VPIRInstruction *ExitIRI : ExitUsersToFix) {
8697+ VPValue *V = ExitIRI->getOperand (0 );
86908698 // Pass live-in values used by exit phis directly through to the live-out.
8691- if (V->isLiveIn ()) {
8692- Plan.addLiveOut (ExitPhi, V);
8699+ if (V->isLiveIn ())
86938700 continue ;
8694- }
8701+
86958702 VPValue *Ext = B.createNaryOp (
86968703 VPInstruction::ExtractFromEnd,
86978704 {V, Plan.getOrAddLiveIn (ConstantInt::get (
86988705 IntegerType::get (ExitBB->getContext (), 32 ), 1 ))});
8699- Plan. addLiveOut (ExitPhi , Ext);
8706+ ExitIRI-> setOperand ( 0 , Ext);
87008707 }
87018708}
87028709
@@ -8709,7 +8716,7 @@ addUsersInExitBlock(VPlan &Plan,
87098716// / 2. Feed the penultimate value of recurrences to their LCSSA phi users in
87108717// / the original exit block using a VPLiveOut.
87118718static void addLiveOutsForFirstOrderRecurrences (
8712- VPlan &Plan, MapVector<PHINode *, VPValue * > &ExitingValuesToFix ) {
8719+ VPlan &Plan, SetVector<VPIRInstruction * > &ExitUsersToFix ) {
87138720 VPRegionBlock *VectorRegion = Plan.getVectorLoopRegion ();
87148721
87158722 // Start by finding out if middle block branches to scalar preheader, which is
@@ -8726,14 +8733,14 @@ static void addLiveOutsForFirstOrderRecurrences(
87268733 ExitBB =
87278734 cast<VPIRBasicBlock>(MiddleVPBB->getSuccessors ()[0 ])->getIRBasicBlock ();
87288735 ScalarPHVPBB = cast<VPBasicBlock>(MiddleVPBB->getSuccessors ()[1 ]);
8729- } else if (ExitingValuesToFix .empty ()) {
8736+ } else if (ExitUsersToFix .empty ()) {
87308737 ScalarPHVPBB = cast<VPBasicBlock>(MiddleVPBB->getSingleSuccessor ());
87318738 } else {
87328739 ExitBB = cast<VPIRBasicBlock>(MiddleVPBB->getSingleSuccessor ())
87338740 ->getIRBasicBlock ();
87348741 }
87358742 if (!ScalarPHVPBB) {
8736- assert (ExitingValuesToFix .empty () &&
8743+ assert (ExitUsersToFix .empty () &&
87378744 " missed inserting extracts for exiting values" );
87388745 return ;
87398746 }
@@ -8827,24 +8834,17 @@ static void addLiveOutsForFirstOrderRecurrences(
88278834 auto *FORPhi = cast<PHINode>(FOR->getUnderlyingInstr ());
88288835 Plan.addLiveOut (FORPhi, ResumePhiRecipe);
88298836
8830- // Now create VPLiveOuts for users in the exit block.
8831- // Extract the penultimate value of the recurrence and add VPLiveOut
8832- // users of the recurrence splice.
8833-
8834- // No edge from the middle block to the unique exit block has been inserted
8835- // and there is nothing to fix from vector loop; phis should have incoming
8836- // from scalar loop only.
8837- if (ExitingValuesToFix.empty ())
8838- continue ;
8839- for (User *U : FORPhi->users ()) {
8840- auto *UI = cast<Instruction>(U);
8841- if (UI->getParent () != ExitBB)
8837+ // Now update VPIRInstructions modeling LCSSA phis in the exit block.
8838+ // Extract the penultimate value of the recurrence and use it as operand for
8839+ // the VPIRInstruction modeling the phi.
8840+ for (VPIRInstruction *ExitIRI : ExitUsersToFix) {
8841+ if (ExitIRI->getOperand (0 ) != FOR)
88428842 continue ;
88438843 VPValue *Ext = MiddleBuilder.createNaryOp (
88448844 VPInstruction::ExtractFromEnd, {FOR->getBackedgeValue (), TwoVPV}, {},
88458845 " vector.recur.extract.for.phi" );
8846- Plan. addLiveOut (cast<PHINode>(UI) , Ext);
8847- ExitingValuesToFix. erase (cast<PHINode>(UI) );
8846+ ExitIRI-> setOperand ( 0 , Ext);
8847+ ExitUsersToFix. remove (ExitIRI );
88488848 }
88498849 }
88508850}
@@ -9006,11 +9006,10 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
90069006 " VPBasicBlock" );
90079007 RecipeBuilder.fixHeaderPhis ();
90089008
9009- MapVector<PHINode *, VPValue *> ExitingValuesToFix = collectUsersInExitBlock (
9009+ SetVector<VPIRInstruction *> ExitUsersToFix = collectUsersInExitBlock (
90109010 OrigLoop, RecipeBuilder, *Plan, Legal->getInductionVars ());
9011-
9012- addLiveOutsForFirstOrderRecurrences (*Plan, ExitingValuesToFix);
9013- addUsersInExitBlock (*Plan, ExitingValuesToFix);
9011+ addLiveOutsForFirstOrderRecurrences (*Plan, ExitUsersToFix);
9012+ addUsersInExitBlock (*Plan, ExitUsersToFix);
90149013
90159014 // ---------------------------------------------------------------------------
90169015 // Transform initial VPlan: Apply previously taken decisions, in order, to
@@ -10128,7 +10127,9 @@ bool LoopVectorizePass::processLoop(Loop *L) {
1012810127 // directly in VPlan.
1012910128 EpilogILV.setTripCount (MainILV.getTripCount ());
1013010129 for (auto &R : make_early_inc_range (*BestEpiPlan.getPreheader ())) {
10131- auto *ExpandR = cast<VPExpandSCEVRecipe>(&R);
10130+ auto *ExpandR = dyn_cast<VPExpandSCEVRecipe>(&R);
10131+ if (!ExpandR)
10132+ continue ;
1013210133 auto *ExpandedVal = BestEpiPlan.getOrAddLiveIn (
1013310134 ExpandedSCEVs.find (ExpandR->getSCEV ())->second );
1013410135 ExpandR->replaceAllUsesWith (ExpandedVal);
0 commit comments