[llvm] [LoopFusion] Remove DT edge from Extiblock to ExitBlockSuc (PR #193641)
Afonso Rafael via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 23 10:50:49 PDT 2026
https://github.com/Alf0nso updated https://github.com/llvm/llvm-project/pull/193641
>From 9f83adca6a4a1d7fd23107c986dc3e28cb3e0d31 Mon Sep 17 00:00:00 2001
From: Afonso Rafael <afonsorafael at sapo.pt>
Date: Thu, 23 Apr 2026 00:11:50 +0000
Subject: [PATCH 1/3] [LoopFusion] Remove DT edge from Extiblock to
ExitBlockSuc
This patch fixes the following assertion failure:
https://www.godbolt.org/z/ejEhYchPq
To remove the node, it cannot have successors, if this edge is not
removed, when applying the updates to the DT the following assertion
will appear:
"Assertion `Node->isLeaf() && "Node is not a leaf node."' failed"
This assertion does not always fail because before applying the
updates on the "GenericDomTreeContruction", "ApplyUpdates" function it
runs CalculateFromScratch on some situations:
// Make unittests of the incremental algorithm work
if (DT.DomTreeNodes.size() <= 100) {
if (BUI.NumLegalized > DT.DomTreeNodes.size())
CalculateFromScratch(DT, &BUI);
} else if (BUI.NumLegalized > DT.DomTreeNodes.size() / 40)
CalculateFromScratch(DT, &BUI);
---
llvm/lib/Transforms/Scalar/LoopFuse.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/llvm/lib/Transforms/Scalar/LoopFuse.cpp b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
index be543062670c6..6de3fc0174d7d 100644
--- a/llvm/lib/Transforms/Scalar/LoopFuse.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
@@ -1818,6 +1818,8 @@ struct LoopFuser {
DominatorTree::Insert, FC0GuardBlock, FC1NonLoopBlock));
if (FC0.Peeled) {
+ TreeUpdates.emplace_back(DominatorTree::UpdateType(
+ DominatorTree::Delete, FC0.ExitBlock, FC0ExitBlockSuccessor));
// Remove the Block after the ExitBlock of FC0
TreeUpdates.emplace_back(DominatorTree::UpdateType(
DominatorTree::Delete, FC0ExitBlockSuccessor, FC1GuardBlock));
>From 5a7a3c75035ca5bc3c6b41c6f2fed65fd6a9a970 Mon Sep 17 00:00:00 2001
From: Afonso Rafael <afonsorafael at sapo.pt>
Date: Thu, 23 Apr 2026 13:38:17 +0000
Subject: [PATCH 2/3] [LoopFusion] Test case for the pr 193641
This test shouldn't trigger any assertion.
---
llvm/test/Transforms/LoopFusion/pr193641.ll | 43 +++++++++++++++++++++
1 file changed, 43 insertions(+)
create mode 100644 llvm/test/Transforms/LoopFusion/pr193641.ll
diff --git a/llvm/test/Transforms/LoopFusion/pr193641.ll b/llvm/test/Transforms/LoopFusion/pr193641.ll
new file mode 100644
index 0000000000000..51e7099f324a4
--- /dev/null
+++ b/llvm/test/Transforms/LoopFusion/pr193641.ll
@@ -0,0 +1,43 @@
+; REQUIRES: asserts
+; RUN: opt -passes=loop-fusion -loop-fusion-peel-max-count=2 -disable-output -stats < %s 2>&1 | FileCheck -check-prefix=STAT %s
+; STAT: 1 loop-fusion - Loops fused
+
+; Loop fusion should not crash when flushing the DomTreeUpdater due to
+; missed edge removals when deleting basic blocks.
+
+define void @_QMdiags_on_lat_aux_gridPinit_lat_aux_grid(i1 %cond, i1 %cond1, i1 %0, i1 %1) {
+.critedge:
+ br i1 %cond, label %common.ret, label %thread-pre-split
+
+common.ret: ; preds = %.loopexit, %.critedge
+ ret void
+
+thread-pre-split: ; preds = %.critedge
+ br i1 %cond1, label %2, label %.loopexit
+
+2: ; preds = %thread-pre-split
+ br i1 %0, label %.lr.ph1333, label %._crit_edge1334
+
+.lr.ph1333: ; preds = %.lr.ph1333, %2
+ %indvars.iv1386 = phi i64 [ %indvars.iv.next1387, %.lr.ph1333 ], [ 0, %2 ]
+ %3 = getelementptr [8 x i8], ptr null, i64 %indvars.iv1386
+ store double 0.000000e+00, ptr %3, align 8
+ %indvars.iv.next1387 = add i64 %indvars.iv1386, 1
+ %exitcond1389.not = icmp eq i64 %indvars.iv1386, 100
+ br i1 %exitcond1389.not, label %._crit_edge1334, label %.lr.ph1333
+
+._crit_edge1334: ; preds = %.lr.ph1333, %2
+ br i1 %1, label %.lr.ph1336, label %.loopexit
+
+.lr.ph1336: ; preds = %.lr.ph1336, %._crit_edge1334
+ %indvars.iv1390 = phi i64 [ %indvars.iv.next1391, %.lr.ph1336 ], [ 0, %._crit_edge1334 ]
+ %5 = getelementptr [8 x i8], ptr null, i64 %indvars.iv1390
+ store double 0.000000e+00, ptr %5, align 8
+ %indvars.iv.next1391 = add i64 %indvars.iv1390, 1
+ %exitcond1393.not = icmp eq i64 %indvars.iv.next1391, 99
+ br i1 %exitcond1393.not, label %.loopexit, label %.lr.ph1336
+
+.loopexit: ; preds = %.lr.ph1336, %._crit_edge1334, %thread-pre-split
+ store volatile i32 0, ptr null, align 4
+ br label %common.ret
+}
>From aa8c6f3036ba367b09f0b0372113ab1100941793 Mon Sep 17 00:00:00 2001
From: Afonso Rafael <afonsorafael at sapo.pt>
Date: Thu, 23 Apr 2026 17:38:44 +0000
Subject: [PATCH 3/3] [LoopFusion] Simplify guard condition in pr193641.ll
---
llvm/test/Transforms/LoopFusion/pr193641.ll | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/test/Transforms/LoopFusion/pr193641.ll b/llvm/test/Transforms/LoopFusion/pr193641.ll
index 51e7099f324a4..e06ec2ce2cd6d 100644
--- a/llvm/test/Transforms/LoopFusion/pr193641.ll
+++ b/llvm/test/Transforms/LoopFusion/pr193641.ll
@@ -5,7 +5,7 @@
; Loop fusion should not crash when flushing the DomTreeUpdater due to
; missed edge removals when deleting basic blocks.
-define void @_QMdiags_on_lat_aux_gridPinit_lat_aux_grid(i1 %cond, i1 %cond1, i1 %0, i1 %1) {
+define void @_QMdiags_on_lat_aux_gridPinit_lat_aux_grid(i1 %cond, i1 %cond1, i1 %0) {
.critedge:
br i1 %cond, label %common.ret, label %thread-pre-split
@@ -27,7 +27,7 @@ thread-pre-split: ; preds = %.critedge
br i1 %exitcond1389.not, label %._crit_edge1334, label %.lr.ph1333
._crit_edge1334: ; preds = %.lr.ph1333, %2
- br i1 %1, label %.lr.ph1336, label %.loopexit
+ br i1 %0, label %.lr.ph1336, label %.loopexit
.lr.ph1336: ; preds = %.lr.ph1336, %._crit_edge1334
%indvars.iv1390 = phi i64 [ %indvars.iv.next1391, %.lr.ph1336 ], [ 0, %._crit_edge1334 ]
More information about the llvm-commits
mailing list