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!

llvm-svn: 179587
This commit is contained in:
Hans Wennborg 2013-04-16 08:35:36 +00:00
parent b4edc00933
commit 9311589e8d
2 changed files with 24 additions and 1 deletions

View File

@ -3073,7 +3073,12 @@ static bool TurnSwitchRangeIntoICmp(SwitchInst *SI, IRBuilder<> &Builder) {
Value *Sub = SI->getCondition();
if (!Offset->isNullValue())
Sub = Builder.CreateAdd(Sub, Offset, Sub->getName()+".off");
Value *Cmp = Builder.CreateICmpULT(Sub, NumCases, "switch");
Value *Cmp;
// If NumCases overflowed, then all possible values jump to the successor.
if (NumCases->isNullValue() && SI->getNumCases() != 0)
Cmp = ConstantInt::getTrue(SI->getContext());
else
Cmp = Builder.CreateICmpULT(Sub, NumCases, "switch");
BranchInst *NewBI = Builder.CreateCondBr(
Cmp, SI->case_begin().getCaseSuccessor(), SI->getDefaultDest());

View File

@ -37,3 +37,21 @@ lor.end:
; CHECK: @test2
; CHECK: %switch = icmp ult i32 %x, 2
}
define i32 @test3(i1 %flag) {
entry:
switch i1 %flag, label %bad [
i1 true, label %good
i1 false, label %good
]
good:
ret i32 0
bad:
ret i32 1
; CHECK: @test3
; CHECK: entry:
; CHECK-NEXT: ret i32 0
}