aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2020-05-22 19:16:15 +0100
committerFlorian Hahn <flo@fhahn.com>2020-05-23 20:07:52 +0100
commit8d041811983b0b8b9df5fa5f76d8b9d5178d03ea (patch)
tree8d37ce9b622a380bca9fedd65e8a5229a547f0d5 /llvm/lib/Analysis/ValueTracking.cpp
parent2833c46f75a9cb97d717101a70db76d20cc4fcbd (diff)
downloadllvm-8d041811983b0b8b9df5fa5f76d8b9d5178d03ea.zip
llvm-8d041811983b0b8b9df5fa5f76d8b9d5178d03ea.tar.gz
llvm-8d041811983b0b8b9df5fa5f76d8b9d5178d03ea.tar.bz2
[ValueTracking] Use assumptions in computeConstantRange.
This patch updates computeConstantRange to optionally take an assumption cache as argument and use the available assumptions to limit the range of the result. Currently this is limited to assumptions that are comparisons. Reviewers: reames, nikic, spatel, jdoerfert, lebedev.ri Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D76193
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp33
1 files changed, 32 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index a5fb6fb..1b73a20 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6367,9 +6367,15 @@ static void setLimitsForSelectPattern(const SelectInst &SI, APInt &Lower,
}
}
-ConstantRange llvm::computeConstantRange(const Value *V, bool UseInstrInfo) {
+ConstantRange llvm::computeConstantRange(const Value *V, bool UseInstrInfo,
+ AssumptionCache *AC,
+ const Instruction *CtxI,
+ unsigned Depth) {
assert(V->getType()->isIntOrIntVectorTy() && "Expected integer instruction");
+ if (Depth == MaxDepth)
+ return ConstantRange::getFull(V->getType()->getScalarSizeInBits());
+
const APInt *C;
if (match(V, m_APInt(C)))
return ConstantRange(*C);
@@ -6391,6 +6397,31 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool UseInstrInfo) {
if (auto *Range = IIQ.getMetadata(I, LLVMContext::MD_range))
CR = CR.intersectWith(getConstantRangeFromMetadata(*Range));
+ if (CtxI && AC) {
+ // Try to restrict the range based on information from assumptions.
+ for (auto &AssumeVH : AC->assumptionsFor(V)) {
+ if (!AssumeVH)
+ continue;
+ CallInst *I = cast<CallInst>(AssumeVH);
+ assert(I->getParent()->getParent() == CtxI->getParent()->getParent() &&
+ "Got assumption for the wrong function!");
+ assert(I->getCalledFunction()->getIntrinsicID() == Intrinsic::assume &&
+ "must be an assume intrinsic");
+
+ if (!isValidAssumeForContext(I, CtxI, nullptr))
+ continue;
+ Value *Arg = I->getArgOperand(0);
+ ICmpInst *Cmp = dyn_cast<ICmpInst>(Arg);
+ // Currently we just use information from comparisons.
+ if (!Cmp || Cmp->getOperand(0) != V)
+ continue;
+ ConstantRange RHS = computeConstantRange(Cmp->getOperand(1), UseInstrInfo,
+ AC, I, Depth + 1);
+ CR = CR.intersectWith(
+ ConstantRange::makeSatisfyingICmpRegion(Cmp->getPredicate(), RHS));
+ }
+ }
+
return CR;
}