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

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 6 06:46:52 PDT 2024


================
@@ -1853,12 +1854,54 @@ 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::isMemMoveMemSetDependency(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());
+
+  // Limit the memset to be within the same basic block.
+  if (!MS || MS->getParent() != M->getParent())
+    return false;
+
+  // The destination buffer must have been memset'd.
+  if (!BAA.isMustAlias(MS->getDest(), M->getDest()))
----------------
nikic wrote:

You also need to make sure that the source location is a subset of the memset memory. Currently, you just find a *potentially* clobbering memset, and then assume that it is fully clobbering. I think this is why https://github.com/dtcxzyw/llvm-opt-benchmark/pull/1135/files#diff-532ba66b66620dd644c14e91d18a3293194f3bfadfef06f698e87588e3d060ed is miscompiled.

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


More information about the llvm-commits mailing list