[llvm] r278231 - [LVI] Handle conditions in the form of (cond1 && cond2)
Artur Pilipenko via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 10 08:13:15 PDT 2016
Author: apilipenko
Date: Wed Aug 10 10:13:15 2016
New Revision: 278231
URL: http://llvm.org/viewvc/llvm-project?rev=278231&view=rev
Log:
[LVI] Handle conditions in the form of (cond1 && cond2)
Teach LVI how to gather information from conditions in the form of (cond1 && cond2). Our out-of-tree front-end emits range checks in this form.
Reviewed By: sanjoy
Differential Revision: http://reviews.llvm.org/D23200
Modified:
llvm/trunk/lib/Analysis/LazyValueInfo.cpp
llvm/trunk/test/Transforms/CorrelatedValuePropagation/add.ll
Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=278231&r1=278230&r2=278231&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Wed Aug 10 10:13:15 2016
@@ -1167,14 +1167,8 @@ bool LazyValueInfoCache::solveBlockValue
return true;
}
-LVILatticeVal getValueFromCondition(Value *Val, Value *Cond, bool isTrueDest) {
- assert(Cond && "precondition");
-
- // For now we only support ICmpInst conditions
- ICmpInst *ICI = dyn_cast<ICmpInst>(Cond);
- if (!ICI)
- return LVILatticeVal::getOverdefined();
-
+static LVILatticeVal getValueFromICmpCondition(Value *Val, ICmpInst *ICI,
+ bool isTrueDest) {
Value *LHS = ICI->getOperand(0);
Value *RHS = ICI->getOperand(1);
CmpInst::Predicate Predicate = ICI->getPredicate();
@@ -1233,6 +1227,46 @@ LVILatticeVal getValueFromCondition(Valu
return LVILatticeVal::getOverdefined();
}
+static LVILatticeVal
+getValueFromCondition(Value *Val, Value *Cond, bool isTrueDest,
+ DenseMap<Value*, LVILatticeVal> &Visited);
+
+static LVILatticeVal
+getValueFromConditionImpl(Value *Val, Value *Cond, bool isTrueDest,
+ DenseMap<Value*, LVILatticeVal> &Visited) {
+ if (ICmpInst *ICI = dyn_cast<ICmpInst>(Cond))
+ 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();
+
+ BinaryOperator *BO = dyn_cast<BinaryOperator>(Cond);
+ if (!BO || BO->getOpcode() != BinaryOperator::And)
+ return LVILatticeVal::getOverdefined();
+
+ auto RHS = getValueFromCondition(Val, BO->getOperand(0), isTrueDest, Visited);
+ auto LHS = getValueFromCondition(Val, BO->getOperand(1), isTrueDest, Visited);
+ return intersect(RHS, LHS);
+}
+
+static LVILatticeVal
+getValueFromCondition(Value *Val, Value *Cond, bool isTrueDest,
+ DenseMap<Value*, LVILatticeVal> &Visited) {
+ auto I = Visited.find(Cond);
+ if (I != Visited.end())
+ return I->second;
+ return Visited[Cond] = getValueFromConditionImpl(Val, Cond, isTrueDest,
+ Visited);
+}
+
+LVILatticeVal getValueFromCondition(Value *Val, Value *Cond, bool isTrueDest) {
+ assert(Cond && "precondition");
+ DenseMap<Value*, LVILatticeVal> Visited;
+ return getValueFromCondition(Val, Cond, isTrueDest, Visited);
+}
+
/// \brief Compute the value of Val on the edge BBFrom -> BBTo. Returns false if
/// Val is not constrained on the edge. Result is unspecified if return value
/// is false.
Modified: llvm/trunk/test/Transforms/CorrelatedValuePropagation/add.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CorrelatedValuePropagation/add.ll?rev=278231&r1=278230&r2=278231&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/CorrelatedValuePropagation/add.ll (original)
+++ llvm/trunk/test/Transforms/CorrelatedValuePropagation/add.ll Wed Aug 10 10:13:15 2016
@@ -99,3 +99,97 @@ bb:
%add = add i32 %a, ptrtoint (i32* @b to i32)
ret void
}
+
+; Check that we can gather information for conditions is the form of
+; and ( i s< 100, Unknown )
+; CHECK-LABEL: @test7(
+define void @test7(i32 %a, i1 %flag) {
+entry:
+ %cmp.1 = icmp slt i32 %a, 100
+ %cmp = and i1 %cmp.1, %flag
+ br i1 %cmp, label %bb, label %exit
+
+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
+; and ( i s< 100, i s> 0 )
+; CHECK-LABEL: @test8(
+define void @test8(i32 %a) {
+entry:
+ %cmp.1 = icmp slt i32 %a, 100
+ %cmp.2 = icmp sgt i32 %a, 0
+ %cmp = and i1 %cmp.1, %cmp.2
+ br i1 %cmp, label %bb, label %exit
+
+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 false path.
+; CHECK-LABEL: @test8_neg(
+define void @test8_neg(i32 %a) {
+entry:
+ %cmp.1 = icmp sge i32 %a, 100
+ %cmp.2 = icmp sle i32 %a, 0
+ %cmp = and i1 %cmp.1, %cmp.2
+ br i1 %cmp, label %exit, label %bb
+
+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
+; and ( i s< 100, and (i s> 0, Unknown )
+; CHECK-LABEL: @test9(
+define void @test9(i32 %a, i1 %flag) {
+entry:
+ %cmp.1 = icmp slt i32 %a, 100
+ %cmp.2 = icmp sgt i32 %a, 0
+ %cmp.3 = and i1 %cmp.2, %flag
+ %cmp = and i1 %cmp.1, %cmp.3
+ br i1 %cmp, label %bb, label %exit
+
+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
+; and ( i s< Unknown, ... )
+; CHECK-LABEL: @test10(
+define void @test10(i32 %a, i32 %b, i1 %flag) {
+entry:
+ %cmp.1 = icmp slt i32 %a, %b
+ %cmp = and i1 %cmp.1, %flag
+ br i1 %cmp, label %bb, label %exit
+
+bb:
+; CHECK: %add = add nsw i32 %a, 1
+ %add = add i32 %a, 1
+ br label %exit
+
+exit:
+ ret void
+}
More information about the llvm-commits
mailing list