[llvm] [MemoryDependenceAnalysis] Migrate `isStorePreservingMemoryLocation` to Loads (NFC) (PR #223700)

Antonio Frighetto via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 16 01:07:16 PDT 2026


https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/223700

>From 48c7bf132df56294ef1d96411af1ce089fb283ec Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Tue, 15 Sep 2026 15:23:51 +0200
Subject: [PATCH] [MemoryDependenceAnalysis] Migrate
 `isStorePreservingMemoryLocation` to Loads (NFC)

Minor opportunity to expose the helper and move it out of MDA.
---
 llvm/include/llvm/Analysis/Loads.h            | 11 ++++++
 llvm/lib/Analysis/Loads.cpp                   | 30 ++++++++++++++++
 .../lib/Analysis/MemoryDependenceAnalysis.cpp | 36 ++-----------------
 3 files changed, 43 insertions(+), 34 deletions(-)

diff --git a/llvm/include/llvm/Analysis/Loads.h b/llvm/include/llvm/Analysis/Loads.h
index 22ce31d61ddb8..b6075082d34ef 100644
--- a/llvm/include/llvm/Analysis/Loads.h
+++ b/llvm/include/llvm/Analysis/Loads.h
@@ -33,6 +33,7 @@ class MemoryLocation;
 class SCEV;
 class ScalarEvolution;
 class SCEVPredicate;
+class StoreInst;
 template <typename T> class SmallVectorImpl;
 class TargetLibraryInfo;
 
@@ -165,6 +166,16 @@ LLVM_ABI Value *
 FindAvailableLoadedValue(LoadInst *Load, BatchAAResults &AA, bool *IsLoadCSE,
                          unsigned MaxInstsToScan = DefMaxInstsToScan);
 
+/// Check whether \p SI, which may alias \p MemLoc, can be safely skipped.
+/// This is possible when \p SI does only MustAlias or NoAlias \p MemLoc (no
+/// partial overlap possible), and it stores the value \p MemLoc currently
+/// holds (loaded before the store and not modified in between).
+LLVM_ABI bool isStorePreservingMemoryLocation(const StoreInst *SI,
+                                              const MemoryLocation &MemLoc,
+                                              Align MemLocAlign,
+                                              BatchAAResults &AA,
+                                              unsigned ScanLimit);
+
 /// Scan backwards to see if we have the value of the given pointer available
 /// locally within a small number of instructions.
 ///
diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp
index de9022c540d42..13a5585c1fa3f 100644
--- a/llvm/lib/Analysis/Loads.cpp
+++ b/llvm/lib/Analysis/Loads.cpp
@@ -813,6 +813,36 @@ Value *llvm::FindAvailableLoadedValue(LoadInst *Load, BatchAAResults &AA,
   return Available;
 }
 
+bool llvm::isStorePreservingMemoryLocation(const StoreInst *SI,
+                                           const MemoryLocation &MemLoc,
+                                           Align MemLocAlign,
+                                           BatchAAResults &AA,
+                                           unsigned ScanLimit) {
+  // Ensure no partial overlap is possible, and that the stored value is the
+  // current content of MemLoc.
+  if (!MemLoc.Size.hasValue() || MemLoc.Size.isScalable())
+    return false;
+  if (MemoryLocation::get(SI).Size != MemLoc.Size)
+    return false;
+  if (std::min(MemLocAlign, SI->getAlign()).value() <
+      MemLoc.Size.getValue().getFixedValue())
+    return false;
+
+  auto *LI = dyn_cast<LoadInst>(SI->getValueOperand());
+  if (!LI || LI->getParent() != SI->getParent())
+    return false;
+  if (AA.alias(MemoryLocation::get(LI), MemLoc) != AliasResult::MustAlias)
+    return false;
+
+  // No memory operation in between may modify MemLoc.
+  unsigned NumVisited = 0;
+  for (const Instruction *I = LI; I != SI; I = I->getNextNode())
+    if (++NumVisited > ScanLimit || isModSet(AA.getModRefInfo(I, MemLoc)))
+      return false;
+
+  return true;
+}
+
 // Returns true if a use is either in an ICmp/PtrToInt or a Phi/Select that only
 // feeds into them.
 static bool isPointerUseReplaceable(const Use &U, bool HasNonAddressBits) {
diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
index a58608b53bb1f..a5a178c6f2583 100644
--- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -351,39 +351,6 @@ MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI,
   return MemDepResult::getNonLocal();
 }
 
-// Check if SI that may alias with MemLoc can be safely skipped. This is
-// possible in case if SI can only must alias or no alias with MemLoc (no
-// partial overlapping possible) and it writes the same value that MemLoc
-// contains now (it was loaded before this store and was not modified in
-// between).
-static bool canSkipClobberingStore(const StoreInst *SI,
-                                   const MemoryLocation &MemLoc,
-                                   Align MemLocAlign, BatchAAResults &BatchAA,
-                                   unsigned ScanLimit) {
-  if (!MemLoc.Size.hasValue())
-    return false;
-  if (MemoryLocation::get(SI).Size != MemLoc.Size)
-    return false;
-  if (MemLoc.Size.isScalable())
-    return false;
-  if (std::min(MemLocAlign, SI->getAlign()).value() <
-      MemLoc.Size.getValue().getKnownMinValue())
-    return false;
-
-  auto *LI = dyn_cast<LoadInst>(SI->getValueOperand());
-  if (!LI || LI->getParent() != SI->getParent())
-    return false;
-  if (BatchAA.alias(MemoryLocation::get(LI), MemLoc) != AliasResult::MustAlias)
-    return false;
-  unsigned NumVisitedInsts = 0;
-  for (const Instruction *I = LI; I != SI; I = I->getNextNode())
-    if (++NumVisitedInsts > ScanLimit ||
-        isModSet(BatchAA.getModRefInfo(I, MemLoc)))
-      return false;
-
-  return true;
-}
-
 MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
     const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt,
     BasicBlock *BB, Instruction *QueryInst, unsigned *Limit,
@@ -598,7 +565,8 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
         return MemDepResult::getDef(Inst);
       if (isInvariantLoad)
         continue;
-      if (canSkipClobberingStore(SI, MemLoc, MemLocAlign, BatchAA, *Limit))
+      if (isStorePreservingMemoryLocation(SI, MemLoc, MemLocAlign, BatchAA,
+                                          *Limit))
         continue;
       return MemDepResult::getClobber(Inst);
     }



More information about the llvm-commits mailing list