[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