[llvm] 09d1b94 - [MemCpyOpt] Fix incorrect size check in memmove of memset opt (#206451)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 29 05:37:16 PDT 2026
Author: Nikita Popov
Date: 2026-06-29T14:37:11+02:00
New Revision: 09d1b945b52e9cdb318842a051bab8fbc3d83d9f
URL: https://github.com/llvm/llvm-project/commit/09d1b945b52e9cdb318842a051bab8fbc3d83d9f
DIFF: https://github.com/llvm/llvm-project/commit/09d1b945b52e9cdb318842a051bab8fbc3d83d9f.diff
LOG: [MemCpyOpt] Fix incorrect size check in memmove of memset opt (#206451)
We were only checking that the memset is at least as large as the
memmove size, but not accounting for the fact that the memmove occurs at
an offset.
Added:
Modified:
llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
llvm/test/Transforms/MemCpyOpt/memset-memmove-redundant-memmove.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index 3f6bb6f408797..3fc84f2fc8c13 100644
--- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -1963,7 +1963,8 @@ bool MemCpyOptPass::isMemMoveMemSetDependency(MemMoveInst *M) {
// Memset length must be sufficiently large.
auto *MemSetLength = dyn_cast<ConstantInt>(MS->getLength());
- if (!MemSetLength || MemSetLength->getZExtValue() < MemMoveSize)
+ if (!MemSetLength ||
+ MemSetLength->getZExtValue() < Offset.getZExtValue() + MemMoveSize)
return false;
// The destination buffer must have been memset'd.
diff --git a/llvm/test/Transforms/MemCpyOpt/memset-memmove-redundant-memmove.ll b/llvm/test/Transforms/MemCpyOpt/memset-memmove-redundant-memmove.ll
index c7593e2941518..ab4d501c01e06 100644
--- a/llvm/test/Transforms/MemCpyOpt/memset-memmove-redundant-memmove.ll
+++ b/llvm/test/Transforms/MemCpyOpt/memset-memmove-redundant-memmove.ll
@@ -175,6 +175,20 @@ define i32 @memset_memmove_dest_buffers_not_alias() {
ret i32 %val
}
+; memset covers size of memmove but not the source offset.
+define void @memset_shorter_than_offset_plus_size(ptr %array) {
+; CHECK-LABEL: @memset_shorter_than_offset_plus_size(
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[ARRAY:%.*]], i8 0, i64 8, i1 false)
+; CHECK-NEXT: [[ARRAY_IDX:%.*]] = getelementptr inbounds i8, ptr [[ARRAY]], i64 4
+; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 16 [[ARRAY]], ptr align 4 [[ARRAY_IDX]], i64 8, i1 false)
+; CHECK-NEXT: ret void
+;
+ call void @llvm.memset.p0.i64(ptr align 16 %array, i8 0, i64 8, i1 false)
+ %array.idx = getelementptr inbounds i8, ptr %array, i64 4
+ call void @llvm.memmove.p0.p0.i64(ptr align 16 %array, ptr align 4 %array.idx, i64 8, i1 false)
+ ret void
+}
+
declare void @opaque(ptr)
declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1)
declare void @llvm.memmove.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1)
More information about the llvm-commits
mailing list