Skip to content

Commit 9080444

Browse files
committed
[MemCpyOpt] Don't generate zero-size memset
If a memset destination is overwritten by a memcpy and the sizes are exactly the same, then the memset is simply dead. We can directly drop it, instead of replacing it with a memset of zero size, which is particularly ugly for the case of a dynamic size.
1 parent dabd6ab commit 9080444

File tree

3 files changed

+9
-13
lines changed

3 files changed

+9
-13
lines changed

llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,13 @@ bool MemCpyOptPass::processMemSetMemCpyDependence(MemCpyInst *MemCpy,
11721172
if (mayBeVisibleThroughUnwinding(Dest, MemSet, MemCpy))
11731173
return false;
11741174

1175+
// If the sizes are the same, simply drop the memset instead of generating
1176+
// a replacement with zero size.
1177+
if (DestSize == SrcSize) {
1178+
eraseInstruction(MemSet);
1179+
return true;
1180+
}
1181+
11751182
// By default, create an unaligned memset.
11761183
unsigned Align = 1;
11771184
// If Dest is aligned, and SrcSize is constant, use the minimum alignment

llvm/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll

+2-9
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,7 @@ define void @test_missing_noalias(i8* %src, i64 %src_size, i8* %dst, i64 %dst_si
239239

240240
define void @test_same_const_size(i8* noalias %src, i8* noalias %dst, i8 %c) {
241241
; CHECK-LABEL: @test_same_const_size(
242-
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, i8* [[DST:%.*]], i64 16
243-
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP1]], i8 [[C:%.*]], i64 0, i1 false)
244-
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC:%.*]], i64 16, i1 false)
242+
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 16, i1 false)
245243
; CHECK-NEXT: ret void
246244
;
247245
call void @llvm.memset.p0i8.i64(i8* %dst, i8 %c, i64 16, i1 false)
@@ -251,12 +249,7 @@ define void @test_same_const_size(i8* noalias %src, i8* noalias %dst, i8 %c) {
251249

252250
define void @test_same_dynamic_size(i8* noalias %src, i8* noalias %dst, i64 %size, i8 %c) {
253251
; CHECK-LABEL: @test_same_dynamic_size(
254-
; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[SIZE:%.*]], [[SIZE]]
255-
; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[SIZE]], [[SIZE]]
256-
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]]
257-
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, i8* [[DST:%.*]], i64 [[SIZE]]
258-
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP4]], i8 [[C:%.*]], i64 [[TMP3]], i1 false)
259-
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC:%.*]], i64 [[SIZE]], i1 false)
252+
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[SIZE:%.*]], i1 false)
260253
; CHECK-NEXT: ret void
261254
;
262255
call void @llvm.memset.p0i8.i64(i8* %dst, i8 %c, i64 %size, i1 false)

llvm/test/Transforms/MemCpyOpt/preserve-memssa.ll

-4
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ define void @test2(i8* noalias %in) {
4040
; CHECK-LABEL: @test2(
4141
; CHECK-NEXT: entry:
4242
; CHECK-NEXT: [[CALL_I1_I:%.*]] = tail call i8* @get_ptr()
43-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, i8* [[CALL_I1_I]], i64 10
44-
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP0]], i8 0, i64 0, i1 false)
4543
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[CALL_I1_I]], i8* [[IN:%.*]], i64 10, i1 false)
4644
; CHECK-NEXT: ret void
4745
;
@@ -69,8 +67,6 @@ define void @test4(i32 %n, i8* noalias %ptr.0, i8* noalias %ptr.1, i32* %ptr.2)
6967
; CHECK-LABEL: @test4(
7068
; CHECK-NEXT: [[ELEM_I:%.*]] = getelementptr i8, i8* [[PTR_0:%.*]], i64 8
7169
; CHECK-NEXT: store i32 [[N:%.*]], i32* [[PTR_2:%.*]], align 8
72-
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, i8* [[ELEM_I]], i64 10
73-
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP1]], i8 0, i64 0, i1 false)
7470
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[ELEM_I]], i8* [[PTR_1:%.*]], i64 10, i1 false)
7571
; CHECK-NEXT: ret void
7672
;

0 commit comments

Comments
 (0)