diff options
-rw-r--r-- | lib/Analysis/LazyValueInfo.cpp | 31 | ||||
-rw-r--r-- | test/Transforms/CorrelatedValuePropagation/range.ll | 23 |
2 files changed, 38 insertions, 16 deletions
diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp index 83786dd..9140786 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 a9e27d6..6750546 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 +} |