[llvm] [AggressiveInstCombine] Bail out on graph nodes in unreachable blocks (PR #226383)

via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 25 00:13:29 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Timur Baidusenov (bai-tim)

<details>
<summary>Changes</summary>

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.

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


2 Files Affected:

- (modified) llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp (+5) 
- (modified) llvm/test/Transforms/AggressiveInstCombine/trunc_unreachable_bb.ll (+28) 


``````````diff
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
+}

``````````

</details>


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


More information about the llvm-commits mailing list