[llvm] [MemCpyOpt] allow more memcpy-to-memcpy optimization (PR #150792)
Jameson Nash via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 26 13:18:42 PDT 2025
================
@@ -1532,21 +1559,43 @@ bool MemCpyOptPass::performStackMoveOptzn(Instruction *Load, Instruction *Store,
return false;
}
- // Check that copy is full with static size.
- const DataLayout &DL = DestAlloca->getDataLayout();
- std::optional<TypeSize> SrcSize = SrcAlloca->getAllocationSize(DL);
- if (!SrcSize || Size != *SrcSize) {
- LLVM_DEBUG(dbgs() << "Stack Move: Source alloca size mismatch\n");
- return false;
- }
- std::optional<TypeSize> DestSize = DestAlloca->getAllocationSize(DL);
- if (!DestSize || Size != *DestSize) {
- LLVM_DEBUG(dbgs() << "Stack Move: Destination alloca size mismatch\n");
+ if (SrcAlloca->isUsedWithInAlloca() || DestAlloca->isUsedWithInAlloca())
return false;
- }
- if (!SrcAlloca->isStaticAlloca() || !DestAlloca->isStaticAlloca())
- return false;
+ Type *SrcType = SrcAlloca->getAllocatedType();
+ Type *DestType = DestAlloca->getAllocatedType();
+ // If they don't have common type, then they will need to be converted to a
+ // common size at runtime
+ const auto &DL = SrcAlloca->getDataLayout();
+ TypeSize SrcSize = DL.getTypeAllocSize(SrcType);
+ TypeSize DestSize = DL.getTypeAllocSize(DestType);
+ if (SrcType != DestType)
+ if (SrcSize != DestSize)
+ if (!SrcSize.isFixed() || !DestSize.isFixed())
+ return false;
+
+ // Check that copy is full with dest size, either because it wrote every byte,
+ // or it was fresh.
+ std::optional<TypeSize> FullSize = DestAlloca->getAllocationSize(DL);
+ if (!FullSize || Size != *FullSize)
+ if (!allOverreadUndefContents(MSSA, Store, BAA)) {
+ LLVM_DEBUG(dbgs() << "Stack Move: Destination alloca size mismatch\n");
+ return false;
+ }
+
+ // Check if it will be legal to combine allocas without breaking dominator.
+ // TODO: Try to hoist the arguments (recursively) instead of giving up
+ // immediately.
----------------
vtjnash wrote:
Which size domination check goes away?
Writing `llvm.umax()` instrinsic vs `llvm::max()` call seem essentially the same amount of code here, but slightly more annoying to have to convert from an LLVM Value to a compile-time value and back again, when LLVM's already has APIs to do this directly on LLVM Values (InstSimplifyFolder) just as easily
https://github.com/llvm/llvm-project/pull/150792
More information about the llvm-commits
mailing list