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.cpp251
1 files changed, 128 insertions, 123 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 8940c2c..62f7c54 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2449,122 +2449,10 @@ static bool isNonZeroShift(const Operator *I, const APInt &DemandedElts,
return false;
}
-/// Return true if the given value is known to be non-zero when defined. For
-/// vectors, return true if every demanded element is known to be non-zero when
-/// defined. For pointers, if the context instruction and dominator tree are
-/// specified, perform context-sensitive analysis and return true if the
-/// pointer couldn't possibly be null at the specified instruction.
-/// Supports values with integer or pointer type and vectors of integers.
-bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
- const SimplifyQuery &Q) {
-
-#ifndef NDEBUG
- Type *Ty = V->getType();
- assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
-
- if (auto *FVTy = dyn_cast<FixedVectorType>(Ty)) {
- assert(
- FVTy->getNumElements() == DemandedElts.getBitWidth() &&
- "DemandedElt width should equal the fixed vector number of elements");
- } else {
- assert(DemandedElts == APInt(1, 1) &&
- "DemandedElt width should be 1 for scalars");
- }
-#endif
-
- if (auto *C = dyn_cast<Constant>(V)) {
- if (C->isNullValue())
- return false;
- if (isa<ConstantInt>(C))
- // Must be non-zero due to null test above.
- return true;
-
- // For constant vectors, check that all elements are undefined or known
- // non-zero to determine that the whole vector is known non-zero.
- if (auto *VecTy = dyn_cast<FixedVectorType>(C->getType())) {
- for (unsigned i = 0, e = VecTy->getNumElements(); i != e; ++i) {
- if (!DemandedElts[i])
- continue;
- Constant *Elt = C->getAggregateElement(i);
- if (!Elt || Elt->isNullValue())
- return false;
- if (!isa<UndefValue>(Elt) && !isa<ConstantInt>(Elt))
- return false;
- }
- return true;
- }
-
- // A global variable in address space 0 is non null unless extern weak
- // or an absolute symbol reference. Other address spaces may have null as a
- // valid address for a global, so we can't assume anything.
- if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
- if (!GV->isAbsoluteSymbolRef() && !GV->hasExternalWeakLinkage() &&
- GV->getType()->getAddressSpace() == 0)
- return true;
- }
-
- // For constant expressions, fall through to the Operator code below.
- if (!isa<ConstantExpr>(V))
- return false;
- }
-
- if (auto *I = dyn_cast<Instruction>(V)) {
- if (MDNode *Ranges = Q.IIQ.getMetadata(I, LLVMContext::MD_range)) {
- // If the possible ranges don't contain zero, then the value is
- // definitely non-zero.
- if (auto *Ty = dyn_cast<IntegerType>(V->getType())) {
- const APInt ZeroValue(Ty->getBitWidth(), 0);
- if (rangeMetadataExcludesValue(Ranges, ZeroValue))
- return true;
- }
- }
- }
-
- if (!isa<Constant>(V) && isKnownNonZeroFromAssume(V, Q))
- return true;
-
- // Some of the tests below are recursive, so bail out if we hit the limit.
- if (Depth++ >= MaxAnalysisRecursionDepth)
- return false;
-
- // Check for pointer simplifications.
-
- if (PointerType *PtrTy = dyn_cast<PointerType>(V->getType())) {
- // Alloca never returns null, malloc might.
- if (isa<AllocaInst>(V) && PtrTy->getAddressSpace() == 0)
- return true;
-
- // A byval, inalloca may not be null in a non-default addres space. A
- // nonnull argument is assumed never 0.
- if (const Argument *A = dyn_cast<Argument>(V)) {
- if (((A->hasPassPointeeByValueCopyAttr() &&
- !NullPointerIsDefined(A->getParent(), PtrTy->getAddressSpace())) ||
- A->hasNonNullAttr()))
- return true;
- }
-
- // A Load tagged with nonnull metadata is never null.
- if (const LoadInst *LI = dyn_cast<LoadInst>(V))
- if (Q.IIQ.getMetadata(LI, LLVMContext::MD_nonnull))
- return true;
-
- if (const auto *Call = dyn_cast<CallBase>(V)) {
- if (Call->isReturnNonNull())
- return true;
- if (const auto *RP = getArgumentAliasingToReturnedPointer(Call, true))
- return isKnownNonZero(RP, Depth, Q);
- }
- }
-
- if (!isa<Constant>(V) &&
- isKnownNonNullFromDominatingCondition(V, Q.CxtI, Q.DT))
- return true;
-
- const Operator *I = dyn_cast<Operator>(V);
- if (!I)
- return false;
-
- unsigned BitWidth = getBitWidth(V->getType()->getScalarType(), Q.DL);
+static bool isKnownNonZeroFromOperator(const Operator *I,
+ const APInt &DemandedElts,
+ unsigned Depth, const SimplifyQuery &Q) {
+ unsigned BitWidth = getBitWidth(I->getType()->getScalarType(), Q.DL);
switch (I->getOpcode()) {
case Instruction::GetElementPtr:
if (I->getType()->isPointerTy())
@@ -2634,7 +2522,7 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
case Instruction::Shl: {
// shl nsw/nuw can't remove any non-zero bits.
- const OverflowingBinaryOperator *BO = cast<OverflowingBinaryOperator>(V);
+ const OverflowingBinaryOperator *BO = cast<OverflowingBinaryOperator>(I);
if (Q.IIQ.hasNoUnsignedWrap(BO) || Q.IIQ.hasNoSignedWrap(BO))
return isKnownNonZero(I->getOperand(0), Depth, Q);
@@ -2650,7 +2538,7 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
case Instruction::LShr:
case Instruction::AShr: {
// shr exact can only shift out zero bits.
- const PossiblyExactOperator *BO = cast<PossiblyExactOperator>(V);
+ const PossiblyExactOperator *BO = cast<PossiblyExactOperator>(I);
if (BO->isExact())
return isKnownNonZero(I->getOperand(0), Depth, Q);
@@ -2689,7 +2577,7 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
// If Add has nuw wrap flag, then if either X or Y is non-zero the result is
// non-zero.
- auto *BO = cast<OverflowingBinaryOperator>(V);
+ auto *BO = cast<OverflowingBinaryOperator>(I);
if (Q.IIQ.hasNoUnsignedWrap(BO))
return isKnownNonZero(I->getOperand(1), DemandedElts, Depth, Q) ||
isKnownNonZero(I->getOperand(0), DemandedElts, Depth, Q);
@@ -2700,7 +2588,7 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
case Instruction::Mul: {
// If X and Y are non-zero then so is X * Y as long as the multiplication
// does not overflow.
- const OverflowingBinaryOperator *BO = cast<OverflowingBinaryOperator>(V);
+ const OverflowingBinaryOperator *BO = cast<OverflowingBinaryOperator>(I);
if (Q.IIQ.hasNoSignedWrap(BO) || Q.IIQ.hasNoUnsignedWrap(BO))
return isKnownNonZero(I->getOperand(0), DemandedElts, Depth, Q) &&
isKnownNonZero(I->getOperand(1), DemandedElts, Depth, Q);
@@ -2774,7 +2662,7 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
});
}
case Instruction::ExtractElement:
- if (const auto *EEI = dyn_cast<ExtractElementInst>(V)) {
+ if (const auto *EEI = dyn_cast<ExtractElementInst>(I)) {
const Value *Vec = EEI->getVectorOperand();
const Value *Idx = EEI->getIndexOperand();
auto *CIdx = dyn_cast<ConstantInt>(Idx);
@@ -2857,11 +2745,128 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
}
KnownBits Known(BitWidth);
- computeKnownBits(V, DemandedElts, Known, Depth, Q);
+ computeKnownBits(I, DemandedElts, Known, Depth, Q);
return Known.One != 0;
}
-bool isKnownNonZero(const Value* V, unsigned Depth, const SimplifyQuery& Q) {
+/// Return true if the given value is known to be non-zero when defined. For
+/// vectors, return true if every demanded element is known to be non-zero when
+/// defined. For pointers, if the context instruction and dominator tree are
+/// specified, perform context-sensitive analysis and return true if the
+/// pointer couldn't possibly be null at the specified instruction.
+/// Supports values with integer or pointer type and vectors of integers.
+bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
+ const SimplifyQuery &Q) {
+
+#ifndef NDEBUG
+ Type *Ty = V->getType();
+ assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
+
+ if (auto *FVTy = dyn_cast<FixedVectorType>(Ty)) {
+ assert(
+ FVTy->getNumElements() == DemandedElts.getBitWidth() &&
+ "DemandedElt width should equal the fixed vector number of elements");
+ } else {
+ assert(DemandedElts == APInt(1, 1) &&
+ "DemandedElt width should be 1 for scalars");
+ }
+#endif
+
+ if (auto *C = dyn_cast<Constant>(V)) {
+ if (C->isNullValue())
+ return false;
+ if (isa<ConstantInt>(C))
+ // Must be non-zero due to null test above.
+ return true;
+
+ // For constant vectors, check that all elements are undefined or known
+ // non-zero to determine that the whole vector is known non-zero.
+ if (auto *VecTy = dyn_cast<FixedVectorType>(C->getType())) {
+ for (unsigned i = 0, e = VecTy->getNumElements(); i != e; ++i) {
+ if (!DemandedElts[i])
+ continue;
+ Constant *Elt = C->getAggregateElement(i);
+ if (!Elt || Elt->isNullValue())
+ return false;
+ if (!isa<UndefValue>(Elt) && !isa<ConstantInt>(Elt))
+ return false;
+ }
+ return true;
+ }
+
+ // A global variable in address space 0 is non null unless extern weak
+ // or an absolute symbol reference. Other address spaces may have null as a
+ // valid address for a global, so we can't assume anything.
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+ if (!GV->isAbsoluteSymbolRef() && !GV->hasExternalWeakLinkage() &&
+ GV->getType()->getAddressSpace() == 0)
+ return true;
+ }
+
+ // For constant expressions, fall through to the Operator code below.
+ if (!isa<ConstantExpr>(V))
+ return false;
+ }
+
+ if (auto *I = dyn_cast<Instruction>(V)) {
+ if (MDNode *Ranges = Q.IIQ.getMetadata(I, LLVMContext::MD_range)) {
+ // If the possible ranges don't contain zero, then the value is
+ // definitely non-zero.
+ if (auto *Ty = dyn_cast<IntegerType>(V->getType())) {
+ const APInt ZeroValue(Ty->getBitWidth(), 0);
+ if (rangeMetadataExcludesValue(Ranges, ZeroValue))
+ return true;
+ }
+ }
+ }
+
+ if (!isa<Constant>(V) && isKnownNonZeroFromAssume(V, Q))
+ return true;
+
+ // Some of the tests below are recursive, so bail out if we hit the limit.
+ if (Depth++ >= MaxAnalysisRecursionDepth)
+ return false;
+
+ // Check for pointer simplifications.
+
+ if (PointerType *PtrTy = dyn_cast<PointerType>(V->getType())) {
+ // Alloca never returns null, malloc might.
+ if (isa<AllocaInst>(V) && PtrTy->getAddressSpace() == 0)
+ return true;
+
+ // A byval, inalloca may not be null in a non-default addres space. A
+ // nonnull argument is assumed never 0.
+ if (const Argument *A = dyn_cast<Argument>(V)) {
+ if (((A->hasPassPointeeByValueCopyAttr() &&
+ !NullPointerIsDefined(A->getParent(), PtrTy->getAddressSpace())) ||
+ A->hasNonNullAttr()))
+ return true;
+ }
+
+ // A Load tagged with nonnull metadata is never null.
+ if (const LoadInst *LI = dyn_cast<LoadInst>(V))
+ if (Q.IIQ.getMetadata(LI, LLVMContext::MD_nonnull))
+ return true;
+
+ if (const auto *Call = dyn_cast<CallBase>(V)) {
+ if (Call->isReturnNonNull())
+ return true;
+ if (const auto *RP = getArgumentAliasingToReturnedPointer(Call, true))
+ return isKnownNonZero(RP, Depth, Q);
+ }
+ }
+
+ if (!isa<Constant>(V) &&
+ isKnownNonNullFromDominatingCondition(V, Q.CxtI, Q.DT))
+ return true;
+
+ if (const auto *I = dyn_cast<Operator>(V))
+ return isKnownNonZeroFromOperator(I, DemandedElts, Depth, Q);
+
+ return false;
+}
+
+bool isKnownNonZero(const Value *V, unsigned Depth, const SimplifyQuery &Q) {
auto *FVTy = dyn_cast<FixedVectorType>(V->getType());
APInt DemandedElts =
FVTy ? APInt::getAllOnes(FVTy->getNumElements()) : APInt(1, 1);