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

Jonas Paulsson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 4 09:00:32 PST 2020


jonpa created this revision.
jonpa added reviewers: craig.topper, aivchenk, mike.dvoretsky.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.

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.


https://reviews.llvm.org/D75620

Files:
  llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
  llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll


Index: llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll
===================================================================
--- /dev/null
+++ 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
+}
Index: llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
+++ llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
@@ -104,6 +104,21 @@
       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;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D75620.248194.patch
Type: text/x-patch
Size: 1955 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200304/3e763011/attachment.bin>


More information about the llvm-commits mailing list