diff options
| author | Philip Reames <listmail@philipreames.com> | 2016-04-26 21:48:16 +0000 |
|---|---|---|
| committer | Philip Reames <listmail@philipreames.com> | 2016-04-26 21:48:16 +0000 |
| commit | 38c87c2e504a2e12a40ae12dd98e16058f304ac2 (patch) | |
| tree | e0cb42be3aa63705127d5d2db8382ea60d75266a /llvm/lib/Analysis | |
| parent | 2bee5ef462d1ffefeb17c150b2e43e15a39e4cf5 (diff) | |
| download | bcm5719-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.cpp | 36 |
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; } |

