JumpThreading: when default destination is the destination of some cases in a

switch, make sure we include the value for the cases when calculating edge
value from switch to the default destination.

rdar://12241132


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163270 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Manman Ren 2012-09-05 23:45:58 +00:00
parent ec65be84cd
commit 408853ea16
2 changed files with 42 additions and 3 deletions

View File

@ -847,9 +847,12 @@ static bool getEdgeValueLocal(Value *Val, BasicBlock *BBFrom,
for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end();
i != e; ++i) {
ConstantRange EdgeVal(i.getCaseValue()->getValue());
if (DefaultCase)
EdgesVals = EdgesVals.difference(EdgeVal);
else if (i.getCaseSuccessor() == BBTo)
if (DefaultCase) {
// It is possible that the default destination is the destination of
// some cases. There is no need to perform difference for those cases.
if (i.getCaseSuccessor() != BBTo)
EdgesVals = EdgesVals.difference(EdgeVal);
} else if (i.getCaseSuccessor() == BBTo)
EdgesVals = EdgesVals.unionWith(EdgeVal);
}
Result = LVILatticeVal::getRange(EdgesVals);

View File

@ -121,3 +121,39 @@ L4:
call void @quux()
br label %L0
}
; Make sure the edge value of %0 from entry to L2 includes 0 and L3 is
; reachable.
; CHECK: test_switch_default
; CHECK: entry:
; CHECK: load
; CHECK: switch
; CHECK: [[THREADED:[A-Za-z.0-9]+]]:
; CHECK: store
; CHECK: br
; CHECK: L2:
; CHECK: icmp
define void @test_switch_default(i32* nocapture %status) nounwind {
entry:
%0 = load i32* %status, align 4
switch i32 %0, label %L2 [
i32 5061, label %L1
i32 0, label %L2
]
L1:
store i32 10025, i32* %status, align 4
br label %L2
L2:
%1 = load i32* %status, align 4
%cmp57.i = icmp eq i32 %1, 0
br i1 %cmp57.i, label %L3, label %L4
L3:
store i32 10000, i32* %status, align 4
br label %L4
L4:
ret void
}