summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2016-04-26 23:10:35 +0000
committerPhilip Reames <listmail@philipreames.com>2016-04-26 23:10:35 +0000
commit053c2a6f25e48132d8f66bd73f3575da47cfde88 (patch)
tree5ea9e98328394ec62faee41bb052e716bb1a4fc5
parentc1b9d47b3b30ba6714776e4a255968946e48bb29 (diff)
downloadbcm5719-llvm-053c2a6f25e48132d8f66bd73f3575da47cfde88.tar.gz
bcm5719-llvm-053c2a6f25e48132d8f66bd73f3575da47cfde88.zip
[LVI] Apply transfer rule for overdefine inputs for binary operators
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 builds on 267609 which did the same thing for unary casts. llvm-svn: 267620
-rw-r--r--llvm/lib/Analysis/LazyValueInfo.cpp27
-rw-r--r--llvm/test/Transforms/CorrelatedValuePropagation/basic.ll23
2 files changed, 39 insertions, 11 deletions
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 6bc639cf8b2..3b0ffb8d400 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -1063,22 +1063,27 @@ bool LazyValueInfoCache::solveBlockValueCast(LVILatticeVal &BBLV,
bool LazyValueInfoCache::solveBlockValueBinaryOp(LVILatticeVal &BBLV,
Instruction *BBI,
BasicBlock *BB) {
+
+ assert(BBI->getOperand(0)->getType()->isSized() &&
+ "all operands to binary operators are sized");
- // 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, use a conservative range,
+ // but apply the transfer rule anyways. This lets us pick up facts from
+ // expressions like "and i32 (call i32 @foo()), 32"
+ 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 =
+ DL.getTypeSizeInBits(BBI->getOperand(0)->getType());
+ 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();
ConstantInt *RHS = cast<ConstantInt>(BBI->getOperand(1));
ConstantRange RHSRange = ConstantRange(RHS->getValue());
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
index 9f41807cc55..d0a17306c6b 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
@@ -440,3 +440,26 @@ entry:
exit:
ret i1 %cmp
}
+
+
+define i1 @and_unknown(i32 %a) {
+; CHECK-LABEL: @and_unknown
+; CHECK: ret i1 true
+entry:
+ %and = and i32 %a, 128
+ %cmp = icmp sle i32 %and, 128
+ br label %exit
+exit:
+ ret i1 %cmp
+}
+
+define i1 @lshr_unknown(i32 %a) {
+; CHECK-LABEL: @lshr_unknown
+; CHECK: ret i1 true
+entry:
+ %and = lshr i32 %a, 30
+ %cmp = icmp sle i32 %and, 128
+ br label %exit
+exit:
+ ret i1 %cmp
+}
OpenPOWER on IntegriCloud