aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/Loads.cpp
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2022-09-19 15:06:08 -0400
committerMatt Arsenault <Matthew.Arsenault@amd.com>2022-09-19 18:57:33 -0400
commit0d8ffcc532ebd1ec5c7f69313be53274d140f72f (patch)
treef67748102b02fac74e5e344ef6aa1e0367fdec6b /llvm/lib/Analysis/Loads.cpp
parent3f77df8e29989c15c04c5ab628f12871a5ae2bc0 (diff)
downloadllvm-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.cpp68
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)