@@ -2458,64 +2458,86 @@ void VPlanTransforms::convertToConcreteRecipes(VPlan &Plan,
24582458 R->eraseFromParent ();
24592459}
24602460
2461- void VPlanTransforms::handleUncountableEarlyExit (
2462- VPlan &Plan, Loop *OrigLoop, BasicBlock *UncountableExitingBlock,
2463- VPRecipeBuilder &RecipeBuilder, VFRange &Range) {
2464- VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion ();
2465- auto *LatchVPBB = cast<VPBasicBlock>(LoopRegion->getExiting ());
2461+ void VPlanTransforms::handleUncountableEarlyExit (VPlan &Plan,
2462+ VPBasicBlock *HeaderVPBB,
2463+ VPBasicBlock *LatchVPBB,
2464+ VFRange &Range) {
2465+ // First find the uncountable early exiting block by looking at the
2466+ // predecessors of the exit blocks.
2467+ VPBlockBase *MiddleVPBB = LatchVPBB->getSuccessors ()[0 ];
2468+ VPBasicBlock *EarlyExitingVPBB = nullptr ;
2469+ VPIRBasicBlock *EarlyExitVPBB = nullptr ;
2470+ for (auto *EB : Plan.getExitBlocks ()) {
2471+ for (VPBlockBase *Pred : EB->getPredecessors ()) {
2472+ if (Pred != MiddleVPBB) {
2473+ EarlyExitingVPBB = cast<VPBasicBlock>(Pred);
2474+ EarlyExitVPBB = EB;
2475+ break ;
2476+ }
2477+ }
2478+ }
2479+ assert (EarlyExitVPBB && " Must have a early exiting block." );
2480+ assert (all_of (Plan.getExitBlocks (),
2481+ [EarlyExitingVPBB, MiddleVPBB](VPIRBasicBlock *EB) {
2482+ return all_of (
2483+ EB->getPredecessors (),
2484+ [EarlyExitingVPBB, MiddleVPBB](VPBlockBase *Pred) {
2485+ return Pred == EarlyExitingVPBB || Pred == MiddleVPBB;
2486+ });
2487+ }) &&
2488+ " All exit blocks must only have EarlyExitingVPBB or MiddleVPBB as "
2489+ " predecessors." );
2490+
24662491 VPBuilder Builder (LatchVPBB->getTerminator ());
2467- auto *MiddleVPBB = Plan.getMiddleBlock ();
2468- VPValue *IsEarlyExitTaken = nullptr ;
2469-
2470- // Process the uncountable exiting block. Update IsEarlyExitTaken, which
2471- // tracks if the uncountable early exit has been taken. Also split the middle
2472- // block and have it conditionally branch to the early exit block if
2473- // EarlyExitTaken.
2474- auto *EarlyExitingBranch =
2475- cast<BranchInst>(UncountableExitingBlock->getTerminator ());
2476- BasicBlock *TrueSucc = EarlyExitingBranch->getSuccessor (0 );
2477- BasicBlock *FalseSucc = EarlyExitingBranch->getSuccessor (1 );
2478- BasicBlock *EarlyExitIRBB =
2479- !OrigLoop->contains (TrueSucc) ? TrueSucc : FalseSucc;
2480- VPIRBasicBlock *VPEarlyExitBlock = Plan.getExitBlock (EarlyExitIRBB);
2481-
2482- VPValue *EarlyExitNotTakenCond = RecipeBuilder.getBlockInMask (
2483- OrigLoop->contains (TrueSucc) ? TrueSucc : FalseSucc);
2484- auto *EarlyExitTakenCond = Builder.createNot (EarlyExitNotTakenCond);
2485- IsEarlyExitTaken =
2486- Builder.createNaryOp (VPInstruction::AnyOf, {EarlyExitTakenCond});
2492+ VPBlockBase *TrueSucc = EarlyExitingVPBB->getSuccessors ()[0 ];
2493+ VPValue *EarlyExitCond = EarlyExitingVPBB->getTerminator ()->getOperand (0 );
2494+ auto *EarlyExitTakenCond = TrueSucc == EarlyExitVPBB
2495+ ? EarlyExitCond
2496+ : Builder.createNot (EarlyExitCond);
2497+
2498+ if (!EarlyExitVPBB->getSinglePredecessor () &&
2499+ EarlyExitVPBB->getPredecessors ()[0 ] != MiddleVPBB) {
2500+ for (VPRecipeBase &R : EarlyExitVPBB->phis ()) {
2501+ // Early exit operand should always be last, i.e., 0 if EarlyExitVPBB has
2502+ // a single predecessor and 1 if it has two.
2503+ // If EarlyExitVPBB has two predecessors, they are already ordered such
2504+ // that early exit is second (and latch exit is first), by construction.
2505+ // But its underlying IRBB (EarlyExitIRBB) may have its predecessors
2506+ // ordered the other way around, and it is the order of the latter which
2507+ // corresponds to the order of operands of EarlyExitVPBB's phi recipes.
2508+ // Therefore, if early exit (UncountableExitingBlock) is the first
2509+ // predecessor of EarlyExitIRBB, we swap the operands of phi recipes,
2510+ // thereby bringing them to match EarlyExitVPBB's predecessor order,
2511+ // with early exit being last (second). Otherwise they already match.
2512+ cast<VPIRPhi>(&R)->swapOperands ();
2513+ }
2514+ }
24872515
2516+ EarlyExitingVPBB->getTerminator ()->eraseFromParent ();
2517+ VPBlockUtils::disconnectBlocks (EarlyExitingVPBB, EarlyExitVPBB);
2518+
2519+ // Split the middle block and have it conditionally branch to the early exit
2520+ // block if EarlyExitTaken.
2521+ VPValue *IsEarlyExitTaken =
2522+ Builder.createNaryOp (VPInstruction::AnyOf, {EarlyExitTakenCond});
24882523 VPBasicBlock *NewMiddle = Plan.createVPBasicBlock (" middle.split" );
24892524 VPBasicBlock *VectorEarlyExitVPBB =
24902525 Plan.createVPBasicBlock (" vector.early.exit" );
2491- VPBlockUtils::insertOnEdge (LoopRegion , MiddleVPBB, NewMiddle);
2526+ VPBlockUtils::insertOnEdge (LatchVPBB , MiddleVPBB, NewMiddle);
24922527 VPBlockUtils::connectBlocks (NewMiddle, VectorEarlyExitVPBB);
24932528 NewMiddle->swapSuccessors ();
24942529
2495- VPBlockUtils::connectBlocks (VectorEarlyExitVPBB, VPEarlyExitBlock );
2530+ VPBlockUtils::connectBlocks (VectorEarlyExitVPBB, EarlyExitVPBB );
24962531
24972532 // Update the exit phis in the early exit block.
24982533 VPBuilder MiddleBuilder (NewMiddle);
24992534 VPBuilder EarlyExitB (VectorEarlyExitVPBB);
2500- for (VPRecipeBase &R : VPEarlyExitBlock ->phis ()) {
2535+ for (VPRecipeBase &R : EarlyExitVPBB ->phis ()) {
25012536 auto *ExitIRI = cast<VPIRPhi>(&R);
2502- // Early exit operand should always be last, i.e., 0 if VPEarlyExitBlock has
2537+ // Early exit operand should always be last, i.e., 0 if EarlyExitVPBB has
25032538 // a single predecessor and 1 if it has two.
25042539 unsigned EarlyExitIdx = ExitIRI->getNumOperands () - 1 ;
2505- if (!VPEarlyExitBlock->getSinglePredecessor ()) {
2506- // If VPEarlyExitBlock has two predecessors, they are already ordered such
2507- // that early exit is second (and latch exit is first), by construction.
2508- // But its underlying IRBB (EarlyExitIRBB) may have its predecessors
2509- // ordered the other way around, and it is the order of the latter which
2510- // corresponds to the order of operands of VPEarlyExitBlock's phi recipes.
2511- // Therefore, if early exit (UncountableExitingBlock) is the first
2512- // predecessor of EarlyExitIRBB, we swap the operands of phi recipes,
2513- // thereby bringing them to match VPEarlyExitBlock's predecessor order,
2514- // with early exit being last (second). Otherwise they already match.
2515- if (*pred_begin (VPEarlyExitBlock->getIRBasicBlock ()) ==
2516- UncountableExitingBlock)
2517- ExitIRI->swapOperands ();
2518-
2540+ if (!EarlyExitVPBB->getSinglePredecessor ()) {
25192541 // The first of two operands corresponds to the latch exit, via MiddleVPBB
25202542 // predecessor. Extract its last lane.
25212543 ExitIRI->extractLastLaneOfFirstOperand (MiddleBuilder);
0 commit comments