Skip to content

Commit a121e24

Browse files
committed
simplifycfg: Fix integer overflow converting switch into icmp.
If a switch instruction has a case for every possible value of its type, with the same successor, SimplifyCFG would replace it with an icmp ult, but the computation of the bound overflows in that case, which inverts the test. Patch by Jed Davis! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179587 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent ad36608 commit a121e24

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

lib/Transforms/Utils/SimplifyCFG.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -3073,7 +3073,12 @@ static bool TurnSwitchRangeIntoICmp(SwitchInst *SI, IRBuilder<> &Builder) {
30733073
Value *Sub = SI->getCondition();
30743074
if (!Offset->isNullValue())
30753075
Sub = Builder.CreateAdd(Sub, Offset, Sub->getName()+".off");
3076-
Value *Cmp = Builder.CreateICmpULT(Sub, NumCases, "switch");
3076+
Value *Cmp;
3077+
// If NumCases overflowed, then all possible values jump to the successor.
3078+
if (NumCases->isNullValue() && SI->getNumCases() != 0)
3079+
Cmp = ConstantInt::getTrue(SI->getContext());
3080+
else
3081+
Cmp = Builder.CreateICmpULT(Sub, NumCases, "switch");
30773082
BranchInst *NewBI = Builder.CreateCondBr(
30783083
Cmp, SI->case_begin().getCaseSuccessor(), SI->getDefaultDest());
30793084

test/Transforms/SimplifyCFG/switch-to-icmp.ll

+18
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,21 @@ lor.end:
3737
; CHECK: @test2
3838
; CHECK: %switch = icmp ult i32 %x, 2
3939
}
40+
41+
define i32 @test3(i1 %flag) {
42+
entry:
43+
switch i1 %flag, label %bad [
44+
i1 true, label %good
45+
i1 false, label %good
46+
]
47+
48+
good:
49+
ret i32 0
50+
51+
bad:
52+
ret i32 1
53+
54+
; CHECK: @test3
55+
; CHECK: entry:
56+
; CHECK-NEXT: ret i32 0
57+
}

0 commit comments

Comments
 (0)