[llvm] 143a869 - [InstCombine] Handle unreachable edge when branching to loop

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 7 07:07:26 PDT 2023


Author: Nikita Popov
Date: 2023-07-07T16:07:18+02:00
New Revision: 143a869cf249e54daa95718fc7afa35fe672c531

URL: https://github.com/llvm/llvm-project/commit/143a869cf249e54daa95718fc7afa35fe672c531
DIFF: https://github.com/llvm/llvm-project/commit/143a869cf249e54daa95718fc7afa35fe672c531.diff

LOG: [InstCombine] Handle unreachable edge when branching to loop

The successor is unreachable if either this is the only edge, or
this is an edge into a loop, in which case other predecessors
don't matter. This is exactly what the edge dominance check does.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
    llvm/test/Transforms/InstCombine/unreachable-code.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index b38cde63ec2f87..971b17d2ce54b0 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2711,9 +2711,19 @@ bool InstCombinerImpl::handleUnreachableFrom(Instruction *I) {
 bool InstCombinerImpl::handlePotentiallyDeadSuccessors(BasicBlock *BB,
                                                        BasicBlock *LiveSucc) {
   bool Changed = false;
-  for (BasicBlock *Succ : successors(BB))
-    if (Succ != LiveSucc && Succ->getSinglePredecessor())
-      Changed |= handleUnreachableFrom(&Succ->front());
+  for (BasicBlock *Succ : successors(BB)) {
+    // The live successor isn't dead.
+    if (Succ == LiveSucc)
+      continue;
+
+    if (!all_of(predecessors(Succ), [&](BasicBlock *Pred) {
+          return DT.dominates(BasicBlockEdge(BB, Succ),
+                              BasicBlockEdge(Pred, Succ));
+        }))
+      continue;
+
+    Changed |= handleUnreachableFrom(&Succ->front());
+  }
   return Changed;
 }
 

diff  --git a/llvm/test/Transforms/InstCombine/unreachable-code.ll b/llvm/test/Transforms/InstCombine/unreachable-code.ll
index bfea1e3789d12c..a00f13878d2006 100644
--- a/llvm/test/Transforms/InstCombine/unreachable-code.ll
+++ b/llvm/test/Transforms/InstCombine/unreachable-code.ll
@@ -229,24 +229,14 @@ join:
 }
 
 define void @br_not_into_loop(i1 %x) {
-; DEFAULT-LABEL: define void @br_not_into_loop
-; DEFAULT-SAME: (i1 [[X:%.*]]) {
-; DEFAULT-NEXT:    br i1 true, label [[EXIT:%.*]], label [[LOOP:%.*]]
-; DEFAULT:       loop:
-; DEFAULT-NEXT:    br label [[LOOP]]
-; DEFAULT:       exit:
-; DEFAULT-NEXT:    call void @dummy()
-; DEFAULT-NEXT:    ret void
-;
-; MAX1-LABEL: define void @br_not_into_loop
-; MAX1-SAME: (i1 [[X:%.*]]) {
-; MAX1-NEXT:    br i1 true, label [[EXIT:%.*]], label [[LOOP:%.*]]
-; MAX1:       loop:
-; MAX1-NEXT:    call void @dummy()
-; MAX1-NEXT:    br label [[LOOP]]
-; MAX1:       exit:
-; MAX1-NEXT:    call void @dummy()
-; MAX1-NEXT:    ret void
+; CHECK-LABEL: define void @br_not_into_loop
+; CHECK-SAME: (i1 [[X:%.*]]) {
+; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    br label [[LOOP]]
+; CHECK:       exit:
+; CHECK-NEXT:    call void @dummy()
+; CHECK-NEXT:    ret void
 ;
   %c = or i1 %x, true
   br i1 %c, label %exit, label %loop
@@ -281,3 +271,6 @@ exit:
   call void @dummy()
   ret void
 }
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; DEFAULT: {{.*}}
+; MAX1: {{.*}}


        


More information about the llvm-commits mailing list