diff options
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 251 |
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); |