Skip to content

Commit c2dafe1

Browse files
committed
[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
1 parent 6e60e10 commit c2dafe1

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,21 @@ static bool mergeEmptyReturnBlocks(Function &F) {
104104
continue;
105105
}
106106

107+
// Skip merging if this would result in a CallBr instruction with a
108+
// duplicate destination. FIXME: See note in CodeGenPrepare.cpp.
109+
bool SkipCallBr = false;
110+
for (pred_iterator PI = pred_begin(&BB), E = pred_end(&BB);
111+
PI != E && !SkipCallBr; ++PI) {
112+
if (auto *CBI = dyn_cast<CallBrInst>((*PI)->getTerminator()))
113+
for (unsigned i = 0, e = CBI->getNumSuccessors(); i != e; ++i)
114+
if (RetBlock == CBI->getSuccessor(i)) {
115+
SkipCallBr = true;
116+
break;
117+
}
118+
}
119+
if (SkipCallBr)
120+
continue;
121+
107122
// Otherwise, we found a duplicate return block. Merge the two.
108123
Changed = true;
109124

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; RUN: opt < %s -simplifycfg -disable-output
2+
;
3+
; Test that SimplifyCFG does not cause CallBr instructions to have duplicate
4+
; destinations, which will cause the verifier to assert.
5+
6+
define void @fun0() {
7+
entry:
8+
callbr void asm sideeffect "", "X"(i8* blockaddress(@fun0, %bb1))
9+
to label %bb2 [label %bb1]
10+
11+
bb1: ; preds = %bb
12+
ret void
13+
14+
bb2: ; preds = %bb
15+
ret void
16+
}
17+
18+
define void @fun1() {
19+
entry:
20+
callbr void asm sideeffect "", "X"(i8* blockaddress(@fun1, %bb1))
21+
to label %bb2 [label %bb1]
22+
23+
bb2: ; preds = %bb
24+
ret void
25+
26+
bb1: ; preds = %bb
27+
ret void
28+
}

0 commit comments

Comments
 (0)