@@ -9043,13 +9043,8 @@ collectUsersInExitBlocks(Loop *OrigLoop, VPRecipeBuilder &Builder,
9043
9043
break ;
9044
9044
for (VPBlockBase *PredVPBB : ExitVPBB->getPredecessors ()) {
9045
9045
BasicBlock *ExitingBB = OrigLoop->getLoopLatch ();
9046
- if (PredVPBB != MiddleVPBB) {
9047
- SmallVector<BasicBlock *> ExitingBlocks;
9048
- OrigLoop->getExitingBlocks (ExitingBlocks);
9049
- assert (ExitingBlocks.size () == 2 && " only support 2 exiting blocks" );
9050
- ExitingBB = ExitingBB == ExitingBlocks[0 ] ? ExitingBlocks[1 ]
9051
- : ExitingBlocks[0 ];
9052
- }
9046
+ if (PredVPBB != MiddleVPBB)
9047
+ continue ;
9053
9048
Value *IncomingValue = ExitPhi->getIncomingValueForBlock (ExitingBB);
9054
9049
VPValue *V = Builder.getVPValueOrAddLiveIn (IncomingValue);
9055
9050
ExitUsersToFix.insert (ExitIRI);
@@ -9070,26 +9065,7 @@ addUsersInExitBlocks(VPlan &Plan,
9070
9065
return ;
9071
9066
9072
9067
auto *MiddleVPBB = Plan.getMiddleBlock ();
9073
- VPBuilder MiddleB (MiddleVPBB, MiddleVPBB->getFirstNonPhi ());
9074
- VPBuilder EarlyExitB;
9075
- VPBasicBlock *VectorEarlyExitVPBB = Plan.getEarlyExit ();
9076
- VPValue *EarlyExitMask = nullptr ;
9077
- if (VectorEarlyExitVPBB) {
9078
- EarlyExitB.setInsertPoint (VectorEarlyExitVPBB,
9079
- VectorEarlyExitVPBB->getFirstNonPhi ());
9080
-
9081
- // Lookup and cache the early exit mask.
9082
- VPBasicBlock *MiddleSplitVPBB =
9083
- cast<VPBasicBlock>(VectorEarlyExitVPBB->getSinglePredecessor ());
9084
- VPInstruction *PredTerm =
9085
- cast<VPInstruction>(MiddleSplitVPBB->getTerminator ());
9086
- assert (PredTerm->getOpcode () == VPInstruction::BranchOnCond &&
9087
- " Unexpected middle split block terminator" );
9088
- VPInstruction *ScalarCond = cast<VPInstruction>(PredTerm->getOperand (0 ));
9089
- assert (ScalarCond->getOpcode () == VPInstruction::AnyOf &&
9090
- " Unexpected condition for middle split block terminator branch" );
9091
- EarlyExitMask = ScalarCond->getOperand (0 );
9092
- }
9068
+ VPBuilder B (MiddleVPBB, MiddleVPBB->getFirstNonPhi ());
9093
9069
9094
9070
// Introduce extract for exiting values and update the VPIRInstructions
9095
9071
// modeling the corresponding LCSSA phis.
@@ -9100,19 +9076,17 @@ addUsersInExitBlocks(VPlan &Plan,
9100
9076
if (Op->isLiveIn ())
9101
9077
continue ;
9102
9078
9103
- LLVMContext &Ctx = ExitIRI-> getInstruction (). getContext ();
9104
- VPValue *Ext;
9079
+ // Values that came from an uncountable early exiting block are dealt
9080
+ // with separately in handleUncountableEarlyExit.
9105
9081
VPBasicBlock *PredVPBB =
9106
9082
cast<VPBasicBlock>(ExitIRI->getParent ()->getPredecessors ()[Idx]);
9107
- if (PredVPBB != MiddleVPBB) {
9108
- assert (ExitIRI->getParent ()->getNumPredecessors () <= 2 );
9109
- Ext = EarlyExitB.createNaryOp (VPInstruction::ExtractFirstActive,
9110
- {Op, EarlyExitMask});
9111
- } else {
9112
- Ext = MiddleB.createNaryOp (VPInstruction::ExtractFromEnd,
9113
- {Op, Plan.getOrAddLiveIn (ConstantInt::get (
9114
- IntegerType::get (Ctx, 32 ), 1 ))});
9115
- }
9083
+ if (PredVPBB != MiddleVPBB)
9084
+ continue ;
9085
+
9086
+ LLVMContext &Ctx = ExitIRI->getInstruction ().getContext ();
9087
+ VPValue *Ext = B.createNaryOp (VPInstruction::ExtractFromEnd,
9088
+ {Op, Plan.getOrAddLiveIn (ConstantInt::get (
9089
+ IntegerType::get (Ctx, 32 ), 1 ))});
9116
9090
ExitIRI->setOperand (Idx, Ext);
9117
9091
}
9118
9092
}
@@ -9409,15 +9383,19 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
9409
9383
R->setOperand (1 , WideIV->getStepValue ());
9410
9384
}
9411
9385
9386
+ // This must be called before handleUncountableEarlyExit in order to preserve
9387
+ // the correct ordering of operands, which should correspond like-for-like
9388
+ // with the order of exit block predecessors in vplan. The middle block is
9389
+ // always the first predecessor, followed by the vector early exit block.
9390
+ SetVector<VPIRInstruction *> ExitUsersToFix =
9391
+ collectUsersInExitBlocks (OrigLoop, RecipeBuilder, *Plan);
9412
9392
if (auto *UncountableExitingBlock =
9413
9393
Legal->getUncountableEarlyExitingBlock ()) {
9414
9394
VPlanTransforms::handleUncountableEarlyExit (
9415
9395
*Plan, *PSE.getSE (), OrigLoop, UncountableExitingBlock, RecipeBuilder);
9416
9396
}
9417
9397
DenseMap<VPValue *, VPValue *> IVEndValues;
9418
9398
addScalarResumePhis (RecipeBuilder, *Plan, IVEndValues);
9419
- SetVector<VPIRInstruction *> ExitUsersToFix =
9420
- collectUsersInExitBlocks (OrigLoop, RecipeBuilder, *Plan);
9421
9399
addExitUsersForFirstOrderRecurrences (*Plan, ExitUsersToFix);
9422
9400
addUsersInExitBlocks (*Plan, ExitUsersToFix);
9423
9401
0 commit comments