@@ -2505,35 +2505,45 @@ void VPlanTransforms::handleUncountableEarlyExit(
25052505 VPBuilder EarlyExitB (VectorEarlyExitVPBB);
25062506 for (VPRecipeBase &R : VPEarlyExitBlock->phis ()) {
25072507 auto *ExitIRI = cast<VPIRPhi>(&R);
2508- PHINode &ExitPhi = ExitIRI->getIRPhi ();
2509- VPValue *IncomingFromEarlyExit = RecipeBuilder.getVPValueOrAddLiveIn (
2510- ExitPhi.getIncomingValueForBlock (UncountableExitingBlock));
2511-
2508+ // Early exit operand should always be last, i.e., 0 if VPEarlyExitBlock has
2509+ // a single predecessor and 1 if it has two.
2510+ unsigned EarlyExitIdx = ExitIRI->getNumOperands () - 1 ;
25122511 if (OrigLoop->getUniqueExitBlock ()) {
2513- // If there's a unique exit block, VPEarlyExitBlock has 2 predecessors
2514- // (MiddleVPBB and NewMiddle). Add the incoming value from MiddleVPBB
2515- // which is coming from the original latch.
2516- VPValue *IncomingFromLatch = RecipeBuilder.getVPValueOrAddLiveIn (
2517- ExitPhi.getIncomingValueForBlock (OrigLoop->getLoopLatch ()));
2518- ExitIRI->addOperand (IncomingFromLatch);
2519- ExitIRI->extractLastLaneOfOperand (MiddleBuilder);
2512+ // If VPEarlyExitBlock has two predecessors, they are already ordered such
2513+ // that early exit is second (and latch exit is first), by construction.
2514+ // But its underlying IRBB (EarlyExitIRBB) may have its predecessors
2515+ // ordered the other way around, and it is the order of the latter which
2516+ // corresponds to the order of operands of VPEarlyExitBlock's phi recipes.
2517+ // Therefore, if early exit (UncountableExitingBlock) is the first
2518+ // predecessor of EarlyExitIRBB, we swap the operands of phi recipes,
2519+ // thereby bringing them to match VPEarlyExitBlock's predecessor order,
2520+ // with early exit being last (second). Otherwise they already match.
2521+ if (*pred_begin (VPEarlyExitBlock->getIRBasicBlock ()) ==
2522+ UncountableExitingBlock)
2523+ ExitIRI->swapOperands ();
2524+
2525+ // The first of two operands corresponds to the latch exit, via MiddleVPBB
2526+ // predecessor. Extract its last lane.
2527+ ExitIRI->extractLastLaneOfFirstOperand (MiddleBuilder);
25202528 }
25212529
2530+ VPValue *IncomingFromEarlyExit = ExitIRI->getOperand (EarlyExitIdx);
25222531 auto IsVector = [](ElementCount VF) { return VF.isVector (); };
25232532 // When the VFs are vectors, need to add `extract` to get the incoming value
25242533 // from early exit. When the range contains scalar VF, limit the range to
25252534 // scalar VF to prevent mis-compilation for the range containing both scalar
25262535 // and vector VFs.
25272536 if (!IncomingFromEarlyExit->isLiveIn () &&
25282537 LoopVectorizationPlanner::getDecisionAndClampRange (IsVector, Range)) {
2538+ // Update the incoming value from the early exit.
25292539 VPValue *FirstActiveLane = EarlyExitB.createNaryOp (
25302540 VPInstruction::FirstActiveLane, {EarlyExitTakenCond}, nullptr ,
25312541 " first.active.lane" );
25322542 IncomingFromEarlyExit = EarlyExitB.createNaryOp (
25332543 Instruction::ExtractElement, {IncomingFromEarlyExit, FirstActiveLane},
25342544 nullptr , " early.exit.value" );
2545+ ExitIRI->setOperand (EarlyExitIdx, IncomingFromEarlyExit);
25352546 }
2536- ExitIRI->addOperand (IncomingFromEarlyExit);
25372547 }
25382548 MiddleBuilder.createNaryOp (VPInstruction::BranchOnCond, {IsEarlyExitTaken});
25392549
0 commit comments