[llvm] [AggressiveInstCombine] Bail out on graph nodes in unreachable blocks (PR #226383)
Timur Baidusenov via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 25 00:12:44 PDT 2026
https://github.com/bai-tim created https://github.com/llvm/llvm-project/pull/226383
TruncInstCombine::run() already skips truncs in unreachable blocks, but the expression graph of reachable trunc can still be extended into an unreachable block through a phi incoming value. Dead code may contain an instruction that is its own operand, and buildTruncExpressionGraph only breaks cycles at phi nodes, so such a cycle leaves the graph unorderable and ReduceExpressionGraph asks for the reduced value of a node it has not built yet.
Solution: Bail out as soon as a graph node is found in an unreachable block, which extends the existing rule from the trunc itself to the whole graph.
Fixes #58008.
>From cb207ad85b71616dc68de77615ffb5fbd14550fd Mon Sep 17 00:00:00 2001
From: Timur Baidusenov <timurbaidusenov at gmail.com>
Date: Fri, 25 Sep 2026 06:34:25 +0000
Subject: [PATCH] [AggressiveInstCombine] Bail out on graph nodes in
unreachable blocks
Fixes #58008.
---
.../TruncInstCombine.cpp | 5 ++++
.../trunc_unreachable_bb.ll | 28 +++++++++++++++++++
2 files changed, 33 insertions(+)
diff --git a/llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp
index 30f535a5e4df4d..cd0f71d3ae0bf6 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp
@@ -113,6 +113,11 @@ bool TruncInstCombine::buildTruncExpressionGraph() {
if (!I)
return false;
+ // Instructions in unreachable blocks may be part of a cycle that contains
+ // no phi node, which the reduced expression graph cannot be ordered around.
+ if (!DT.isReachableFromEntry(I->getParent()))
+ return false;
+
if (!Stack.empty() && Stack.back() == I) {
// Already handled all instruction operands, can remove it from both the
// Worklist and the Stack, and add it to the instruction info map.
diff --git a/llvm/test/Transforms/AggressiveInstCombine/trunc_unreachable_bb.ll b/llvm/test/Transforms/AggressiveInstCombine/trunc_unreachable_bb.ll
index 3d8a679b31dffd..c3fb7911d8d262 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/trunc_unreachable_bb.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/trunc_unreachable_bb.ll
@@ -45,3 +45,31 @@ for.cond641:
%conv724 = trunc i32 %or723 to i16
br label %for.cond641
}
+
+; The expression graph of a reachable trunc must not be extended into an
+; unreachable block through a phi node.
+
+define i16 @func_22() {
+; CHECK-LABEL: @func_22(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[EXIT:%.*]]
+; CHECK: for.cond641:
+; CHECK-NEXT: [[OR722:%.*]] = or i32 [[OR722]], poison
+; CHECK-NEXT: br i1 poison, label [[FOR_COND641:%.*]], label [[EXIT]]
+; CHECK: exit:
+; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OR722]], [[FOR_COND641]] ]
+; CHECK-NEXT: [[CONV724:%.*]] = trunc i32 [[PHI]] to i16
+; CHECK-NEXT: ret i16 [[CONV724]]
+;
+entry:
+ br label %exit
+
+for.cond641: ; preds = %for.cond641
+ %or722 = or i32 %or722, poison
+ br i1 poison, label %for.cond641, label %exit
+
+exit: ; preds = %for.cond641, %entry
+ %phi = phi i32 [ 0, %entry ], [ %or722, %for.cond641 ]
+ %conv724 = trunc i32 %phi to i16
+ ret i16 %conv724
+}
More information about the llvm-commits
mailing list