diff options
author | Madhur Amilkanthwar <madhura@nvidia.com> | 2025-07-28 12:08:43 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-28 12:08:43 +0530 |
commit | 90de4a4ac96ef314e3af9c43c516d5aaf105777a (patch) | |
tree | bd2f73666c7a4f0dd77010ec19aa00c20b8840d7 /llvm/lib | |
parent | 495774d6d59379edad3c8c35be8c4672d4a513fa (diff) | |
download | llvm-90de4a4ac96ef314e3af9c43c516d5aaf105777a.zip llvm-90de4a4ac96ef314e3af9c43c516d5aaf105777a.tar.gz llvm-90de4a4ac96ef314e3af9c43c516d5aaf105777a.tar.bz2 |
[LoopFusion] Fix sink instructions (#147501)
If we have instructions in second loop's preheader which can be sunk, we
should also be adjusting PHI nodes to receive values from the fused loop's latch block.
Fixes #128600
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopFuse.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopFuse.cpp b/llvm/lib/Transforms/Scalar/LoopFuse.cpp index d6bd92d..b5eb647 100644 --- a/llvm/lib/Transforms/Scalar/LoopFuse.cpp +++ b/llvm/lib/Transforms/Scalar/LoopFuse.cpp @@ -1176,6 +1176,28 @@ private: return true; } + /// This function fixes PHI nodes after fusion in \p SafeToSink. + /// \p SafeToSink instructions are the instructions that are to be moved past + /// the fused loop. Thus, the PHI nodes in \p SafeToSink should be updated to + /// receive values from the fused loop if they are currently taking values + /// from the first loop (i.e. FC0)'s latch. + void fixPHINodes(ArrayRef<Instruction *> SafeToSink, + const FusionCandidate &FC0, + const FusionCandidate &FC1) const { + for (Instruction *Inst : SafeToSink) { + // No update needed for non-PHI nodes. + PHINode *Phi = dyn_cast<PHINode>(Inst); + if (!Phi) + continue; + for (unsigned I = 0; I < Phi->getNumIncomingValues(); I++) { + if (Phi->getIncomingBlock(I) != FC0.Latch) + continue; + assert(FC1.Latch && "FC1 latch is not set"); + Phi->setIncomingBlock(I, FC1.Latch); + } + } + } + /// Collect instructions in the \p FC1 Preheader that can be hoisted /// to the \p FC0 Preheader or sunk into the \p FC1 Body bool collectMovablePreheaderInsts( @@ -1481,6 +1503,9 @@ private: assert(I->getParent() == FC1.Preheader); I->moveBefore(*FC1.ExitBlock, FC1.ExitBlock->getFirstInsertionPt()); } + // PHI nodes in SinkInsts need to be updated to receive values from the + // fused loop. + fixPHINodes(SinkInsts, FC0, FC1); } /// Determine if two fusion candidates have identical guards |