summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2016-04-26 21:48:16 +0000
committerPhilip Reames <listmail@philipreames.com>2016-04-26 21:48:16 +0000
commit38c87c2e504a2e12a40ae12dd98e16058f304ac2 (patch)
treee0cb42be3aa63705127d5d2db8382ea60d75266a /llvm/lib/Analysis
parent2bee5ef462d1ffefeb17c150b2e43e15a39e4cf5 (diff)
downloadbcm5719-llvm-38c87c2e504a2e12a40ae12dd98e16058f304ac2.tar.gz
bcm5719-llvm-38c87c2e504a2e12a40ae12dd98e16058f304ac2.zip
[LVI] Infer local facts from unary expressions
As pointed out by John Regehr over in http://reviews.llvm.org/D19485, LVI was being incredibly stupid about applying its transfer rules. Rather than gathering local facts from the expression itself, it was simply giving up entirely if one of the inputs was overdefined. This greatly impacts the precision of the overall analysis and makes it far more fragile as well. This patch implements only the unary operation case. Once this is in, I'll implement the same for the binary operations. Differential Revision: http://reviews.llvm.org/D19492 llvm-svn: 267609
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/LazyValueInfo.cpp36
1 files changed, 20 insertions, 16 deletions
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 66b64c5c7a3..4abb0981baa 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -1003,23 +1003,27 @@ bool LazyValueInfoCache::solveBlockValueSelect(LVILatticeVal &BBLV,
bool LazyValueInfoCache::solveBlockValueCast(LVILatticeVal &BBLV,
Instruction *BBI,
BasicBlock *BB) {
- // Figure out the range of the LHS. If that fails, bail.
- if (!hasBlockValue(BBI->getOperand(0), BB)) {
+ // Figure out the range of the LHS. If that fails, we still apply the
+ // transfer rule on the full set since we may be able to locally infer
+ // interesting facts.
+ if (!hasBlockValue(BBI->getOperand(0), BB))
if (pushBlockValue(std::make_pair(BB, BBI->getOperand(0))))
+ // More work to do before applying this transfer rule.
return false;
- BBLV.markOverdefined();
- return true;
- }
- LVILatticeVal LHSVal = getBlockValue(BBI->getOperand(0), BB);
- intersectAssumeBlockValueConstantRange(BBI->getOperand(0), LHSVal, BBI);
- if (!LHSVal.isConstantRange()) {
- BBLV.markOverdefined();
- return true;
+ const unsigned OperandBitWidth =
+ BBI->getOperand(0)->getType()->getPrimitiveSizeInBits();
+
+ ConstantRange LHSRange = ConstantRange(OperandBitWidth);
+ if (hasBlockValue(BBI->getOperand(0), BB)) {
+ LVILatticeVal LHSVal = getBlockValue(BBI->getOperand(0), BB);
+ intersectAssumeBlockValueConstantRange(BBI->getOperand(0), LHSVal, BBI);
+ if (LHSVal.isConstantRange())
+ LHSRange = LHSVal.getConstantRange();
}
- ConstantRange LHSRange = LHSVal.getConstantRange();
- IntegerType *ResultTy = cast<IntegerType>(BBI->getType());
+ const unsigned ResultBitWidth =
+ cast<IntegerType>(BBI->getType())->getBitWidth();
// NOTE: We're currently limited by the set of operations that ConstantRange
// can evaluate symbolically. Enhancing that set will allows us to analyze
@@ -1027,13 +1031,13 @@ bool LazyValueInfoCache::solveBlockValueCast(LVILatticeVal &BBLV,
LVILatticeVal Result;
switch (BBI->getOpcode()) {
case Instruction::Trunc:
- Result.markConstantRange(LHSRange.truncate(ResultTy->getBitWidth()));
+ Result.markConstantRange(LHSRange.truncate(ResultBitWidth));
break;
case Instruction::SExt:
- Result.markConstantRange(LHSRange.signExtend(ResultTy->getBitWidth()));
+ Result.markConstantRange(LHSRange.signExtend(ResultBitWidth));
break;
case Instruction::ZExt:
- Result.markConstantRange(LHSRange.zeroExtend(ResultTy->getBitWidth()));
+ Result.markConstantRange(LHSRange.zeroExtend(ResultBitWidth));
break;
case Instruction::BitCast:
Result.markConstantRange(LHSRange);
@@ -1152,7 +1156,7 @@ bool getValueFromFromCondition(Value *Val, ICmpInst *ICI,
return true;
}
}
-
+
return false;
}
OpenPOWER on IntegriCloud