@@ -2488,64 +2488,86 @@ void VPlanTransforms::convertToConcreteRecipes(VPlan &Plan,
24882488 R->eraseFromParent ();
24892489}
24902490
2491- void VPlanTransforms::handleUncountableEarlyExit (
2492- VPlan &Plan, Loop *OrigLoop, BasicBlock *UncountableExitingBlock,
2493- VPRecipeBuilder &RecipeBuilder, VFRange &Range) {
2494- VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion ();
2495- auto *LatchVPBB = cast<VPBasicBlock>(LoopRegion->getExiting ());
2491+ void VPlanTransforms::handleUncountableEarlyExit (VPlan &Plan,
2492+ VPBasicBlock *HeaderVPBB,
2493+ VPBasicBlock *LatchVPBB,
2494+ VFRange &Range) {
2495+ // First find the uncountable early exiting block by looking at the
2496+ // predecessors of the exit blocks.
2497+ VPBlockBase *MiddleVPBB = LatchVPBB->getSuccessors ()[0 ];
2498+ VPBasicBlock *EarlyExitingVPBB = nullptr ;
2499+ VPIRBasicBlock *EarlyExitVPBB = nullptr ;
2500+ for (auto *EB : Plan.getExitBlocks ()) {
2501+ for (VPBlockBase *Pred : EB->getPredecessors ()) {
2502+ if (Pred != MiddleVPBB) {
2503+ EarlyExitingVPBB = cast<VPBasicBlock>(Pred);
2504+ EarlyExitVPBB = EB;
2505+ break ;
2506+ }
2507+ }
2508+ }
2509+ assert (EarlyExitVPBB && " Must have a early exiting block." );
2510+ assert (all_of (Plan.getExitBlocks (),
2511+ [EarlyExitingVPBB, MiddleVPBB](VPIRBasicBlock *EB) {
2512+ return all_of (
2513+ EB->getPredecessors (),
2514+ [EarlyExitingVPBB, MiddleVPBB](VPBlockBase *Pred) {
2515+ return Pred == EarlyExitingVPBB || Pred == MiddleVPBB;
2516+ });
2517+ }) &&
2518+ " All exit blocks must only have EarlyExitingVPBB or MiddleVPBB as "
2519+ " predecessors." );
2520+
24962521 VPBuilder Builder (LatchVPBB->getTerminator ());
2497- auto *MiddleVPBB = Plan.getMiddleBlock ();
2498- VPValue *IsEarlyExitTaken = nullptr ;
2499-
2500- // Process the uncountable exiting block. Update IsEarlyExitTaken, which
2501- // tracks if the uncountable early exit has been taken. Also split the middle
2502- // block and have it conditionally branch to the early exit block if
2503- // EarlyExitTaken.
2504- auto *EarlyExitingBranch =
2505- cast<BranchInst>(UncountableExitingBlock->getTerminator ());
2506- BasicBlock *TrueSucc = EarlyExitingBranch->getSuccessor (0 );
2507- BasicBlock *FalseSucc = EarlyExitingBranch->getSuccessor (1 );
2508- BasicBlock *EarlyExitIRBB =
2509- !OrigLoop->contains (TrueSucc) ? TrueSucc : FalseSucc;
2510- VPIRBasicBlock *VPEarlyExitBlock = Plan.getExitBlock (EarlyExitIRBB);
2511-
2512- VPValue *EarlyExitNotTakenCond = RecipeBuilder.getBlockInMask (
2513- OrigLoop->contains (TrueSucc) ? TrueSucc : FalseSucc);
2514- auto *EarlyExitTakenCond = Builder.createNot (EarlyExitNotTakenCond);
2515- IsEarlyExitTaken =
2516- Builder.createNaryOp (VPInstruction::AnyOf, {EarlyExitTakenCond});
2522+ VPBlockBase *TrueSucc = EarlyExitingVPBB->getSuccessors ()[0 ];
2523+ VPValue *EarlyExitCond = EarlyExitingVPBB->getTerminator ()->getOperand (0 );
2524+ auto *EarlyExitTakenCond = TrueSucc == EarlyExitVPBB
2525+ ? EarlyExitCond
2526+ : Builder.createNot (EarlyExitCond);
2527+
2528+ if (!EarlyExitVPBB->getSinglePredecessor () &&
2529+ EarlyExitVPBB->getPredecessors ()[0 ] != MiddleVPBB) {
2530+ for (VPRecipeBase &R : EarlyExitVPBB->phis ()) {
2531+ // Early exit operand should always be last, i.e., 0 if EarlyExitVPBB has
2532+ // a single predecessor and 1 if it has two.
2533+ // If EarlyExitVPBB has two predecessors, they are already ordered such
2534+ // that early exit is second (and latch exit is first), by construction.
2535+ // But its underlying IRBB (EarlyExitIRBB) may have its predecessors
2536+ // ordered the other way around, and it is the order of the latter which
2537+ // corresponds to the order of operands of EarlyExitVPBB's phi recipes.
2538+ // Therefore, if early exit (UncountableExitingBlock) is the first
2539+ // predecessor of EarlyExitIRBB, we swap the operands of phi recipes,
2540+ // thereby bringing them to match EarlyExitVPBB's predecessor order,
2541+ // with early exit being last (second). Otherwise they already match.
2542+ cast<VPIRPhi>(&R)->swapOperands ();
2543+ }
2544+ }
25172545
2546+ EarlyExitingVPBB->getTerminator ()->eraseFromParent ();
2547+ VPBlockUtils::disconnectBlocks (EarlyExitingVPBB, EarlyExitVPBB);
2548+
2549+ // Split the middle block and have it conditionally branch to the early exit
2550+ // block if EarlyExitTaken.
2551+ VPValue *IsEarlyExitTaken =
2552+ Builder.createNaryOp (VPInstruction::AnyOf, {EarlyExitTakenCond});
25182553 VPBasicBlock *NewMiddle = Plan.createVPBasicBlock (" middle.split" );
25192554 VPBasicBlock *VectorEarlyExitVPBB =
25202555 Plan.createVPBasicBlock (" vector.early.exit" );
2521- VPBlockUtils::insertOnEdge (LoopRegion , MiddleVPBB, NewMiddle);
2556+ VPBlockUtils::insertOnEdge (LatchVPBB , MiddleVPBB, NewMiddle);
25222557 VPBlockUtils::connectBlocks (NewMiddle, VectorEarlyExitVPBB);
25232558 NewMiddle->swapSuccessors ();
25242559
2525- VPBlockUtils::connectBlocks (VectorEarlyExitVPBB, VPEarlyExitBlock );
2560+ VPBlockUtils::connectBlocks (VectorEarlyExitVPBB, EarlyExitVPBB );
25262561
25272562 // Update the exit phis in the early exit block.
25282563 VPBuilder MiddleBuilder (NewMiddle);
25292564 VPBuilder EarlyExitB (VectorEarlyExitVPBB);
2530- for (VPRecipeBase &R : VPEarlyExitBlock ->phis ()) {
2565+ for (VPRecipeBase &R : EarlyExitVPBB ->phis ()) {
25312566 auto *ExitIRI = cast<VPIRPhi>(&R);
2532- // Early exit operand should always be last, i.e., 0 if VPEarlyExitBlock has
2567+ // Early exit operand should always be last, i.e., 0 if EarlyExitVPBB has
25332568 // a single predecessor and 1 if it has two.
25342569 unsigned EarlyExitIdx = ExitIRI->getNumOperands () - 1 ;
2535- if (!VPEarlyExitBlock->getSinglePredecessor ()) {
2536- // If VPEarlyExitBlock has two predecessors, they are already ordered such
2537- // that early exit is second (and latch exit is first), by construction.
2538- // But its underlying IRBB (EarlyExitIRBB) may have its predecessors
2539- // ordered the other way around, and it is the order of the latter which
2540- // corresponds to the order of operands of VPEarlyExitBlock's phi recipes.
2541- // Therefore, if early exit (UncountableExitingBlock) is the first
2542- // predecessor of EarlyExitIRBB, we swap the operands of phi recipes,
2543- // thereby bringing them to match VPEarlyExitBlock's predecessor order,
2544- // with early exit being last (second). Otherwise they already match.
2545- if (*pred_begin (VPEarlyExitBlock->getIRBasicBlock ()) ==
2546- UncountableExitingBlock)
2547- ExitIRI->swapOperands ();
2548-
2570+ if (!EarlyExitVPBB->getSinglePredecessor ()) {
25492571 // The first of two operands corresponds to the latch exit, via MiddleVPBB
25502572 // predecessor. Extract its last lane.
25512573 ExitIRI->extractLastLaneOfFirstOperand (MiddleBuilder);
0 commit comments