[llvm] [MemCpyOpt] Drop dead `memmove` calls on `memset`'d source data (PR #101930)

Antonio Frighetto via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 5 03:36:33 PDT 2024


================
@@ -1854,12 +1855,53 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
   return false;
 }
 
+/// Memmove calls with overlapping src/dest buffers that come after a memset may
+/// be removed.
+bool MemCpyOptPass::mayBeMemMoveMemSetDependency(MemMoveInst *M) {
+  MemoryUseOrDef *MemMoveAccess = MSSA->getMemoryAccess(M);
+  if (!MemMoveAccess)
+    return false;
+
+  BatchAAResults BAA(*AA);
+  MemoryAccess *FirstDef = MemMoveAccess->getDefiningAccess();
+  MemoryLocation SourceLoc = MemoryLocation::getForSource(M);
+  MemoryAccess *SourceClobber =
+      MSSA->getWalker()->getClobberingMemoryAccess(FirstDef, SourceLoc, BAA);
+
+  MemSetInst *MS = nullptr;
+  if (auto *Def = dyn_cast<MemoryDef>(SourceClobber))
+    MS = dyn_cast_or_null<MemSetInst>(Def->getMemoryInst());
+
+  if (!MS || MS->getParent() != M->getParent())
+    return false;
+
+  // The destination buffer must have been memset'd.
+  if (!BAA.isMustAlias(MS->getDest(), M->getDest()))
+    return false;
+
+  // No clobbering writes in between.
+  if (writtenBetween(MSSA, BAA, SourceLoc, MSSA->getMemoryAccess(MS),
+                     MemMoveAccess))
+    return false;
+  return true;
+}
+
 /// Transforms memmove calls to memcpy calls when the src/dst are guaranteed
 /// not to alias.
-bool MemCpyOptPass::processMemMove(MemMoveInst *M) {
+bool MemCpyOptPass::processMemMove(MemMoveInst *M, BasicBlock::iterator &BBI) {
   // See if the source could be modified by this memmove potentially.
-  if (isModSet(AA->getModRefInfo(M, MemoryLocation::getForSource(M))))
+  if (isModSet(AA->getModRefInfo(M, MemoryLocation::getForSource(M)))) {
+    // On the off-chance the memmove clobbers src with previously memset'd
+    // bytes, the memmove may be redundant.
+    if (mayBeMemMoveMemSetDependency(M)) {
+      LLVM_DEBUG(dbgs() << "Removed redundant memmove.\n");
----------------
antoniofrighetto wrote:

The logging seems to be already coherent with the ones used in MemCpyOpt? E.g.: https://github.com/llvm/llvm-project/blob/71051deff27928cff908ea794e09806eee662801/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp#L1826

https://github.com/llvm/llvm-project/pull/101930


More information about the llvm-commits mailing list