Skip to content

Commit e931309

Browse files
committed
[VPlan] Add exit phi operands during initial construction (NFC).
Add incoming exit phi operands during the initial VPlan construction. This ensures all users are added to the initial VPlan and is also needed in preparation to retaining exiting edges during initial construction.
1 parent 0314755 commit e931309

File tree

4 files changed

+38
-17
lines changed

4 files changed

+38
-17
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9392,11 +9392,7 @@ collectUsersInExitBlocks(Loop *OrigLoop, VPRecipeBuilder &Builder,
93929392
continue;
93939393
}
93949394

9395-
PHINode &ExitPhi = ExitIRI->getIRPhi();
9396-
BasicBlock *ExitingBB = OrigLoop->getLoopLatch();
9397-
Value *IncomingValue = ExitPhi.getIncomingValueForBlock(ExitingBB);
9398-
VPValue *V = Builder.getVPValueOrAddLiveIn(IncomingValue);
9399-
ExitIRI->addOperand(V);
9395+
VPValue *V = ExitIRI->getOperand(0);
94009396
if (V->isLiveIn())
94019397
continue;
94029398
assert(V->getDefiningRecipe()->getParent()->getEnclosingLoopRegion() &&

llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,19 @@ std::unique_ptr<VPlan> PlainCFGBuilder::buildPlainCFG(
352352
Plan->getEntry()->setOneSuccessor(getOrCreateVPBB(TheLoop->getHeader()));
353353
Plan->getEntry()->setPlan(&*Plan);
354354

355+
// Add incoming operands for the VPIRInstructions wrapping the exit phis.
356+
for (auto *EB : Plan->getExitBlocks()) {
357+
for (VPRecipeBase &R : *EB) {
358+
auto *PhiR = dyn_cast<VPIRPhi>(&R);
359+
if (!PhiR)
360+
break;
361+
PHINode &Phi = PhiR->getIRPhi();
362+
for (BasicBlock *Pred : predecessors(EB->getIRBasicBlock()))
363+
PhiR->addOperand(
364+
getOrCreateVPOperand(Phi.getIncomingValueForBlock(Pred)));
365+
}
366+
}
367+
355368
for (const auto &[IRBB, VPB] : BB2VPBB)
356369
VPB2IRBB[VPB] = IRBB;
357370

@@ -464,6 +477,12 @@ void VPlanTransforms::createLoopRegions(VPlan &Plan, Type *InductionTy,
464477
VPBlockUtils::connectBlocks(ScalarPH, Plan.getScalarHeader());
465478
if (!RequiresScalarEpilogueCheck) {
466479
VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH);
480+
// The exit blocks are dead, remove any recipes to make sure no users remain
481+
// that may pessimize transforms.
482+
for (auto *EB : Plan.getExitBlocks()) {
483+
for (VPRecipeBase &R : make_early_inc_range(*EB))
484+
R.eraseFromParent();
485+
}
467486
return;
468487
}
469488

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1139,7 +1139,7 @@ InstructionCost VPIRInstruction::computeCost(ElementCount VF,
11391139
void VPIRInstruction::extractLastLaneOfOperand(VPBuilder &Builder) {
11401140
assert(isa<PHINode>(getInstruction()) &&
11411141
"can only add exiting operands to phi nodes");
1142-
assert(getNumOperands() == 1 && "must have a single operand");
1142+
assert(getNumOperands() > 0 && "must have at least one operand");
11431143
VPValue *Exiting = getOperand(0);
11441144
if (!Exiting->isLiveIn()) {
11451145
LLVMContext &Ctx = getInstruction().getContext();

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2501,35 +2501,41 @@ void VPlanTransforms::handleUncountableEarlyExit(
25012501
if (!ExitIRI)
25022502
break;
25032503

2504-
PHINode &ExitPhi = ExitIRI->getIRPhi();
2505-
VPValue *IncomingFromEarlyExit = RecipeBuilder.getVPValueOrAddLiveIn(
2506-
ExitPhi.getIncomingValueForBlock(UncountableExitingBlock));
2507-
2504+
unsigned EarlyExitIdx = 0;
25082505
if (OrigLoop->getUniqueExitBlock()) {
2506+
// After the transform, the first incoming value is coming from the
2507+
// orignial loop latch, while the second operand is from the early exit.
2508+
// Sawp the phi operands, if the first predecessor in the original IR is
2509+
// not the loop latch.
2510+
if (*pred_begin(VPEarlyExitBlock->getIRBasicBlock()) !=
2511+
OrigLoop->getLoopLatch())
2512+
ExitIRI->swapOperands();
2513+
2514+
EarlyExitIdx = 1;
25092515
// If there's a unique exit block, VPEarlyExitBlock has 2 predecessors
25102516
// (MiddleVPBB and NewMiddle). Add the incoming value from MiddleVPBB
25112517
// which is coming from the original latch.
2512-
VPValue *IncomingFromLatch = RecipeBuilder.getVPValueOrAddLiveIn(
2513-
ExitPhi.getIncomingValueForBlock(OrigLoop->getLoopLatch()));
2514-
ExitIRI->addOperand(IncomingFromLatch);
25152518
ExitIRI->extractLastLaneOfOperand(MiddleBuilder);
25162519
}
25172520

2521+
VPValue *IncomingFromEarlyExit = ExitIRI->getOperand(EarlyExitIdx);
25182522
auto IsVector = [](ElementCount VF) { return VF.isVector(); };
25192523
// When the VFs are vectors, need to add `extract` to get the incoming value
25202524
// from early exit. When the range contains scalar VF, limit the range to
25212525
// scalar VF to prevent mis-compilation for the range containing both scalar
25222526
// and vector VFs.
25232527
if (!IncomingFromEarlyExit->isLiveIn() &&
25242528
LoopVectorizationPlanner::getDecisionAndClampRange(IsVector, Range)) {
2529+
// Add the incoming value from the early exit.
25252530
VPValue *FirstActiveLane = EarlyExitB.createNaryOp(
25262531
VPInstruction::FirstActiveLane, {EarlyExitTakenCond}, nullptr,
25272532
"first.active.lane");
2528-
IncomingFromEarlyExit = EarlyExitB.createNaryOp(
2529-
Instruction::ExtractElement, {IncomingFromEarlyExit, FirstActiveLane},
2530-
nullptr, "early.exit.value");
2533+
ExitIRI->setOperand(
2534+
EarlyExitIdx,
2535+
EarlyExitB.createNaryOp(Instruction::ExtractElement,
2536+
{IncomingFromEarlyExit, FirstActiveLane},
2537+
nullptr, "early.exit.value"));
25312538
}
2532-
ExitIRI->addOperand(IncomingFromEarlyExit);
25332539
}
25342540
MiddleBuilder.createNaryOp(VPInstruction::BranchOnCond, {IsEarlyExitTaken});
25352541

0 commit comments

Comments
 (0)