[llvm] [Loads] Migrate isDereferenceable APIs to SimplifyQuery (NFC) (PR #202553)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 9 02:09:24 PDT 2026


https://github.com/nikic created https://github.com/llvm/llvm-project/pull/202553

These take the usual set of analysis parameters, so we can encapsulate them using SimplifyQuery.

>From b5b418cfd18acbb5a5bc5c3c3d7a9fecb2c1a41a Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Tue, 9 Jun 2026 10:34:36 +0200
Subject: [PATCH] [Loads] Migrate isDereferenceable APIs to SimplifyQuery (NFC)

These take the usual set of analysis parameters, so we can
encapsulate them using SimplifyQuery.
---
 llvm/include/llvm/Analysis/Loads.h            |  22 ++-
 llvm/lib/Analysis/Loads.cpp                   | 134 ++++++++----------
 llvm/lib/Analysis/MemDerefPrinter.cpp         |   4 +-
 llvm/lib/Analysis/ValueTracking.cpp           |   6 +-
 llvm/lib/CodeGen/MachineOperand.cpp           |   4 +-
 llvm/lib/CodeGen/TargetLoweringBase.cpp       |   6 +-
 llvm/lib/Transforms/IPO/ArgumentPromotion.cpp |   8 +-
 .../InstCombine/InstCombineCalls.cpp          |   2 +-
 llvm/lib/Transforms/Scalar/LICM.cpp           |   3 +-
 .../lib/Transforms/Scalar/MemCpyOptimizer.cpp |   2 +-
 llvm/lib/Transforms/Utils/LoopPeel.cpp        |   3 +-
 11 files changed, 86 insertions(+), 108 deletions(-)

diff --git a/llvm/include/llvm/Analysis/Loads.h b/llvm/include/llvm/Analysis/Loads.h
index 275dc2c5db847..00510c11632b9 100644
--- a/llvm/include/llvm/Analysis/Loads.h
+++ b/llvm/include/llvm/Analysis/Loads.h
@@ -14,6 +14,7 @@
 #define LLVM_ANALYSIS_LOADS_H
 
 #include "llvm/ADT/APInt.h"
+#include "llvm/Analysis/SimplifyQuery.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/GEPNoWrapFlags.h"
 #include "llvm/Support/CommandLine.h"
@@ -39,29 +40,24 @@ class TargetLibraryInfo;
 /// instruction is specified perform context-sensitive analysis and return true
 /// if the pointer is dereferenceable at the specified instruction.
 LLVM_ABI bool isDereferenceablePointer(const Value *V, Type *Ty,
-                                       const DataLayout &DL,
-                                       const Instruction *CtxI = nullptr,
-                                       AssumptionCache *AC = nullptr,
-                                       const DominatorTree *DT = nullptr,
-                                       const TargetLibraryInfo *TLI = nullptr);
+                                       const SimplifyQuery &Q);
 
 /// Returns true if V is always a dereferenceable pointer with alignment
 /// greater or equal than requested. If the context instruction is specified
 /// performs context-sensitive analysis and returns true if the pointer is
 /// dereferenceable at the specified instruction.
-LLVM_ABI bool isDereferenceableAndAlignedPointer(
-    const Value *V, Type *Ty, Align Alignment, const DataLayout &DL,
-    const Instruction *CtxI = nullptr, AssumptionCache *AC = nullptr,
-    const DominatorTree *DT = nullptr, const TargetLibraryInfo *TLI = nullptr);
+LLVM_ABI bool isDereferenceableAndAlignedPointer(const Value *V, Type *Ty,
+                                                 Align Alignment,
+                                                 const SimplifyQuery &Q);
 
 /// Returns true if V is always dereferenceable for Size byte with alignment
 /// greater or equal than requested. If the context instruction is specified
 /// performs context-sensitive analysis and returns true if the pointer is
 /// dereferenceable at the specified instruction.
-LLVM_ABI bool isDereferenceableAndAlignedPointer(
-    const Value *V, Align Alignment, const APInt &Size, const DataLayout &DL,
-    const Instruction *CtxI = nullptr, AssumptionCache *AC = nullptr,
-    const DominatorTree *DT = nullptr, const TargetLibraryInfo *TLI = nullptr);
+LLVM_ABI bool isDereferenceableAndAlignedPointer(const Value *V,
+                                                 Align Alignment,
+                                                 const APInt &Size,
+                                                 const SimplifyQuery &Q);
 
 /// Return true if we know that executing a load from this value cannot trap.
 ///
diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp
index ab27da6317bd7..647078849048e 100644
--- a/llvm/lib/Analysis/Loads.cpp
+++ b/llvm/lib/Analysis/Loads.cpp
@@ -33,29 +33,27 @@ static bool isAligned(const Value *Base, Align Alignment,
 }
 
 static bool isDereferenceableAndAlignedPointerViaAssumption(
-    const Value *Ptr, Align Alignment,
-    function_ref<bool(const RetainedKnowledge &RK)> CheckSize,
-    const DataLayout &DL, const Instruction *CtxI, AssumptionCache *AC,
-    const DominatorTree *DT) {
-  if (!CtxI)
+    const Value *Ptr, Align Alignment, const SimplifyQuery &SQ,
+    function_ref<bool(const RetainedKnowledge &RK)> CheckSize) {
+  if (!SQ.CxtI)
     return false;
   /// Look through assumes to see if both dereferencability and alignment can
   /// be proven by an assume if needed.
   RetainedKnowledge AlignRK;
   RetainedKnowledge DerefRK;
   bool PtrCanBeFreed = Ptr->canBeFreed();
-  bool IsAligned = Ptr->getPointerAlignment(DL) >= Alignment;
+  bool IsAligned = Ptr->getPointerAlignment(SQ.DL) >= Alignment;
   return getKnowledgeForValue(
-      Ptr, {Attribute::Dereferenceable, Attribute::Alignment}, *AC,
+      Ptr, {Attribute::Dereferenceable, Attribute::Alignment}, *SQ.AC,
       [&](RetainedKnowledge RK, Instruction *Assume, auto) {
-        if (!isValidAssumeForContext(Assume, CtxI, DT))
+        if (!isValidAssumeForContext(Assume, SQ.CxtI, SQ.DT))
           return false;
         if (RK.AttrKind == Attribute::Alignment)
           AlignRK = std::max(AlignRK, RK);
 
         // Dereferenceable information from assumptions is only valid if the
         // value cannot be freed between the assumption and use.
-        if ((!PtrCanBeFreed || willNotFreeBetween(Assume, CtxI)) &&
+        if ((!PtrCanBeFreed || willNotFreeBetween(Assume, SQ.CxtI)) &&
             RK.AttrKind == Attribute::Dereferenceable)
           DerefRK = std::max(DerefRK, RK);
         IsAligned |= AlignRK && AlignRK.ArgValue >= Alignment.value();
@@ -69,10 +67,8 @@ static bool isDereferenceableAndAlignedPointerViaAssumption(
 /// Test if V is always a pointer to allocated and suitably aligned memory for
 /// a simple load or store.
 static bool isDereferenceableAndAlignedPointer(
-    const Value *V, Align Alignment, const APInt &Size, const DataLayout &DL,
-    const Instruction *CtxI, AssumptionCache *AC, const DominatorTree *DT,
-    const TargetLibraryInfo *TLI, SmallPtrSetImpl<const Value *> &Visited,
-    unsigned MaxDepth) {
+    const Value *V, Align Alignment, const APInt &Size, const SimplifyQuery &SQ,
+    SmallPtrSetImpl<const Value *> &Visited, unsigned MaxDepth) {
   assert(V->getType()->isPointerTy() && "Base must be pointer");
 
   // Recursion limit.
@@ -90,8 +86,8 @@ static bool isDereferenceableAndAlignedPointer(
   if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
     const Value *Base = GEP->getPointerOperand();
 
-    APInt Offset(DL.getIndexTypeSizeInBits(GEP->getType()), 0);
-    if (!GEP->accumulateConstantOffset(DL, Offset) || Offset.isNegative() ||
+    APInt Offset(SQ.DL.getIndexTypeSizeInBits(GEP->getType()), 0);
+    if (!GEP->accumulateConstantOffset(SQ.DL, Offset) || Offset.isNegative() ||
         !Offset.urem(APInt(Offset.getBitWidth(), Alignment.value()))
              .isMinValue())
       return false;
@@ -105,35 +101,31 @@ static bool isDereferenceableAndAlignedPointer(
     // Offset and Size may have different bit widths if we have visited an
     // addrspacecast, so we can't do arithmetic directly on the APInt values.
     return isDereferenceableAndAlignedPointer(
-        Base, Alignment, Offset + Size.sextOrTrunc(Offset.getBitWidth()), DL,
-        CtxI, AC, DT, TLI, Visited, MaxDepth);
+        Base, Alignment, Offset + Size.sextOrTrunc(Offset.getBitWidth()), SQ,
+        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, AC, DT, TLI,
-          Visited, MaxDepth);
+      return isDereferenceableAndAlignedPointer(BC->getOperand(0), Alignment,
+                                                Size, SQ, Visited, MaxDepth);
   }
 
   // Recurse into both hands of select.
   if (const SelectInst *Sel = dyn_cast<SelectInst>(V)) {
     return isDereferenceableAndAlignedPointer(Sel->getTrueValue(), Alignment,
-                                              Size, DL, CtxI, AC, DT, TLI,
-                                              Visited, MaxDepth) &&
+                                              Size, SQ, Visited, MaxDepth) &&
            isDereferenceableAndAlignedPointer(Sel->getFalseValue(), Alignment,
-                                              Size, DL, CtxI, AC, DT, TLI,
-                                              Visited, MaxDepth);
+                                              Size, SQ, Visited, MaxDepth);
   }
 
   auto IsKnownDeref = [&]() {
     bool CheckForNonNull, CheckForFreed;
-    if (!Size.ule(V->getPointerDereferenceableBytes(DL, CheckForNonNull,
+    if (!Size.ule(V->getPointerDereferenceableBytes(SQ.DL, CheckForNonNull,
                                                     CheckForFreed)))
       return false;
-    if (CheckForNonNull &&
-        !isKnownNonZero(V, SimplifyQuery(DL, DT, AC, CtxI)))
+    if (CheckForNonNull && !isKnownNonZero(V, SQ))
       return false;
 
     auto *I = dyn_cast<Instruction>(V);
@@ -154,7 +146,7 @@ static bool isDereferenceableAndAlignedPointer(
         DefI = &cast<Argument>(V)->getParent()->getEntryBlock().front();
       }
 
-      if (!CtxI || !willNotFreeBetween(DefI, CtxI))
+      if (!SQ.CxtI || !willNotFreeBetween(DefI, SQ.CxtI))
         return false;
     }
 
@@ -167,14 +159,14 @@ static bool isDereferenceableAndAlignedPointer(
     // We don't bother handling allocas here, as they aren't speculatable
     // anyway.
     if (I && !isa<AllocaInst>(I))
-      return CtxI && isValidAssumeForContext(I, CtxI, DT);
+      return SQ.CxtI && isValidAssumeForContext(I, SQ.CxtI, SQ.DT);
     return true;
   };
   if (IsKnownDeref()) {
     // 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.
-    return isAligned(V, Alignment, DL);
+    return isAligned(V, Alignment, SQ.DL);
   }
 
   /// TODO refactor this function to be able to search independently for
@@ -184,8 +176,8 @@ static bool isDereferenceableAndAlignedPointer(
   if (const auto *Call = dyn_cast<CallBase>(V)) {
     if (auto *RP = getArgumentAliasingToReturnedPointer(
             Call, /*MustPreserveOffset=*/true))
-      return isDereferenceableAndAlignedPointer(RP, Alignment, Size, DL, CtxI,
-                                                AC, DT, TLI, Visited, MaxDepth);
+      return isDereferenceableAndAlignedPointer(RP, Alignment, Size, SQ,
+                                                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.
@@ -201,57 +193,50 @@ static bool isDereferenceableAndAlignedPointer(
     Opts.RoundToAlign = false;
     Opts.NullIsUnknownSize = true;
     uint64_t ObjSize;
-    if (getObjectSize(V, ObjSize, DL, TLI, Opts)) {
+    if (getObjectSize(V, ObjSize, SQ.DL, SQ.TLI, Opts)) {
       APInt KnownDerefBytes(Size.getBitWidth(), ObjSize);
       if (KnownDerefBytes.getBoolValue() && KnownDerefBytes.uge(Size) &&
-          isKnownNonZero(V, SimplifyQuery(DL, DT, AC, CtxI)) &&
-          !V->canBeFreed()) {
+          isKnownNonZero(V, SQ) && !V->canBeFreed()) {
         // 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.
-        return isAligned(V, Alignment, DL);
+        return isAligned(V, Alignment, SQ.DL);
       }
     }
   }
 
   // For gc.relocate, look through relocations
   if (const GCRelocateInst *RelocateInst = dyn_cast<GCRelocateInst>(V))
-    return isDereferenceableAndAlignedPointer(RelocateInst->getDerivedPtr(),
-                                              Alignment, Size, DL, CtxI, AC, DT,
-                                              TLI, Visited, MaxDepth);
+    return isDereferenceableAndAlignedPointer(
+        RelocateInst->getDerivedPtr(), Alignment, Size, SQ, Visited, MaxDepth);
 
   if (const AddrSpaceCastOperator *ASC = dyn_cast<AddrSpaceCastOperator>(V))
     return isDereferenceableAndAlignedPointer(ASC->getOperand(0), Alignment,
-                                              Size, DL, CtxI, AC, DT, TLI,
-                                              Visited, MaxDepth);
-
-  return AC && isDereferenceableAndAlignedPointerViaAssumption(
-                   V, Alignment,
-                   [Size](const RetainedKnowledge &RK) {
-                     return RK.ArgValue >= Size.getZExtValue();
-                   },
-                   DL, CtxI, AC, DT);
+                                              Size, SQ, Visited, MaxDepth);
+
+  return SQ.AC && isDereferenceableAndAlignedPointerViaAssumption(
+                      V, Alignment, SQ, [Size](const RetainedKnowledge &RK) {
+                        return RK.ArgValue >= Size.getZExtValue();
+                      });
 }
 
-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) {
+bool llvm::isDereferenceableAndAlignedPointer(const Value *V, Align Alignment,
+                                              const APInt &Size,
+                                              const SimplifyQuery &SQ) {
   // 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, AC,
-                                              DT, TLI, Visited, 16);
+  return ::isDereferenceableAndAlignedPointer(V, Alignment, Size, SQ, Visited,
+                                              /*MaxDepth=*/16);
 }
 
-bool llvm::isDereferenceableAndAlignedPointer(
-    const Value *V, Type *Ty, Align Alignment, const DataLayout &DL,
-    const Instruction *CtxI, AssumptionCache *AC, const DominatorTree *DT,
-    const TargetLibraryInfo *TLI) {
+bool llvm::isDereferenceableAndAlignedPointer(const Value *V, Type *Ty,
+                                              Align Alignment,
+                                              const SimplifyQuery &SQ) {
   // For unsized types or scalable vectors we don't know exactly how many bytes
   // are dereferenced, so bail out.
   if (!Ty->isSized() || Ty->isScalableTy())
@@ -262,20 +247,14 @@ bool llvm::isDereferenceableAndAlignedPointer(
   // determine the exact offset to the attributed variable, we can use that
   // information here.
 
-  APInt AccessSize(DL.getPointerTypeSizeInBits(V->getType()),
-                   DL.getTypeStoreSize(Ty));
-  return isDereferenceableAndAlignedPointer(V, Alignment, AccessSize, DL, CtxI,
-                                            AC, DT, TLI);
+  APInt AccessSize(SQ.DL.getPointerTypeSizeInBits(V->getType()),
+                   SQ.DL.getTypeStoreSize(Ty));
+  return isDereferenceableAndAlignedPointer(V, Alignment, AccessSize, SQ);
 }
 
 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, AC, DT,
-                                            TLI);
+                                    const SimplifyQuery &SQ) {
+  return isDereferenceableAndAlignedPointer(V, Ty, Align(1), SQ);
 }
 
 /// Test if A and B will obviously have the same value.
@@ -321,8 +300,8 @@ bool llvm::isDereferenceableAndAlignedInLoop(
   // access is safe within the loop w/o needing predication.
   if (L->isLoopInvariant(Ptr))
     return isDereferenceableAndAlignedPointer(
-        Ptr, LI->getAlign(), EltSize, DL, &*L->getHeader()->getFirstNonPHIIt(),
-        AC, &DT);
+        Ptr, LI->getAlign(), EltSize,
+        SimplifyQuery(DL, &DT, AC, &*L->getHeader()->getFirstNonPHIIt()));
 
   const SCEV *EltSizeSCEV = SE.getConstant(EltSize);
   return isDereferenceableAndAlignedInLoop(PtrSCEV, LI->getAlign(), EltSizeSCEV,
@@ -428,17 +407,16 @@ bool llvm::isDereferenceableAndAlignedInLoop(
     if (isa<UncondBrInst, CondBrInst>(LoopPred->getTerminator()))
       CtxI = LoopPred->getTerminator();
   }
+  SimplifyQuery SQ(DL, &DT, AC, CtxI);
   return isDereferenceableAndAlignedPointerViaAssumption(
-             Base, Alignment,
+             Base, Alignment, SQ,
              [&SE, AccessSizeSCEV, &LoopGuards](const RetainedKnowledge &RK) {
                return SE.isKnownPredicate(
                    CmpInst::ICMP_ULE,
                    SE.applyLoopGuards(AccessSizeSCEV, *LoopGuards),
                    SE.applyLoopGuards(SE.getSCEV(RK.IRArgValue), *LoopGuards));
-             },
-             DL, CtxI, AC, &DT) ||
-         isDereferenceableAndAlignedPointer(Base, Alignment, AccessSize, DL,
-                                            CtxI, AC, &DT);
+             }) ||
+         isDereferenceableAndAlignedPointer(Base, Alignment, AccessSize, SQ);
 }
 
 static bool suppressSpeculativeLoadForSanitizers(const Instruction &CtxI) {
@@ -460,8 +438,8 @@ bool llvm::isSafeToLoadUnconditionally(Value *V, Align Alignment, const APInt &S
                                        AssumptionCache *AC,
                                        const DominatorTree *DT,
                                        const TargetLibraryInfo *TLI) {
-  if (isDereferenceableAndAlignedPointer(V, Alignment, Size, DL, ScanFrom, AC,
-                                         DT, TLI)) {
+  if (isDereferenceableAndAlignedPointer(
+          V, Alignment, Size, SimplifyQuery(DL, TLI, DT, AC, ScanFrom, AC))) {
     // With sanitizers `Dereferenceable` is not always enough for unconditional
     // load.
     if (!ScanFrom || !suppressSpeculativeLoadForSanitizers(*ScanFrom))
diff --git a/llvm/lib/Analysis/MemDerefPrinter.cpp b/llvm/lib/Analysis/MemDerefPrinter.cpp
index e1245e2ed44c0..2b157cf06dc05 100644
--- a/llvm/lib/Analysis/MemDerefPrinter.cpp
+++ b/llvm/lib/Analysis/MemDerefPrinter.cpp
@@ -27,10 +27,10 @@ PreservedAnalyses MemDerefPrinterPass::run(Function &F,
   for (auto &I : instructions(F)) {
     if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
       Value *PO = LI->getPointerOperand();
-      if (isDereferenceablePointer(PO, LI->getType(), DL, LI))
+      if (isDereferenceablePointer(PO, LI->getType(), SimplifyQuery(DL, LI)))
         Deref.push_back(PO);
       if (isDereferenceableAndAlignedPointer(PO, LI->getType(), LI->getAlign(),
-                                             DL, LI))
+                                             SimplifyQuery(DL, LI)))
         DerefAndAligned.insert(PO);
     }
   }
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 04def11136d35..96a7a10675d89 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -7303,9 +7303,9 @@ bool llvm::isSafeToSpeculativelyExecuteWithOpcode(
     if (mustSuppressSpeculation(*LI))
       return false;
     const DataLayout &DL = LI->getDataLayout();
-    return isDereferenceableAndAlignedPointer(LI->getPointerOperand(),
-                                              LI->getType(), LI->getAlign(), DL,
-                                              CtxI, AC, DT, TLI);
+    return isDereferenceableAndAlignedPointer(
+        LI->getPointerOperand(), LI->getType(), LI->getAlign(),
+        SimplifyQuery(DL, TLI, DT, AC, CtxI));
   }
   case Instruction::Call: {
     auto *CI = dyn_cast<const CallInst>(Inst);
diff --git a/llvm/lib/CodeGen/MachineOperand.cpp b/llvm/lib/CodeGen/MachineOperand.cpp
index 4185035b79337..96aac20610ff7 100644
--- a/llvm/lib/CodeGen/MachineOperand.cpp
+++ b/llvm/lib/CodeGen/MachineOperand.cpp
@@ -1135,8 +1135,8 @@ bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C,
     return false;
 
   return isDereferenceableAndAlignedPointer(
-      BasePtr, Align(1), APInt(DL.getPointerSizeInBits(), Offset + Size), DL,
-      dyn_cast<Instruction>(BasePtr));
+      BasePtr, Align(1), APInt(DL.getPointerSizeInBits(), Offset + Size),
+      SimplifyQuery(DL, dyn_cast<Instruction>(BasePtr)));
 }
 
 /// getConstantPool - Return a MachinePointerInfo record that refers to the
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index 1f4842fb3df15..83ad156e770f4 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -2798,9 +2798,9 @@ MachineMemOperand::Flags TargetLoweringBase::getLoadMemOperandFlags(
 
   // Dereferenceability analysis is expensive, skip at O0.
   if (OptLevel != CodeGenOptLevel::None &&
-      isDereferenceableAndAlignedPointer(LI.getPointerOperand(), LI.getType(),
-                                         LI.getAlign(), DL, &LI, AC,
-                                         /*DT=*/nullptr, LibInfo)) {
+      isDereferenceableAndAlignedPointer(
+          LI.getPointerOperand(), LI.getType(), LI.getAlign(),
+          SimplifyQuery(DL, LibInfo, /*DT=*/nullptr, AC, &LI))) {
     Flags |= MachineMemOperand::MODereferenceable;
   } else if (LI.hasMetadata(LLVMContext::MD_dereferenceable)) {
     Flags |= MachineMemOperand::MODereferenceable;
diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
index 6ef7323364907..3be54a710b0ec 100644
--- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -456,8 +456,9 @@ static bool allCallersPassValidPointerForArgument(
   APInt Bytes(64, NeededDerefBytes);
 
   // Check if the argument itself is marked dereferenceable and aligned.
-  if (isDereferenceableAndAlignedPointer(Arg, NeededAlign, Bytes, DL,
-                                         &Callee->getEntryBlock().front()))
+  if (isDereferenceableAndAlignedPointer(
+          Arg, NeededAlign, Bytes,
+          SimplifyQuery(DL, &Callee->getEntryBlock().front())))
     return true;
 
   // Look at all call sites of the function.  At this point we know we only have
@@ -492,7 +493,8 @@ static bool allCallersPassValidPointerForArgument(
       return true;
 
     return isDereferenceableAndAlignedPointer(CB.getArgOperand(Arg->getArgNo()),
-                                              NeededAlign, Bytes, DL, &CB);
+                                              NeededAlign, Bytes,
+                                              SimplifyQuery(DL, &CB));
   });
 }
 
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 35c60e6eb3753..a1acdff8ba393 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -307,7 +307,7 @@ Value *InstCombinerImpl::simplifyMaskedLoad(IntrinsicInst &II) {
   // If we can unconditionally load from this address, replace with a
   // load/select idiom. TODO: use DT for context sensitive query
   if (isDereferenceablePointer(LoadPtr, II.getType(),
-                               II.getDataLayout(), &II, &AC)) {
+                               SQ.getWithInstruction(&II))) {
     LoadInst *LI = Builder.CreateAlignedLoad(II.getType(), LoadPtr, Alignment,
                                              "unmaskedload");
     LI->copyMetadata(II);
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index e9e3554959a67..c5b8eb4b07f0b 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -2100,7 +2100,8 @@ bool llvm::promoteLoopAccessesToScalars(
         if (!DereferenceableInPH) {
           DereferenceableInPH = isDereferenceableAndAlignedPointer(
               Store->getPointerOperand(), Store->getValueOperand()->getType(),
-              Store->getAlign(), MDL, Preheader->getTerminator(), AC, DT, TLI);
+              Store->getAlign(),
+              SimplifyQuery(MDL, TLI, DT, AC, Preheader->getTerminator()));
         }
       } else
         continue; // Not a load or store.
diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index 4d51dbf3aa4de..68671ef4b81aa 100644
--- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -923,7 +923,7 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpyLoad,
   if (!isWritableObject(getUnderlyingObject(cpyDest),
                         ExplicitlyDereferenceableOnly) ||
       !isDereferenceableAndAlignedPointer(cpyDest, Align(1), APInt(64, cpySize),
-                                          DL, C, AC, DT)) {
+                                          SimplifyQuery(DL, DT, AC, C))) {
     LLVM_DEBUG(dbgs() << "Call Slot: Dest pointer not dereferenceable\n");
     return false;
   }
diff --git a/llvm/lib/Transforms/Utils/LoopPeel.cpp b/llvm/lib/Transforms/Utils/LoopPeel.cpp
index 3ae2a78190082..9488b91caa830 100644
--- a/llvm/lib/Transforms/Utils/LoopPeel.cpp
+++ b/llvm/lib/Transforms/Utils/LoopPeel.cpp
@@ -464,7 +464,8 @@ static unsigned peelToTurnInvariantLoadsDereferenceable(Loop &L,
       if (auto *LI = dyn_cast<LoadInst>(&I)) {
         Value *Ptr = LI->getPointerOperand();
         if (DT.dominates(BB, Latch) && L.isLoopInvariant(Ptr) &&
-            !isDereferenceablePointer(Ptr, LI->getType(), DL, LI, AC, &DT))
+            !isDereferenceablePointer(Ptr, LI->getType(),
+                                      SimplifyQuery(DL, &DT, AC, LI)))
           LoadUsers.insert_range(I.users());
       }
     }



More information about the llvm-commits mailing list