Skip to content

Commit 8fbba30

Browse files
committed
[StructurizeCFG] Fix a crash caused by not updating Predicates properly
A very simple IR could crash the pass at `assert(BB != Parent);`. ``` define void @foo() { entry: br i1 false, label %cond.true, label %cond.false cond.true: ; preds = %entry br label %cond.end cond.false: ; preds = %entry br label %cond.end cond.end: ; preds = %cond.false, %cond.true ret void } ``` TBH I'm not sure if my fix is right. I don't know why we don't update `Predicates` after we replace a conditional branch with a branch, given the one not taken will no longer be a sucessor of the current BB. There are many test cases need to be updated but I'd like to update them after I fix this properly. Any help would be appreciated.
1 parent b46fcb9 commit 8fbba30

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

llvm/lib/Transforms/Scalar/StructurizeCFG.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,10 @@ void StructurizeCFG::changeExit(RegionNode *Node, BasicBlock *NewExit,
971971
SubRegion->replaceExit(NewExit);
972972
} else {
973973
BasicBlock *BB = Node->getNodeAs<BasicBlock>();
974+
for (BasicBlock *Succ : successors(BB)) {
975+
if (Succ != NewExit)
976+
Predicates[Succ].erase(BB);
977+
}
974978
killTerminator(BB);
975979
BranchInst *Br = BranchInst::Create(NewExit, BB);
976980
Br->setDebugLoc(TermDL[BB]);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S -passes=structurizecfg %s -o - | FileCheck %s
3+
4+
define void @foo() {
5+
; CHECK-LABEL: define void @foo() {
6+
; CHECK-NEXT: [[ENTRY:.*:]]
7+
; CHECK-NEXT: br label %[[COND_FALSE:.*]]
8+
; CHECK: [[COND_TRUE:.*]]:
9+
; CHECK-NEXT: br label %[[COND_END:.*]]
10+
; CHECK: [[COND_FALSE]]:
11+
; CHECK-NEXT: br i1 false, label %[[COND_TRUE]], label %[[COND_END]]
12+
; CHECK: [[COND_END]]:
13+
; CHECK-NEXT: ret void
14+
;
15+
entry:
16+
br i1 false, label %cond.true, label %cond.false
17+
18+
cond.true: ; preds = %entry
19+
br label %cond.end
20+
21+
cond.false: ; preds = %entry
22+
br label %cond.end
23+
24+
cond.end: ; preds = %cond.false, %cond.true
25+
ret void
26+
}

0 commit comments

Comments
 (0)