diff options
author | Artur Pilipenko <apilipenko@azulsystems.com> | 2016-08-10 15:13:15 +0000 |
---|---|---|
committer | Artur Pilipenko <apilipenko@azulsystems.com> | 2016-08-10 15:13:15 +0000 |
commit | fd223d5d25d3faf5693847a3e1e08aaf1a430a80 (patch) | |
tree | 0d3eca1c9fcd4a4e13669f172a78e81717c1bc7b /llvm/lib/Analysis/LazyValueInfo.cpp | |
parent | 9ef1215c8002615a6cd33c655bd4b44dd5f03e18 (diff) | |
download | llvm-fd223d5d25d3faf5693847a3e1e08aaf1a430a80.zip llvm-fd223d5d25d3faf5693847a3e1e08aaf1a430a80.tar.gz llvm-fd223d5d25d3faf5693847a3e1e08aaf1a430a80.tar.bz2 |
[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
llvm-svn: 278231
Diffstat (limited to 'llvm/lib/Analysis/LazyValueInfo.cpp')
-rw-r--r-- | llvm/lib/Analysis/LazyValueInfo.cpp | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index f41978f..5faa975 100644 --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -1167,14 +1167,8 @@ bool LazyValueInfoCache::solveBlockValueBinaryOp(LVILatticeVal &BBLV, 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(Value *Val, Value *Cond, bool isTrueDest) { 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. |