[llvm-branch-commits] [llvm] 5fbba36 - [SimplifyCFG] Skip merging return blocks if it would break a CallBr.

Tom Stellard via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Apr 16 11:12:29 PDT 2020


Author: Jonas Paulsson
Date: 2020-04-16T11:12:13-07:00
New Revision: 5fbba36cbe93f12da5c4d6063db21cf35ecc9bfc

URL: https://github.com/llvm/llvm-project/commit/5fbba36cbe93f12da5c4d6063db21cf35ecc9bfc
DIFF: https://github.com/llvm/llvm-project/commit/5fbba36cbe93f12da5c4d6063db21cf35ecc9bfc.diff

LOG: [SimplifyCFG]  Skip merging return blocks if it would break a CallBr.

SimplifyCFG should not merge empty return blocks and leave a CallBr behind
with a duplicated destination since the verifier will then trigger an
assert. This patch checks for this case and avoids the transformation.

CodeGenPrepare has a similar check which also has a FIXME comment about why
this is needed. It seems perhaps better if these two passes would eventually
instead update the CallBr instruction instead of just checking and avoiding.

This fixes https://bugs.llvm.org/show_bug.cgi?id=45062.

Review: Craig Topper

Differential Revision: https://reviews.llvm.org/D75620

(cherry picked from commit c2dafe12dc24f7f1326f5c4c6a3b23f1485f1bd6)

Added: 
    llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll

Modified: 
    llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
index 623a8b711ed8..ac53ff33e836 100644
--- a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
+++ b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
@@ -104,6 +104,21 @@ static bool mergeEmptyReturnBlocks(Function &F) {
       continue;
     }
 
+    // Skip merging if this would result in a CallBr instruction with a
+    // duplicate destination. FIXME: See note in CodeGenPrepare.cpp.
+    bool SkipCallBr = false;
+    for (pred_iterator PI = pred_begin(&BB), E = pred_end(&BB);
+         PI != E && !SkipCallBr; ++PI) {
+      if (auto *CBI = dyn_cast<CallBrInst>((*PI)->getTerminator()))
+        for (unsigned i = 0, e = CBI->getNumSuccessors(); i != e; ++i)
+          if (RetBlock == CBI->getSuccessor(i)) {
+            SkipCallBr = true;
+            break;
+          }
+    }
+    if (SkipCallBr)
+      continue;
+
     // Otherwise, we found a duplicate return block.  Merge the two.
     Changed = true;
 

diff  --git a/llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll b/llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll
new file mode 100644
index 000000000000..18210e5e0b06
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll
@@ -0,0 +1,28 @@
+; RUN: opt < %s -simplifycfg -disable-output
+;
+; Test that SimplifyCFG does not cause CallBr instructions to have duplicate
+; destinations, which will cause the verifier to assert.
+
+define void @fun0() {
+entry:
+  callbr void asm sideeffect "", "X"(i8* blockaddress(@fun0, %bb1))
+          to label %bb2 [label %bb1]
+
+bb1:                                              ; preds = %bb
+  ret void
+
+bb2:                                             ; preds = %bb
+  ret void
+}
+
+define void @fun1() {
+entry:
+  callbr void asm sideeffect "", "X"(i8* blockaddress(@fun1, %bb1))
+          to label %bb2 [label %bb1]
+
+bb2:                                             ; preds = %bb
+  ret void
+
+bb1:                                              ; preds = %bb
+  ret void
+}


        


More information about the llvm-branch-commits mailing list