[llvm] [BDCE] Eliminate unreachable blocks to prevent incorrect replacement (PR #194614)

Hongyu Chen via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 28 06:17:01 PDT 2026


https://github.com/XChy created https://github.com/llvm/llvm-project/pull/194614

Fixes #194564.

>From c07f753d50f86ff38327050410e6cc9de63e4e10 Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Tue, 28 Apr 2026 20:57:30 +0800
Subject: [PATCH] [BDCE] Eliminate unreachable blocks to prevent incorrect
 replacement

---
 llvm/lib/Transforms/Scalar/BDCE.cpp    |  9 +++++++--
 llvm/test/Transforms/BDCE/dead-uses.ll | 15 +++++++++++++++
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/BDCE.cpp b/llvm/lib/Transforms/Scalar/BDCE.cpp
index d96dbca30fdb1..81d43e10784fd 100644
--- a/llvm/lib/Transforms/Scalar/BDCE.cpp
+++ b/llvm/lib/Transforms/Scalar/BDCE.cpp
@@ -26,6 +26,7 @@
 #include "llvm/IR/PatternMatch.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/Local.h"
 
 using namespace llvm;
@@ -201,10 +202,14 @@ static bool bitTrackingDCE(Function &F, DemandedBits &DB) {
 
 PreservedAnalyses BDCEPass::run(Function &F, FunctionAnalysisManager &AM) {
   auto &DB = AM.getResult<DemandedBitsAnalysis>(F);
-  if (!bitTrackingDCE(F, DB))
+
+  // Avoid incorrect replacement of non-SSA values in unreachable blocks.
+  bool CFGChanged = EliminateUnreachableBlocks(F);
+  if (!CFGChanged && !bitTrackingDCE(F, DB))
     return PreservedAnalyses::all();
 
   PreservedAnalyses PA;
-  PA.preserveSet<CFGAnalyses>();
+  if (!CFGChanged)
+    PA.preserveSet<CFGAnalyses>();
   return PA;
 }
diff --git a/llvm/test/Transforms/BDCE/dead-uses.ll b/llvm/test/Transforms/BDCE/dead-uses.ll
index 5c1677e59a8b8..449da755a7efa 100644
--- a/llvm/test/Transforms/BDCE/dead-uses.ll
+++ b/llvm/test/Transforms/BDCE/dead-uses.ll
@@ -101,3 +101,18 @@ define void @dead_use_invalidation(i32 %a) {
   ret void
 }
 declare void @dummy(i32)
+
+define i64 @deadcode_self_reference() {
+; CHECK-LABEL: @deadcode_self_reference(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret i64 0
+;
+entry:
+  ret i64 0
+
+loop:
+  %or = or i32 %or, 0
+  %conv = trunc i32 %or to i16
+  %call = call i16 null(i16 0, i16 %conv)
+  br label %loop
+}



More information about the llvm-commits mailing list