aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp38
1 files changed, 34 insertions, 4 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 58bc68b..797665c 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1500,14 +1500,20 @@ static void computeKnownBitsFromOperator(const Operator *I,
break;
}
case Instruction::Call:
- case Instruction::Invoke:
+ case Instruction::Invoke: {
// If range metadata is attached to this call, set known bits from that,
// and then intersect with known bits based on other properties of the
// function.
if (MDNode *MD =
Q.IIQ.getMetadata(cast<Instruction>(I), LLVMContext::MD_range))
computeKnownBitsFromRangeMetadata(*MD, Known);
- if (const Value *RV = cast<CallBase>(I)->getReturnedArgOperand()) {
+
+ const auto *CB = cast<CallBase>(I);
+
+ if (std::optional<ConstantRange> Range = CB->getRange())
+ Known = Known.unionWith(Range->toKnownBits());
+
+ if (const Value *RV = CB->getReturnedArgOperand()) {
if (RV->getType() == I->getType()) {
computeKnownBits(RV, Known2, Depth + 1, Q);
Known = Known.unionWith(Known2);
@@ -1679,6 +1685,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
}
}
break;
+ }
case Instruction::ShuffleVector: {
auto *Shuf = dyn_cast<ShuffleVectorInst>(I);
// FIXME: Do we need to handle ConstantExpr involving shufflevectors?
@@ -1933,6 +1940,10 @@ void computeKnownBits(const Value *V, const APInt &DemandedElts,
// assumptions. Confirm that we've handled them all.
assert(!isa<ConstantData>(V) && "Unhandled constant data!");
+ if (const auto *A = dyn_cast<Argument>(V))
+ if (std::optional<ConstantRange> Range = A->getRange())
+ Known = Range->toKnownBits();
+
// All recursive calls that increase depth must come after this.
if (Depth == MaxAnalysisRecursionDepth)
return;
@@ -2783,6 +2794,11 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
} else {
if (MDNode *Ranges = Q.IIQ.getMetadata(Call, LLVMContext::MD_range))
return rangeMetadataExcludesValue(Ranges, APInt::getZero(BitWidth));
+ if (std::optional<ConstantRange> Range = Call->getRange()) {
+ const APInt ZeroValue(Range->getBitWidth(), 0);
+ if (!Range->contains(ZeroValue))
+ return true;
+ }
if (const Value *RV = Call->getReturnedArgOperand())
if (RV->getType() == I->getType() && isKnownNonZero(RV, Depth, Q))
return true;
@@ -2921,6 +2937,13 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
return false;
}
+ if (const auto *A = dyn_cast<Argument>(V))
+ if (std::optional<ConstantRange> Range = A->getRange()) {
+ const APInt ZeroValue(Range->getBitWidth(), 0);
+ if (!Range->contains(ZeroValue))
+ return true;
+ }
+
if (!isa<Constant>(V) && isKnownNonZeroFromAssume(V, Q))
return true;
@@ -9146,12 +9169,19 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned,
// TODO: Return ConstantRange.
setLimitForFPToI(cast<Instruction>(V), Lower, Upper);
CR = ConstantRange::getNonEmpty(Lower, Upper);
- }
+ } else if (const auto *A = dyn_cast<Argument>(V))
+ if (std::optional<ConstantRange> Range = A->getRange())
+ CR = *Range;
- if (auto *I = dyn_cast<Instruction>(V))
+ if (auto *I = dyn_cast<Instruction>(V)) {
if (auto *Range = IIQ.getMetadata(I, LLVMContext::MD_range))
CR = CR.intersectWith(getConstantRangeFromMetadata(*Range));
+ if (const auto *CB = dyn_cast<CallBase>(V))
+ if (std::optional<ConstantRange> Range = CB->getRange())
+ CR = CR.intersectWith(*Range);
+ }
+
if (CtxI && AC) {
// Try to restrict the range based on information from assumptions.
for (auto &AssumeVH : AC->assumptionsFor(V)) {