[llvm] [LoopInterchange] Also look at lcssa phis in outer loop latch block (PR #160889)
Michael Kruse via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 2 05:26:42 PDT 2025
================
@@ -1837,6 +1838,38 @@ static void moveLCSSAPhis(BasicBlock *InnerExit, BasicBlock *InnerHeader,
for (PHINode *P : LcssaInnerLatch)
P->moveBefore(InnerExit->getFirstNonPHIIt());
+ // This deals with a corner case of LCSSA phi nodes in the outer loop latch
+ // block: the loop was in LCSSA form, some transformations can come along
+ // (e.g. unswitch) and create an empty block:
+ //
+ // BB4:
+ // br label %BB5
+ // BB5:
+ // %old.cond.lcssa = phi i16 [ %cond, %BB4 ]
+ // br outer.header
+ //
+ // Interchange then brings it in LCSSA form again and we get:
+ //
+ // BB4:
+ // %new.cond.lcssa = phi i16 [ %cond, %BB3 ]
+ // br label %BB5
+ // BB5:
+ // %old.cond.lcssa = phi i16 [ %new.cond.lcssa, %BB4 ]
+ //
+ // Which means that we have a chain of LCSSA phi nodes from %new.cond.lcssa
+ // to %old.cond.lcssa. The problem is that interchange can reoder blocks BB4
+ // and BB5 placing the use before the def if we don't check this. The
+ // observation is that %old.cond.lcssa is unused, so instead of moving and
+ // renaming these phi nodes, just delete it if it's trivially dead. If it
+ // isn't trivially dead, it is handled above. The loop should still be in
+ // LCSSA form, and if it isn't, formLCSSARecursively is called after the
+ // interchange rewrite.
+ SmallVector<PHINode *, 8> LcssaOuterLatch(
+ llvm::make_pointer_range(OuterLatch->phis()));
----------------
Meinersbur wrote:
Consider iterating over `OuterLatch->phis()`, and only adding those instructions to the list to be erased. That's the more established pattern.
https://github.com/llvm/llvm-project/pull/160889
More information about the llvm-commits
mailing list