diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp index 3ed61a79478..a5d6e670f72 100644 --- a/lib/Analysis/LazyValueInfo.cpp +++ b/lib/Analysis/LazyValueInfo.cpp @@ -1324,12 +1324,12 @@ getValueFromConditionImpl(Value *Val, Value *Cond, bool isTrueDest, return getValueFromICmpCondition(Val, ICI, isTrueDest); // Handle conditions in the form of (cond1 && cond2), we know that on the - // true dest path both of the conditions hold. - if (!isTrueDest) - return LVILatticeVal::getOverdefined(); - + // true dest path both of the conditions hold. Similarly for conditions of + // the form (cond1 || cond2), we know that on the false dest path neither + // condition holds. BinaryOperator *BO = dyn_cast(Cond); - if (!BO || BO->getOpcode() != BinaryOperator::And) + if (!BO || (isTrueDest && BO->getOpcode() != BinaryOperator::And) || + (!isTrueDest && BO->getOpcode() != BinaryOperator::Or)) return LVILatticeVal::getOverdefined(); auto RHS = getValueFromCondition(Val, BO->getOperand(0), isTrueDest, Visited); diff --git a/test/Transforms/CorrelatedValuePropagation/add.ll b/test/Transforms/CorrelatedValuePropagation/add.ll index 0ba521c894e..b07330aa0f2 100644 --- a/test/Transforms/CorrelatedValuePropagation/add.ll +++ b/test/Transforms/CorrelatedValuePropagation/add.ll @@ -212,3 +212,98 @@ then: else: ret i32 0 } + +; Check that we can gather information for conditions is the form of +; or ( i s>= 100, Unknown ) +; CHECK-LABEL: @test12( +define void @test12(i32 %a, i1 %flag) { +entry: + %cmp.1 = icmp sge i32 %a, 100 + %cmp = or i1 %cmp.1, %flag + br i1 %cmp, label %exit, label %bb + +bb: +; CHECK: %add = add nsw i32 %a, 1 + %add = add i32 %a, 1 + br label %exit + +exit: + ret void +} + +; Check that we can gather information for conditions is the form of +; or ( i s>= 100, i s<= 0 ) +; CHECK-LABEL: @test13( +define void @test13(i32 %a) { +entry: + %cmp.1 = icmp sge i32 %a, 100 + %cmp.2 = icmp sle i32 %a, 0 + %cmp = or i1 %cmp.1, %cmp.2 + br i1 %cmp, label %exit, label %bb + +bb: +; CHECK: %add = add nuw nsw i32 %a, 1 + %add = add i32 %a, 1 + br label %exit + +exit: + ret void +} + +; Check that for conditions is the form of cond1 || cond2 we don't mistakenly +; assume that cond1 || cond2 holds down to true path. +; CHECK-LABEL: @test13_neg( +define void @test13_neg(i32 %a) { +entry: + %cmp.1 = icmp slt i32 %a, 100 + %cmp.2 = icmp sgt i32 %a, 0 + %cmp = or i1 %cmp.1, %cmp.2 + br i1 %cmp, label %bb, label %exit + +bb: +; CHECK: %add = add i32 %a, 1 + %add = add i32 %a, 1 + br label %exit + +exit: + ret void +} + +; Check that we can gather information for conditions is the form of +; or ( i s>=100, or (i s<= 0, Unknown ) +; CHECK-LABEL: @test14( +define void @test14(i32 %a, i1 %flag) { +entry: + %cmp.1 = icmp sge i32 %a, 100 + %cmp.2 = icmp sle i32 %a, 0 + %cmp.3 = or i1 %cmp.2, %flag + %cmp = or i1 %cmp.1, %cmp.3 + br i1 %cmp, label %exit, label %bb + +bb: +; CHECK: %add = add nuw nsw i32 %a, 1 + %add = add i32 %a, 1 + br label %exit + +exit: + ret void +} + +; Check that we can gather information for conditions is the form of +; or ( i s>= Unknown, ... ) +; CHECK-LABEL: @test15( +define void @test15(i32 %a, i32 %b, i1 %flag) { +entry: + %cmp.1 = icmp sge i32 %a, %b + %cmp = or i1 %cmp.1, %flag + br i1 %cmp, label %exit, label %bb + +bb: +; CHECK: %add = add nsw i32 %a, 1 + %add = add i32 %a, 1 + br label %exit + +exit: + ret void +} +