[PATCH] D116928: [LoopVectorize] Support epilogue vectorisation of loops with reductions
Sander de Smalen via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 10 04:53:56 PST 2022
sdesmalen added a comment.
Hi @kmclaughlin thanks for sharing this patch. Overall the approach looks sensible, i.e. updating the VPlan for the epilogue to use a new start value for the `VPReductionPHIRecipe`, and moving the bc.merge.rdx to the correct block. The implementation itself still seems a bit fuzzy, so I've given some suggestions to make the remapping of values/edges more explicit.
================
Comment at: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:1231
+ auto *I = dyn_cast<Instruction>(PN->getIncomingValue(In));
+ if (I->getParent() == LoopScalarPreHeader)
+ return I;
----------------
Instead of inferring this information from the PHI node in the original loop, I'd prefer to record the resume values separately in the ILV and pass the information through the EpilogueLoopVectorizationInfo.
================
Comment at: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:4339
+ if (ResumeInst)
+ ResumePhi = dyn_cast<PHINode>(ResumeInst);
+
----------------
It's not necessarily safe to assume ResumePhi is a resume value just because it is a PHINode, so I'd recommend looking this up in the map that I mentioned earlier.
================
Comment at: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:4350-4351
+ for (unsigned I = 0, E = LoopBypassBlocks.size(); I != E; ++I) {
+ if (ResumeInst && LoopBypassBlocks[I] == ResumeInst->getParent())
+ BCBlockPhi->addIncoming(ResumeVal, LoopBypassBlocks[I]);
+ else if (ResumePhi &&
----------------
This case seems a bit odd, does it matter that ResumeValue is an instruction?
For the preheader after epilogue vectorization, I'd expect there to only be three cases to consider:
1. Original start value (when not having executed any vector code at all).
2. Intermediate reduction value after the main vector body (i.e. no epilogue vectorization because of the iter checks)
3. Intermediate reduction value after the vectorized epilogue. (i.e. the VPReductionPHI's new start value).
If you know that ResumePhi is actually a resume PHI node, you can write the loop as:
for (auto *Incoming : predecessors(LoopScalarPreHeader)) {
if (Incoming == LoopMiddleBlock)
BCBlockPhi->addIncoming(ReducedPartRdx, Incoming);
else if (ResumePhi && // case 2 from above.
// note that ResumePhi is only non-zero for epilogue vectorization.
llvm::is_contained(ResumePhi->blocks(), Incoming))
BCBlockPhi->addIncoming(ResumePhi->getIncomingValueForBlock(Incoming),
Incoming);
else
BCBlockPhi->addIncoming((Value *)ReductionStartValue, Incoming);
}
// Now, we need to fix the users of the reduction variable
// inside and outside of the scalar remainder loop.
[...]
================
Comment at: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:8325
+ SmallVector<BasicBlock *, 8> BlocksToRemove;
+ for (unsigned int In = 0; In < Phi.getNumIncomingValues(); In++) {
+ BasicBlock *InBlock = Phi.getIncomingBlock(In);
----------------
Instead of going through all the basic blocks like this, you can simply remove the incoming values from the `EPI.SCEVSafetyCheck`, `EPI.MemSafetyCheck` and `EPI.EpilogueIterationCountCheck`.
The incoming edge from the middle block can be updated to now come from `VecEpilogueIterationCountCheck`.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D116928/new/
https://reviews.llvm.org/D116928
More information about the llvm-commits
mailing list