diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2022-09-19 15:06:08 -0400 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2022-09-19 18:57:33 -0400 |
commit | 0d8ffcc532ebd1ec5c7f69313be53274d140f72f (patch) | |
tree | f67748102b02fac74e5e344ef6aa1e0367fdec6b /llvm/lib/Analysis/Loads.cpp | |
parent | 3f77df8e29989c15c04c5ab628f12871a5ae2bc0 (diff) | |
download | llvm-0d8ffcc532ebd1ec5c7f69313be53274d140f72f.zip llvm-0d8ffcc532ebd1ec5c7f69313be53274d140f72f.tar.gz llvm-0d8ffcc532ebd1ec5c7f69313be53274d140f72f.tar.bz2 |
Analysis: Add AssumptionCache argument to isDereferenceableAndAlignedPointer
This does not try to pass it through from the end users.
Diffstat (limited to 'llvm/lib/Analysis/Loads.cpp')
-rw-r--r-- | llvm/lib/Analysis/Loads.cpp | 68 |
1 files changed, 34 insertions, 34 deletions
diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp index 938d950..5a693c2 100644 --- a/llvm/lib/Analysis/Loads.cpp +++ b/llvm/lib/Analysis/Loads.cpp @@ -38,7 +38,7 @@ static bool isAligned(const Value *Base, const APInt &Offset, Align Alignment, /// a simple load or store. static bool isDereferenceableAndAlignedPointer( const Value *V, Align Alignment, const APInt &Size, const DataLayout &DL, - const Instruction *CtxI, const DominatorTree *DT, + const Instruction *CtxI, AssumptionCache *AC, const DominatorTree *DT, const TargetLibraryInfo *TLI, SmallPtrSetImpl<const Value *> &Visited, unsigned MaxDepth) { assert(V->getType()->isPointerTy() && "Base must be pointer"); @@ -57,19 +57,19 @@ static bool isDereferenceableAndAlignedPointer( // Recurse into both hands of select. if (const SelectInst *Sel = dyn_cast<SelectInst>(V)) { return isDereferenceableAndAlignedPointer(Sel->getTrueValue(), Alignment, - Size, DL, CtxI, DT, TLI, Visited, - MaxDepth) && + Size, DL, CtxI, AC, DT, TLI, + Visited, MaxDepth) && isDereferenceableAndAlignedPointer(Sel->getFalseValue(), Alignment, - Size, DL, CtxI, DT, TLI, Visited, - MaxDepth); + Size, DL, CtxI, AC, DT, TLI, + Visited, MaxDepth); } // bitcast instructions are no-ops as far as dereferenceability is concerned. if (const BitCastOperator *BC = dyn_cast<BitCastOperator>(V)) { if (BC->getSrcTy()->isPointerTy()) - return isDereferenceableAndAlignedPointer( - BC->getOperand(0), Alignment, Size, DL, CtxI, DT, TLI, - Visited, MaxDepth); + return isDereferenceableAndAlignedPointer(BC->getOperand(0), Alignment, + Size, DL, CtxI, AC, DT, TLI, + Visited, MaxDepth); } bool CheckForNonNull, CheckForFreed; @@ -94,7 +94,7 @@ static bool isDereferenceableAndAlignedPointer( RetainedKnowledge AlignRK; RetainedKnowledge DerefRK; if (getKnowledgeForValue( - V, {Attribute::Dereferenceable, Attribute::Alignment}, nullptr, + V, {Attribute::Dereferenceable, Attribute::Alignment}, AC, [&](RetainedKnowledge RK, Instruction *Assume, auto) { if (!isValidAssumeForContext(Assume, CtxI)) return false; @@ -133,24 +133,24 @@ static bool isDereferenceableAndAlignedPointer( // addrspacecast, so we can't do arithmetic directly on the APInt values. return isDereferenceableAndAlignedPointer( Base, Alignment, Offset + Size.sextOrTrunc(Offset.getBitWidth()), DL, - CtxI, DT, TLI, Visited, MaxDepth); + CtxI, AC, DT, TLI, Visited, MaxDepth); } // For gc.relocate, look through relocations if (const GCRelocateInst *RelocateInst = dyn_cast<GCRelocateInst>(V)) return isDereferenceableAndAlignedPointer(RelocateInst->getDerivedPtr(), - Alignment, Size, DL, CtxI, DT, + Alignment, Size, DL, CtxI, AC, DT, TLI, Visited, MaxDepth); if (const AddrSpaceCastOperator *ASC = dyn_cast<AddrSpaceCastOperator>(V)) return isDereferenceableAndAlignedPointer(ASC->getOperand(0), Alignment, - Size, DL, CtxI, DT, TLI, + Size, DL, CtxI, AC, DT, TLI, Visited, MaxDepth); if (const auto *Call = dyn_cast<CallBase>(V)) { if (auto *RP = getArgumentAliasingToReturnedPointer(Call, true)) return isDereferenceableAndAlignedPointer(RP, Alignment, Size, DL, CtxI, - DT, TLI, Visited, MaxDepth); + AC, DT, TLI, Visited, MaxDepth); // If we have a call we can't recurse through, check to see if this is an // allocation function for which we can establish an minimum object size. @@ -173,7 +173,7 @@ static bool isDereferenceableAndAlignedPointer( // As we recursed through GEPs to get here, we've incrementally // checked that each step advanced by a multiple of the alignment. If // our base is properly aligned, then the original offset accessed - // must also be. + // must also be. Type *Ty = V->getType(); assert(Ty->isSized() && "must be sized"); APInt Offset(DL.getTypeStoreSizeInBits(Ty), 0); @@ -186,28 +186,24 @@ static bool isDereferenceableAndAlignedPointer( return false; } -bool llvm::isDereferenceableAndAlignedPointer(const Value *V, Align Alignment, - const APInt &Size, - const DataLayout &DL, - const Instruction *CtxI, - const DominatorTree *DT, - const TargetLibraryInfo *TLI) { +bool llvm::isDereferenceableAndAlignedPointer( + const Value *V, Align Alignment, const APInt &Size, const DataLayout &DL, + const Instruction *CtxI, AssumptionCache *AC, const DominatorTree *DT, + const TargetLibraryInfo *TLI) { // Note: At the moment, Size can be zero. This ends up being interpreted as // a query of whether [Base, V] is dereferenceable and V is aligned (since // that's what the implementation happened to do). It's unclear if this is // the desired semantic, but at least SelectionDAG does exercise this case. SmallPtrSet<const Value *, 32> Visited; - return ::isDereferenceableAndAlignedPointer(V, Alignment, Size, DL, CtxI, DT, - TLI, Visited, 16); + return ::isDereferenceableAndAlignedPointer(V, Alignment, Size, DL, CtxI, AC, + DT, TLI, Visited, 16); } -bool llvm::isDereferenceableAndAlignedPointer(const Value *V, Type *Ty, - Align Alignment, - const DataLayout &DL, - const Instruction *CtxI, - const DominatorTree *DT, - const TargetLibraryInfo *TLI) { +bool llvm::isDereferenceableAndAlignedPointer( + const Value *V, Type *Ty, Align Alignment, const DataLayout &DL, + const Instruction *CtxI, AssumptionCache *AC, const DominatorTree *DT, + const TargetLibraryInfo *TLI) { // For unsized types or scalable vectors we don't know exactly how many bytes // are dereferenced, so bail out. if (!Ty->isSized() || isa<ScalableVectorType>(Ty)) @@ -221,15 +217,17 @@ bool llvm::isDereferenceableAndAlignedPointer(const Value *V, Type *Ty, APInt AccessSize(DL.getPointerTypeSizeInBits(V->getType()), DL.getTypeStoreSize(Ty)); return isDereferenceableAndAlignedPointer(V, Alignment, AccessSize, DL, CtxI, - DT, TLI); + AC, DT, TLI); } bool llvm::isDereferenceablePointer(const Value *V, Type *Ty, const DataLayout &DL, const Instruction *CtxI, + AssumptionCache *AC, const DominatorTree *DT, const TargetLibraryInfo *TLI) { - return isDereferenceableAndAlignedPointer(V, Ty, Align(1), DL, CtxI, DT, TLI); + return isDereferenceableAndAlignedPointer(V, Ty, Align(1), DL, CtxI, AC, DT, + TLI); } /// Test if A and B will obviously have the same value. @@ -265,7 +263,8 @@ static bool AreEquivalentAddressValues(const Value *A, const Value *B) { bool llvm::isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L, ScalarEvolution &SE, - DominatorTree &DT) { + DominatorTree &DT, + AssumptionCache *AC) { auto &DL = LI->getModule()->getDataLayout(); Value *Ptr = LI->getPointerOperand(); @@ -279,7 +278,7 @@ bool llvm::isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L, // access is safe within the loop w/o needing predication. if (L->isLoopInvariant(Ptr)) return isDereferenceableAndAlignedPointer(Ptr, Alignment, EltSize, DL, - HeaderFirstNonPHI, &DT); + HeaderFirstNonPHI, AC, &DT); // Otherwise, check to see if we have a repeating access pattern where we can // prove that all accesses are well aligned and dereferenceable. @@ -311,7 +310,7 @@ bool llvm::isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L, if (EltSize.urem(Alignment.value()) != 0) return false; return isDereferenceableAndAlignedPointer(Base, Alignment, AccessSize, DL, - HeaderFirstNonPHI, &DT); + HeaderFirstNonPHI, AC, &DT); } /// Check if executing a load of this pointer value cannot trap. @@ -332,7 +331,8 @@ bool llvm::isSafeToLoadUnconditionally(Value *V, Align Alignment, APInt &Size, const TargetLibraryInfo *TLI) { // If DT is not specified we can't make context-sensitive query const Instruction* CtxI = DT ? ScanFrom : nullptr; - if (isDereferenceableAndAlignedPointer(V, Alignment, Size, DL, CtxI, DT, TLI)) + if (isDereferenceableAndAlignedPointer(V, Alignment, Size, DL, CtxI, nullptr, + DT, TLI)) return true; if (!ScanFrom) |