Skip to content

Commit 733740b

Browse files
committed
Fix a phase-ordering problem in SimplifyCFG.
Switch simplification could sometimes fail to notice when an intermediate case removal caused the switch condition to become constant. This would cause the switch to be simplified into a conditional branch rather than a direct branch. Most of the time this didn't matter, except that occasionally downstream parts of SimplifyCFG expect tautological branches to already have been eliminated. The missed handling in switch simplification would cause an assertion failure in the downstream code. Triggering the assertion failure is fairly sensitive to the exact order of various simplifications. Fixes #59768 Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D140831
1 parent d65e66a commit 733740b

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,14 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions,
237237
DefaultDest->removePredecessor(ParentBB);
238238
i = SI->removeCase(i);
239239
e = SI->case_end();
240+
241+
// Removing this case may have made the condition constant. In that
242+
// case, update CI and restart iteration through the cases.
243+
if (auto *NewCI = dyn_cast<ConstantInt>(SI->getCondition())) {
244+
CI = NewCI;
245+
i = SI->case_begin();
246+
}
247+
240248
Changed = true;
241249
continue;
242250
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt -S -passes="simplifycfg<forward-switch-cond;no-keep-loops>" < %s | FileCheck %s
3+
4+
define i8 @test() {
5+
; CHECK-LABEL: @test(
6+
; CHECK-NEXT: entry:
7+
; CHECK-NEXT: br label [[LOOP2:%.*]]
8+
; CHECK: loop2:
9+
; CHECK-NEXT: br label [[LOOP2]]
10+
;
11+
entry:
12+
br label %loop
13+
14+
loop:
15+
%phi1 = phi i8 [ 0, %entry ], [ %phi2, %loop2 ]
16+
br label %loop2
17+
18+
loop2:
19+
%phi2 = phi i8 [ %phi1, %loop ], [ 0, %loop2 ]
20+
switch i8 %phi2, label %loop [
21+
i8 0, label %loop2
22+
i8 1, label %exit
23+
]
24+
25+
exit:
26+
ret i8 0
27+
}

0 commit comments

Comments
 (0)