Skip to content

Commit 85ef4b2

Browse files
committed
[VPlan] Don't reset canonical IV start value.
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.
1 parent b66dfa7 commit 85ef4b2

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9562,7 +9562,10 @@ static SmallVector<Instruction *> preparePlanForEpilogueVectorLoop(
95629562
}) &&
95639563
"the canonical IV should only be used by its increment or "
95649564
"ScalarIVSteps when resetting the start value");
9565-
IV->setOperand(0, VPV);
9565+
VPBuilder Builder(Header, Header->getFirstNonPhi());
9566+
VPInstruction *Add = Builder.createNaryOp(Instruction::Add, {IV, VPV});
9567+
IV->replaceAllUsesWith(Add);
9568+
Add->setOperand(0, IV);
95669569

95679570
DenseMap<Value *, Value *> ToFrozen;
95689571
SmallVector<Instruction *> InstsToMove;
@@ -9596,17 +9599,18 @@ static SmallVector<Instruction *> preparePlanForEpilogueVectorLoop(
95969599
ToFrozen[StartV] = cast<PHINode>(ResumeV)->getIncomingValueForBlock(
95979600
EPI.MainLoopIterationCountCheck);
95989601

9599-
// VPReductionPHIRecipe for FindFirstIV/FindLastIV reductions requires
9600-
// an adjustment to the resume value. The resume value is adjusted to
9601-
// the sentinel value when the final value from the main vector loop
9602-
// equals the start value. This ensures correctness when the start value
9603-
// might not be less than the minimum value of a monotonically
9604-
// increasing induction variable.
9602+
// VPReductionPHIRecipe for FindFirstIV/FindLastIV reductions
9603+
// requires an adjustment to the resume value. The resume value is
9604+
// adjusted to the sentinel value when the final value from the main
9605+
// vector loop equals the start value. This ensures correctness when
9606+
// the start value might not be less than the minimum value of a
9607+
// monotonically increasing induction variable.
96059608
BasicBlock *ResumeBB = cast<Instruction>(ResumeV)->getParent();
96069609
IRBuilder<> Builder(ResumeBB, ResumeBB->getFirstNonPHIIt());
96079610
Value *Cmp = Builder.CreateICmpEQ(ResumeV, ToFrozen[StartV]);
96089611
if (auto *I = dyn_cast<Instruction>(Cmp))
96099612
InstsToMove.push_back(I);
9613+
96109614
Value *Sentinel = RdxResult->getOperand(2)->getLiveInIRValue();
96119615
ResumeV = Builder.CreateSelect(Cmp, Sentinel, ResumeV);
96129616
if (auto *I = dyn_cast<Instruction>(ResumeV))

llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,12 @@ m_c_Binary(const Op0_t &Op0, const Op1_t &Op1) {
431431
return AllRecipe_commutative_match<Opcode, Op0_t, Op1_t>(Op0, Op1);
432432
}
433433

434+
template <typename Op0_t, typename Op1_t>
435+
inline AllRecipe_match<Instruction::Add, Op0_t, Op1_t> m_Add(const Op0_t &Op0,
436+
const Op1_t &Op1) {
437+
return m_Binary<Instruction::Add, Op0_t, Op1_t>(Op0, Op1);
438+
}
439+
434440
template <typename Op0_t, typename Op1_t>
435441
inline AllRecipe_commutative_match<Instruction::Add, Op0_t, Op1_t>
436442
m_c_Add(const Op0_t &Op0, const Op1_t &Op1) {

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

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

1238+
if (match(Def, m_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+
12381249
// VPVectorPointer for part 0 can be replaced by their start pointer.
12391250
if (auto *VecPtr = dyn_cast<VPVectorPointerRecipe>(&R)) {
12401251
if (VecPtr->isFirstPart()) {

0 commit comments

Comments
 (0)