Skip to content

Commit 4b8cac2

Browse files
authored
[VPlan] Don't reset canonical IV start value. (llvm#161589)
Instead of re-setting the start value of the canonical IV when vectorizing the epilogue we can emit an Add VPInstruction to provide canonical IV value, adjusted by the resume value from the main loop. This is in preparation to make the canonical IV a VPValue defined by loop regions. It ensures that the canonical IV always starts at 0. PR: llvm#161589
1 parent e6b49ce commit 4b8cac2

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9348,13 +9348,12 @@ static SmallVector<Instruction *> preparePlanForEpilogueVectorLoop(
93489348
VPBasicBlock *Header = VectorLoop->getEntryBasicBlock();
93499349
Header->setName("vec.epilog.vector.body");
93509350

9351-
// Ensure that the start values for all header phi recipes are updated before
9352-
// vectorizing the epilogue loop.
93539351
VPCanonicalIVPHIRecipe *IV = Plan.getCanonicalIV();
9354-
// When vectorizing the epilogue loop, the canonical induction start
9355-
// value needs to be changed from zero to the value after the main
9356-
// vector loop. Find the resume value created during execution of the main
9357-
// VPlan. It must be the first phi in the loop preheader.
9352+
// When vectorizing the epilogue loop, the canonical induction needs to be
9353+
// adjusted by the value after the main vector loop. Find the resume value
9354+
// created during execution of the main VPlan. It must be the first phi in the
9355+
// loop preheader. Use the value to increment the canonical IV, and update all
9356+
// users in the loop region to use the adjusted value.
93589357
// FIXME: Improve modeling for canonical IV start values in the epilogue
93599358
// loop.
93609359
using namespace llvm::PatternMatch;
@@ -9389,10 +9388,16 @@ static SmallVector<Instruction *> preparePlanForEpilogueVectorLoop(
93899388
}) &&
93909389
"the canonical IV should only be used by its increment or "
93919390
"ScalarIVSteps when resetting the start value");
9392-
IV->setOperand(0, VPV);
9391+
VPBuilder Builder(Header, Header->getFirstNonPhi());
9392+
VPInstruction *Add = Builder.createNaryOp(Instruction::Add, {IV, VPV});
9393+
IV->replaceAllUsesWith(Add);
9394+
Add->setOperand(0, IV);
93939395

93949396
DenseMap<Value *, Value *> ToFrozen;
93959397
SmallVector<Instruction *> InstsToMove;
9398+
// Ensure that the start values for all header phi recipes are updated before
9399+
// vectorizing the epilogue loop. Skip the canonical IV, which has been
9400+
// handled above.
93969401
for (VPRecipeBase &R : drop_begin(Header->phis())) {
93979402
Value *ResumeV = nullptr;
93989403
// TODO: Move setting of resume values to prepareToExecute.

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,18 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
12341234
if (!Plan->isUnrolled())
12351235
return;
12361236

1237+
// Hoist an invariant increment Y of a phi X, by having X start at Y.
1238+
if (match(Def, m_c_Add(m_VPValue(X), m_VPValue(Y))) && Y->isLiveIn() &&
1239+
isa<VPPhi>(X)) {
1240+
auto *Phi = cast<VPPhi>(X);
1241+
if (Phi->getOperand(1) != Def && match(Phi->getOperand(0), m_ZeroInt()) &&
1242+
Phi->getNumUsers() == 1 && (*Phi->user_begin() == &R)) {
1243+
Phi->setOperand(0, Y);
1244+
Def->replaceAllUsesWith(Phi);
1245+
return;
1246+
}
1247+
}
1248+
12371249
// VPVectorPointer for part 0 can be replaced by their start pointer.
12381250
if (auto *VecPtr = dyn_cast<VPVectorPointerRecipe>(&R)) {
12391251
if (VecPtr->isFirstPart()) {

0 commit comments

Comments
 (0)