[llvm] 6c6c968 - [AggressiveInstCombine] Bail out on graph nodes in unreachable blocks (#226383)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 25 00:55:35 PDT 2026
Author: Timur Baidusenov
Date: 2026-09-25T07:55:23Z
New Revision: 6c6c968398f25c2a56705004f2eb68d21d5de900
URL: https://github.com/llvm/llvm-project/commit/6c6c968398f25c2a56705004f2eb68d21d5de900
DIFF: https://github.com/llvm/llvm-project/commit/6c6c968398f25c2a56705004f2eb68d21d5de900.diff
LOG: [AggressiveInstCombine] Bail out on graph nodes in unreachable blocks (#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.
Added:
Modified:
llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp
llvm/test/Transforms/AggressiveInstCombine/trunc_unreachable_bb.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp
index 30f535a5e4df4..cd0f71d3ae0bf 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 3d8a679b31dff..c3fb7911d8d26 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