From 3e58dd19dfa3c2537c3168a4885a5d757b3f1a6a Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Fri, 6 Aug 2021 08:12:54 +0100 Subject: [PATCH] [LV] Move reduction PHI node fixup to VPlan::execute (NFC). All information to fix-up the reduction phi nodes in the vectorized loop is available in VPlan now. This patch moves the code to do so, to make this clearer. Fixing up the loop exit value still relies on other information and remains outside of VPlan for now. Reviewed By: Ayal Differential Revision: https://reviews.llvm.org/D100113 --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 19 +---------------- llvm/lib/Transforms/Vectorize/VPlan.cpp | 28 ++++++++++++++++++------- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index c2358d3..375079e 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -594,8 +594,7 @@ protected: /// update their users. void fixFirstOrderRecurrence(VPWidenPHIRecipe *PhiR, VPTransformState &State); - /// Fix a reduction cross-iteration phi. This is the second phase of - /// vectorizing this phi node. + /// Create code for the loop exit value of the reduction. void fixReduction(VPReductionPHIRecipe *Phi, VPTransformState &State); /// Clear NSW/NUW flags from reduction instructions if necessary. @@ -4303,22 +4302,6 @@ void InnerLoopVectorizer::fixReduction(VPReductionPHIRecipe *PhiR, // Wrap flags are in general invalid after vectorization, clear them. clearReductionWrapFlags(RdxDesc, State); - // Fix the vector-loop phi. - - // Reductions do not have to start at zero. They can start with - // any loop invariant values. - BasicBlock *VectorLoopLatch = LI->getLoopFor(LoopVectorBody)->getLoopLatch(); - - unsigned LastPartForNewPhi = PhiR->isOrdered() ? 1 : UF; - for (unsigned Part = 0; Part < LastPartForNewPhi; ++Part) { - Value *VecRdxPhi = State.get(PhiR->getVPSingleValue(), Part); - Value *Val = State.get(PhiR->getBackedgeValue(), Part); - if (PhiR->isOrdered()) - Val = State.get(PhiR->getBackedgeValue(), UF - 1); - - cast(VecRdxPhi)->addIncoming(Val, VectorLoopLatch); - } - // Before each round, move the insertion point right between // the PHIs and the values we are going to write. // This allows us to write both PHINodes and the extractelement diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp index d0a6fde..fa71b1c 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -815,16 +815,25 @@ void VPlan::execute(VPTransformState *State) { for (VPBlockBase *Block : depth_first(Entry)) Block->execute(State); - // Fix the latch value of the first-order recurrences in the vector loop. Only - // a single part is generated, regardless of the UF. + // Fix the latch value of reduction and first-order recurrences phis in the + // vector loop. VPBasicBlock *Header = Entry->getEntryBasicBlock(); for (VPRecipeBase &R : Header->phis()) { - if (auto *FOR = dyn_cast(&R)) { - auto *VecPhi = cast(State->get(FOR, 0)); - - VPValue *PreviousDef = FOR->getBackedgeValue(); - Value *Incoming = State->get(PreviousDef, State->UF - 1); - VecPhi->addIncoming(Incoming, VectorLatchBB); + auto *PhiR = dyn_cast(&R); + if (!PhiR || !(isa(&R) || + isa(&R))) + continue; + // For first-order recurrences and in-order reduction phis, only a single + // part is generated, which provides the last part from the previous + // iteration. Otherwise all UF parts are generated. + bool SinglePartNeeded = isa(&R) || + cast(&R)->isOrdered(); + unsigned LastPartForNewPhi = SinglePartNeeded ? 1 : State->UF; + for (unsigned Part = 0; Part < LastPartForNewPhi; ++Part) { + Value *VecPhi = State->get(PhiR, Part); + Value *Val = State->get(PhiR->getBackedgeValue(), + SinglePartNeeded ? State->UF - 1 : Part); + cast(VecPhi)->addIncoming(Val, VectorLatchBB); } } @@ -1319,6 +1328,9 @@ void VPReductionPHIRecipe::execute(VPTransformState &State) { PHINode::Create(VecTy, 2, "vec.phi", &*HeaderBB->getFirstInsertionPt()); State.set(this, EntryPart, Part); } + + // Reductions do not have to start at zero. They can start with + // any loop invariant values. VPValue *StartVPV = getStartValue(); Value *StartV = StartVPV->getLiveInIRValue(); -- 2.7.4