Index: llvm/trunk/lib/Analysis/LazyValueInfo.cpp =================================================================== --- llvm/trunk/lib/Analysis/LazyValueInfo.cpp +++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp @@ -911,6 +911,25 @@ return true; } + // Can we constrain the facts about the true and false values by using the + // condition itself? This shows up with idioms like e.g. select(a > 5, a, 5). + // TODO: We could potentially refine an overdefined true value above. + if (auto *ICI = dyn_cast(SI->getCondition())) { + LVILatticeVal TrueValTaken, FalseValTaken; + if (!getValueFromFromCondition(SI->getTrueValue(), ICI, + TrueValTaken, true)) + TrueValTaken.markOverdefined(); + if (!getValueFromFromCondition(SI->getFalseValue(), ICI, + FalseValTaken, false)) + FalseValTaken.markOverdefined(); + + TrueVal = intersect(TrueVal, TrueValTaken); + FalseVal = intersect(FalseVal, FalseValTaken); + } + + // TODO: handle idioms like min & max where we can use a more precise merge + // when our inputs are constant ranges. + LVILatticeVal Result; // Start Undefined. Result.mergeIn(TrueVal, DL); Result.mergeIn(FalseVal, DL); Index: llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll =================================================================== --- llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll +++ llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll @@ -167,3 +167,52 @@ ; CHECK: ret i1 true ret i1 true } + +;; Using the condition to clamp the result +;; + +define i1 @test5(i32* %p, i1 %unknown) { +; CHECK-LABEL: @test5 + %pval = load i32, i32* %p + %cmp1 = icmp slt i32 %pval, 255 + br i1 %cmp1, label %next, label %exit + +next: + %cond = icmp sgt i32 %pval, 0 + %min = select i1 %cond, i32 %pval, i32 5 + ;; TODO: This pointless branch shouldn't be neccessary + br label %next2 +next2: +; CHECK-LABEL: next2: +; CHECK: ret i1 false + %res = icmp eq i32 %min, -1 + ret i1 %res + +exit: +; CHECK-LABEL: exit: +; CHECK: ret i1 true + ret i1 true +} + +define i1 @test6(i32* %p, i1 %unknown) { +; CHECK-LABEL: @test6 + %pval = load i32, i32* %p + %cmp1 = icmp ult i32 %pval, 255 + br i1 %cmp1, label %next, label %exit + +next: + %cond = icmp ne i32 %pval, 254 + %sel = select i1 %cond, i32 %pval, i32 1 + ;; TODO: This pointless branch shouldn't be neccessary + br label %next2 +next2: +; CHECK-LABEL: next2: +; CHECK: ret i1 true + %res = icmp slt i32 %sel, 254 + ret i1 %res + +exit: +; CHECK-LABEL: exit: +; CHECK: ret i1 true + ret i1 true +}