@@ -451,6 +451,30 @@ static void addCanonicalIVRecipes(VPlan &Plan, VPBasicBlock *HeaderVPBB,
451451 LatchDL);
452452}
453453
454+ // / Creates extracts for values in \p Plan defined in a loop region and used
455+ // / outside a loop region.
456+ static void createExtractsForLiveOuts (VPlan &Plan, VPBasicBlock *MiddleVPBB) {
457+ VPBuilder B (MiddleVPBB, MiddleVPBB->getFirstNonPhi ());
458+ for (VPBasicBlock *EB : Plan.getExitBlocks ()) {
459+ if (EB->getSinglePredecessor () != MiddleVPBB)
460+ continue ;
461+
462+ for (VPRecipeBase &R : EB->phis ()) {
463+ auto *ExitIRI = cast<VPIRPhi>(&R);
464+ for (unsigned Idx = 0 ; Idx != ExitIRI->getNumIncoming (); ++Idx) {
465+ VPRecipeBase *Inc = ExitIRI->getIncomingValue (Idx)->getDefiningRecipe ();
466+ if (!Inc)
467+ continue ;
468+ assert (ExitIRI->getNumOperands () == 1 &&
469+ ExitIRI->getParent ()->getSinglePredecessor () == MiddleVPBB &&
470+ " exit values from early exits must be fixed when branch to "
471+ " early-exit is added" );
472+ ExitIRI->extractLastLaneOfFirstOperand (B);
473+ }
474+ }
475+ }
476+ }
477+
454478static void addInitialSkeleton (VPlan &Plan, Type *InductionTy, DebugLoc IVDL,
455479 PredicatedScalarEvolution &PSE, Loop *TheLoop) {
456480 VPDominatorTree VPDT;
@@ -500,6 +524,8 @@ static void addInitialSkeleton(VPlan &Plan, Type *InductionTy, DebugLoc IVDL,
500524 // check.
501525 VPBlockUtils::connectBlocks (Plan.getEntry (), ScalarPH);
502526 Plan.getEntry ()->swapSuccessors ();
527+
528+ createExtractsForLiveOuts (Plan, MiddleVPBB);
503529}
504530
505531std::unique_ptr<VPlan>
@@ -607,30 +633,6 @@ void VPlanTransforms::createLoopRegions(VPlan &Plan) {
607633 TopRegion->getEntryBasicBlock ()->setName (" vector.body" );
608634}
609635
610- void VPlanTransforms::createExtractsForLiveOuts (VPlan &Plan) {
611- for (VPBasicBlock *EB : Plan.getExitBlocks ()) {
612- VPBasicBlock *MiddleVPBB = Plan.getMiddleBlock ();
613- VPBuilder B (MiddleVPBB, MiddleVPBB->getFirstNonPhi ());
614-
615- if (EB->getSinglePredecessor () != Plan.getMiddleBlock ())
616- continue ;
617-
618- for (VPRecipeBase &R : EB->phis ()) {
619- auto *ExitIRI = cast<VPIRPhi>(&R);
620- for (unsigned Idx = 0 ; Idx != ExitIRI->getNumIncoming (); ++Idx) {
621- VPRecipeBase *Inc = ExitIRI->getIncomingValue (Idx)->getDefiningRecipe ();
622- if (!Inc || !Inc->getParent ()->getParent ())
623- continue ;
624- assert (ExitIRI->getNumOperands () == 1 &&
625- ExitIRI->getParent ()->getSinglePredecessor () == MiddleVPBB &&
626- " exit values from early exits must be fixed when branch to "
627- " early-exit is added" );
628- ExitIRI->extractLastLaneOfFirstOperand (B);
629- }
630- }
631- }
632- }
633-
634636// Likelyhood of bypassing the vectorized loop due to a runtime check block,
635637// including memory overlap checks block and wrapping/unit-stride checks block.
636638static constexpr uint32_t CheckBypassWeights[] = {1 , 127 };
0 commit comments