This patch updates the code handling reduction recipes to also keep
track of the incoming value from the latch in the recipe. This is needed
to model the def-use chains completely in VPlan, so that it is possible
to replace the incoming value with an arbitrary VPValue.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Rebase & ping.
I just pushed a small patch that prints prints VPWidenPHIRecipe using the VPValue operands, if there are operands for all incoming values (a6b06b785cda1bb94dd05f29d66892ccb44cf0cd).
Now the change in this patch (adding the incoming value from the loop backedge) is visible in the printing.
Update comment to clarify that the first operand of a VPWidenPHIRecipe for a reduction is the start value and the second operand is the incoming value from the backedge.
Looks good to me!
Adding a couple of nits and thoughts.
Perhaps "[VPlan] Representing backedge def-use feeding reduction phi's" may be a more accurate title - "incoming" also (more-so?) applies to the operand from the preheader.
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
4323–4328 | nit: worth hoisting LoopVectorLatch = LI->getLoopFor(LoopVectorBody)->getLoopLatch() here. | |
4329–4330 | nit: can continue to obtain the first-and-only VPValue defined by PhiR, by calling getVPValue() as before, which defaults to getVPValue(0), right? | |
8970 | Worth a comment here explaining that source and destination of cross-iteration dependences are marked here in order to wire their recipes in VPlan later. Current implementation looks fine. Raising a possible alternative, if preferred? | |
llvm/lib/Transforms/Vectorize/VPlan.h | ||
997 | Worth supplying another interface to retrieve 'preheadered' and 'latched' operands of a header phi recipe (by setting them as 0 and 1 enum values?) to increase the readability of 'getOperand(0)' and 'getOperand(1)'? | |
llvm/test/Transforms/LoopVectorize/vplan-printing.ll | ||
82 | Clean up the TODO in VPlan.cpp/ VPWidenPHIRecipe::print() ? |
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
4323–4328 | I'll do that in a separate commit. | |
4329–4330 | Yep, changed it back. | |
8970 | Thanks for the suggestion. Doing the tracking and fixup directly in VPRecipeBuilder seems preferable. I updated the patch and added the additional comments to the new code. | |
llvm/lib/Transforms/Vectorize/VPlan.h | ||
997 | I added a VPWidenPHIRecipe::getBackedgeValue(), similar to getStartValue. WDYT? | |
llvm/test/Transforms/LoopVectorize/vplan-printing.ll | ||
82 | Unfortunately there are still cases where we do not track the value from the back-edge (like first-order recurrences). |
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
4323–4328 | Done in cb96d802d4d7 |
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
8771 | can alternatively traverse over R : PhiRecipesToFix, and use R's underlying ingredient to retrieve its PN, etc. | |
8886 | Instead of recording the recipe of Phi, which the next line creates, can do auto *PhiRecipe = new VPWidenPHIRecipe(Phi, RdxDesc, *StartV); PhiRecipesToFix.push_back(PhiRecipe); return toVPRecipeResult(PhiRecipe); | |
llvm/lib/Transforms/Vectorize/VPlan.h | ||
997 | Great! | |
llvm/test/Transforms/LoopVectorize/vplan-printing.ll | ||
82 | Ah, right. |
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
8771 | excellent idea, updated! |
Adding a couple of related thoughts. Thanks!
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
8775 | while we're here: it may be useful to have a "getVPSingleValue()" which would take care of the assert (and the redundant 0)? In any case, the assert deserves an error message. | |
8889 | while we're here: the use of toVPRecipeResult() and VPRecipeOrVPValueTy, if intended to solve D44800 Blend issue only, seem like an overkill - BlendRecipe pass-throughs a single-operand phi, having a full (null) mask; so it should be easy(ier) to have it pass-through an(y) operand also for a phi having multiple identical operands. I.e., tryToBlend() can always return a VPRecipe. Better to discuss this on a related review, if there is one available? |
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
8775 | Added getVPSingleValue in a0e1313c2329 |
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
8882 | nit: "// Record the [PHI and the] incoming value" |
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
8882 | Thanks, should be fixed in 75b9997760c6 |
Hi,
I wrote a PR about a LV-crash that started happening with this patch:
https://bugs.llvm.org/show_bug.cgi?id=50298
Thanks for the report! The problem was that we did not record the recipe if a simplified VPValue is used. I pushed faebc6bf108e to fix it for now, but as Ayal pointed out, it might be worth the simplify the handling, which I'll look into separately.
nit: worth hoisting LoopVectorLatch = LI->getLoopFor(LoopVectorBody)->getLoopLatch() here.
(admittedly independent of this patch)