[llvm] [MemCpyOpt] Drop dead `memmove` calls on `memset`'d source data (PR #101930)
Antonio Frighetto via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 27 10:41:37 PST 2024
================
@@ -1843,12 +1844,77 @@ 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) {
+ const auto &DL = M->getDataLayout();
+ MemSetInst *MS = nullptr;
+ MemoryUseOrDef *MemMoveAccess = MSSA->getMemoryAccess(M);
+ if (!MemMoveAccess)
+ return false;
+
+ BatchAAResults BAA(*AA);
+ MemoryAccess *FirstDef = MemMoveAccess->getDefiningAccess();
+ MemoryLocation SourceLoc = MemoryLocation::getForSource(M);
+ MemoryLocation DestLoc = MemoryLocation::getForDest(M);
+
+ // The first dominating clobbering MemoryAccess for the source location
+ // needs to be the memset.
+ MemoryAccess *SourceClobber =
+ MSSA->getWalker()->getClobberingMemoryAccess(FirstDef, SourceLoc, BAA);
+ if (auto *Def = dyn_cast<MemoryDef>(SourceClobber))
+ MS = dyn_cast_or_null<MemSetInst>(Def->getMemoryInst());
+ if (!MS)
+ return false;
+
+ // The destination buffer must have been memset'd.
+ if (!BAA.isMustAlias(MS->getDest(), M->getDest()))
+ return false;
+
+ // The memmove is of form memmove(x, x + A, B).
+ auto *Source = dyn_cast<GetElementPtrInst>(M->getSource());
+ if (!Source)
+ return false;
+ APInt Offset(DL.getIndexTypeSizeInBits(Source->getType()), 0);
+ auto MemMoveSize = MemoryLocation::getForSource(M).Size;
+ if (!Source->accumulateConstantOffset(DL, Offset) || Offset.isNegative() ||
+ Source->getPointerOperand() != M->getDest() || !MemMoveSize.hasValue())
+ return false;
+
+ LocationSize TotalSize =
+ LocationSize::precise(Offset.getZExtValue() + MemMoveSize.getValue());
+ MemoryLocation CombinedSourceLoc(M->getSource(), TotalSize);
+ MemoryLocation CombinedDestLoc(M->getDest(), TotalSize);
+ if (!isModOrRefSet(BAA.getModRefInfo(MS, CombinedSourceLoc)) ||
+ !isModOrRefSet(BAA.getModRefInfo(MS, CombinedDestLoc)))
+ return false;
+
+ // The first dominating clobbering MemoryAccess for the destination location
+ // needs to be the memset as well.
+ MemoryAccess *DestClobber =
+ MSSA->getWalker()->getClobberingMemoryAccess(FirstDef, DestLoc, BAA);
----------------
antoniofrighetto wrote:
Updated, thanks!
https://github.com/llvm/llvm-project/pull/101930
More information about the llvm-commits
mailing list