aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNuno Lopes <nunoplopes@sapo.pt>2012-06-28 16:13:37 +0000
committerNuno Lopes <nunoplopes@sapo.pt>2012-06-28 16:13:37 +0000
commite50487796d49624bf174bd08a86d20fcdbfb45c1 (patch)
tree4ea44bb17f03e8627a147ba7a3ecb78fa8bf6708
parent62d7afad8faf7a1fbbf3402f8e23ce4ece9ab108 (diff)
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
-rw-r--r--lib/Analysis/LazyValueInfo.cpp31
-rw-r--r--test/Transforms/CorrelatedValuePropagation/range.ll23
2 files changed, 38 insertions, 16 deletions
diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp
index 83786dd88b..9140786a1b 100644
--- a/lib/Analysis/LazyValueInfo.cpp
+++ b/lib/Analysis/LazyValueInfo.cpp
@@ -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;
}
diff --git a/test/Transforms/CorrelatedValuePropagation/range.ll b/test/Transforms/CorrelatedValuePropagation/range.ll
index a9e27d6e1d..6750546ba1 100644
--- a/test/Transforms/CorrelatedValuePropagation/range.ll
+++ b/test/Transforms/CorrelatedValuePropagation/range.ll
@@ -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
+}