[llvm] [LoopFusion] Fix out-of-date LoopInfo being used during fusion (PR #189452)

via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 30 11:50:25 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Congzhe (CongzheUalberta)

<details>
<summary>Changes</summary>

This is fix for [187902](https://github.com/llvm/llvm-project/issues/187902).

The reason for the bug is that, `mergeLatch()` is called at a place where control flow and dominator trees have been updated but LoopInfo has not completed the update yet. `mergeLatch()` calls into ScalarEvolution that uses LoopInfo, where out-of-date LoopInfo would result in crash or unpredicatable results.

This patch moves `mergeLatch()` to the place where LoopInfo has completed its update and hence is in a valid state.

---
Full diff: https://github.com/llvm/llvm-project/pull/189452.diff


1 Files Affected:

- (modified) llvm/lib/Transforms/Scalar/LoopFuse.cpp (+22-22) 


``````````diff
diff --git a/llvm/lib/Transforms/Scalar/LoopFuse.cpp b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
index 23bba139212e8..07cc86c76ca1d 100644
--- a/llvm/lib/Transforms/Scalar/LoopFuse.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
@@ -1676,19 +1676,6 @@ struct LoopFuser {
     SE.forgetLoop(FC1.L);
     SE.forgetLoop(FC0.L);
 
-    // Move instructions from FC0.Latch to FC1.Latch.
-    // Note: mergeLatch requires an updated DT.
-    mergeLatch(FC0, FC1);
-
-    // Forget block dispositions as well, so that there are no dangling
-    // pointers to erased/free'ed blocks. It should be done after mergeLatch()
-    // since merging the latches may affect the dispositions.
-    SE.forgetBlockAndLoopDispositions();
-
-    // Forget the cached SCEV values including the induction variable that may
-    // have changed after the fusion.
-    SE.forgetLoop(FC0.L);
-
     // Merge the loops.
     SmallVector<BasicBlock *, 8> Blocks(FC1.L->blocks());
     for (BasicBlock *BB : Blocks) {
@@ -1708,6 +1695,19 @@ struct LoopFuser {
     // Delete the now empty loop L1.
     LI.erase(FC1.L);
 
+    // Move instructions from FC0.Latch to FC1.Latch.
+    // Note: mergeLatch requires an updated DT.
+    mergeLatch(FC0, FC1);
+
+    // Forget block dispositions as well, so that there are no dangling
+    // pointers to erased/free'ed blocks. It should be done after mergeLatch()
+    // since merging the latches may affect the dispositions.
+    SE.forgetBlockAndLoopDispositions();
+
+    // Forget the cached SCEV values including the induction variable that may
+    // have changed after the fusion.
+    SE.forgetLoop(FC0.L);
+
 #ifndef NDEBUG
     assert(!verifyFunction(*FC0.Header->getParent(), &errs()));
     assert(DT.verify(DominatorTree::VerificationLevel::Fast));
@@ -1978,15 +1978,6 @@ struct LoopFuser {
     SE.forgetLoop(FC1.L);
     SE.forgetLoop(FC0.L);
 
-    // Move instructions from FC0.Latch to FC1.Latch.
-    // Note: mergeLatch requires an updated DT.
-    mergeLatch(FC0, FC1);
-
-    // Forget block dispositions as well, so that there are no dangling
-    // pointers to erased/free'ed blocks. It should be done after mergeLatch()
-    // since merging the latches may affect the dispositions.
-    SE.forgetBlockAndLoopDispositions();
-
     // Merge the loops.
     SmallVector<BasicBlock *, 8> Blocks(FC1.L->blocks());
     for (BasicBlock *BB : Blocks) {
@@ -2006,6 +1997,15 @@ struct LoopFuser {
     // Delete the now empty loop L1.
     LI.erase(FC1.L);
 
+    // Move instructions from FC0.Latch to FC1.Latch.
+    // Note: mergeLatch requires an updated DT.
+    mergeLatch(FC0, FC1);
+
+    // Forget block dispositions as well, so that there are no dangling
+    // pointers to erased/free'ed blocks. It should be done after mergeLatch()
+    // since merging the latches may affect the dispositions.
+    SE.forgetBlockAndLoopDispositions();
+
 #ifndef NDEBUG
     assert(!verifyFunction(*FC0.Header->getParent(), &errs()));
     assert(DT.verify(DominatorTree::VerificationLevel::Fast));

``````````

</details>


https://github.com/llvm/llvm-project/pull/189452


More information about the llvm-commits mailing list