From: Craig Topper Date: Fri, 23 Jun 2017 01:08:16 +0000 (+0000) Subject: [LVI] Teach LVI to reason about ORs of icmps similar to how it reasons about ANDs... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9c13e87ea8c8ecef061649d7ec9956490636f298;p=llvm [LVI] Teach LVI to reason about ORs of icmps similar to how it reasons about ANDs of icmps Summary: LVI can reason about an AND of icmps on the true dest of a branch. I believe we can do similar for the false dest of ORs. This allows us to get the same answer for the demorganed versions of some of the AND test cases as you can see. Reviewers: anna, reames Reviewed By: reames Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D34431 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306076 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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 +} +