make LazyValueInfo analyze the default case of switch statements (we know that in the default branch the value cannot be any of the switch cases)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159353 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nuno Lopes 2012-06-28 16:13:37 +00:00
parent 62d7afad8f
commit e50487796d
2 changed files with 38 additions and 16 deletions

View File

@ -835,24 +835,23 @@ static bool getEdgeValueLocal(Value *Val, BasicBlock *BBFrom,
// If the edge was formed by a switch on the value, then we may know exactly
// what it is.
if (SwitchInst *SI = dyn_cast<SwitchInst>(BBFrom->getTerminator())) {
if (SI->getCondition() == Val) {
// We don't know anything in the default case.
if (SI->getDefaultDest() == BBTo) {
Result.markOverdefined();
return true;
}
unsigned BitWidth = Val->getType()->getIntegerBitWidth();
ConstantRange EdgesVals(BitWidth, false/*isFullSet*/);
for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end();
i != e; ++i) {
if (i.getCaseSuccessor() != BBTo) continue;
ConstantRange EdgeVal(i.getCaseValue()->getValue());
if (SI->getCondition() != Val)
return false;
bool DefaultCase = SI->getDefaultDest() == BBTo;
unsigned BitWidth = Val->getType()->getIntegerBitWidth();
ConstantRange EdgesVals(BitWidth, DefaultCase/*isFullSet*/);
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)
EdgesVals = EdgesVals.unionWith(EdgeVal);
}
Result = LVILatticeVal::getRange(EdgesVals);
return true;
}
Result = LVILatticeVal::getRange(EdgesVals);
return true;
}
return false;
}

View File

@ -142,3 +142,26 @@ sw.bb:
; CHECK: ret i1 true
ret i1 %cmp2
}
; CHECK: @test7
define i1 @test7(i32 %c) nounwind {
entry:
switch i32 %c, label %sw.default [
i32 6, label %sw.bb
i32 7, label %sw.bb
]
sw.bb:
ret i1 true
sw.default:
%cmp5 = icmp eq i32 %c, 5
%cmp6 = icmp eq i32 %c, 6
%cmp7 = icmp eq i32 %c, 7
%cmp8 = icmp eq i32 %c, 8
; CHECK: %or = or i1 %cmp5, false
%or = or i1 %cmp5, %cmp6
; CHECK: %or2 = or i1 false, %cmp8
%or2 = or i1 %cmp7, %cmp8
ret i1 false
}