[llvm] 8201e3e - [BasicBlockUtils] Don't drop callbr with unique successor

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 18 03:26:38 PDT 2022


Author: Nikita Popov
Date: 2022-07-18T12:26:29+02:00
New Revision: 8201e3ef5c84561260218bc041209611aac690e3

URL: https://github.com/llvm/llvm-project/commit/8201e3ef5c84561260218bc041209611aac690e3
DIFF: https://github.com/llvm/llvm-project/commit/8201e3ef5c84561260218bc041209611aac690e3.diff

LOG: [BasicBlockUtils] Don't drop callbr with unique successor

As callbr is now allowed to have duplicate destinations, we can
have a callbr with a unique successor. Make sure it doesn't get
dropped, as we still need to preserve the side-effect.

Added: 
    

Modified: 
    llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
    llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
index 079b2fc973b96..b08bf480923ac 100644
--- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -188,8 +188,10 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU,
 
   // Don't break self-loops.
   if (PredBB == BB) return false;
-  // Don't break unwinding instructions.
-  if (PredBB->getTerminator()->isExceptionalTerminator())
+
+  // Don't break unwinding instructions or terminators with other side-effects.
+  Instruction *PTI = PredBB->getTerminator();
+  if (PTI->isExceptionalTerminator() || PTI->mayHaveSideEffects())
     return false;
 
   // Can't merge if there are multiple distinct successors.
@@ -202,7 +204,7 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU,
   BasicBlock *NewSucc = nullptr;
   unsigned FallThruPath;
   if (PredecessorWithTwoSuccessors) {
-    if (!(PredBB_BI = dyn_cast<BranchInst>(PredBB->getTerminator())))
+    if (!(PredBB_BI = dyn_cast<BranchInst>(PTI)))
       return false;
     BranchInst *BB_JmpI = dyn_cast<BranchInst>(BB->getTerminator());
     if (!BB_JmpI || !BB_JmpI->isUnconditional())
@@ -256,7 +258,6 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU,
     Updates.push_back({DominatorTree::Delete, PredBB, BB});
   }
 
-  Instruction *PTI = PredBB->getTerminator();
   Instruction *STI = BB->getTerminator();
   Instruction *Start = &*BB->begin();
   // If there's nothing to move, mark the starting instruction as the last

diff  --git a/llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll b/llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll
index aa1b37a249ba3..368bc5e9331f7 100644
--- a/llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll
+++ b/llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll
@@ -1,28 +1,67 @@
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -disable-output
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -S -simplifycfg -simplifycfg-require-and-preserve-domtree=1 | FileCheck %s
+
+define void @callbr_duplicate_dest() {
+; CHECK-LABEL: @callbr_duplicate_dest(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    callbr void asm sideeffect "", "!i"()
+; CHECK-NEXT:    to label [[BB:%.*]] [label %bb]
+; CHECK:       bb:
+; CHECK-NEXT:    ret void
 ;
-; Test that SimplifyCFG does not cause CallBr instructions to have duplicate
-; destinations, which will cause the verifier to assert.
+entry:
+  callbr void asm sideeffect "", "!i"()
+  to label %bb [label %bb]
+
+bb:
+  ret void
+}
 
-define void @fun0() {
+; TODO: Can fold to a duplicate callbr destination.
+define void @callbr_can_fold_to_duplicate_dest1() {
+; CHECK-LABEL: @callbr_can_fold_to_duplicate_dest1(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    callbr void asm sideeffect "", "!i"()
+; CHECK-NEXT:    to label [[BB2:%.*]] [label %common.ret]
+; CHECK:       common.ret:
+; CHECK-NEXT:    ret void
+; CHECK:       bb2:
+; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
+;
 entry:
   callbr void asm sideeffect "", "!i"()
-          to label %bb2 [label %bb1]
+  to label %bb2 [label %bb1]
 
-bb1:                                              ; preds = %bb
+bb1:
   ret void
 
-bb2:                                             ; preds = %bb
+bb2:
   ret void
 }
 
-define void @fun1() {
+; TODO: Can fold to a duplicate callbr destination.
+define void @callbr_can_fold_to_duplicate_dest2() {
+; CHECK-LABEL: @callbr_can_fold_to_duplicate_dest2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    callbr void asm sideeffect "", "!i,!i"()
+; CHECK-NEXT:    to label [[COMMON_RET:%.*]] [label [[BB2:%.*]], label %bb3]
+; CHECK:       common.ret:
+; CHECK-NEXT:    ret void
+; CHECK:       bb2:
+; CHECK-NEXT:    br label [[COMMON_RET]]
+; CHECK:       bb3:
+; CHECK-NEXT:    br label [[COMMON_RET]]
+;
 entry:
-  callbr void asm sideeffect "", "!i"()
-          to label %bb2 [label %bb1]
+  callbr void asm sideeffect "", "!i,!i"()
+  to label %bb1 [label %bb2, label %bb3]
+
+bb1:
+  ret void
 
-bb2:                                             ; preds = %bb
+bb2:
   ret void
 
-bb1:                                              ; preds = %bb
+bb3:
   ret void
 }


        


More information about the llvm-commits mailing list