diff options
author | Florian Hahn <flo@fhahn.com> | 2020-05-22 19:16:15 +0100 |
---|---|---|
committer | Florian Hahn <flo@fhahn.com> | 2020-05-23 20:07:52 +0100 |
commit | 8d041811983b0b8b9df5fa5f76d8b9d5178d03ea (patch) | |
tree | 8d37ce9b622a380bca9fedd65e8a5229a547f0d5 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 2833c46f75a9cb97d717101a70db76d20cc4fcbd (diff) | |
download | llvm-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.cpp | 33 |
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; } |