@@ -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