[llvm] 9080444 - [MemCpyOpt] Don't generate zero-size memset

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 13 02:43:38 PST 2021


Author: Nikita Popov
Date: 2021-03-13T11:41:15+01:00
New Revision: 9080444f3311d62a98c28ce5a72b39da9e54e3cc

URL: https://github.com/llvm/llvm-project/commit/9080444f3311d62a98c28ce5a72b39da9e54e3cc
DIFF: https://github.com/llvm/llvm-project/commit/9080444f3311d62a98c28ce5a72b39da9e54e3cc.diff

LOG: [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.

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
    llvm/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll
    llvm/test/Transforms/MemCpyOpt/preserve-memssa.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index da4513535542..6b1c168967d2 100644
--- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -1172,6 +1172,13 @@ bool MemCpyOptPass::processMemSetMemCpyDependence(MemCpyInst *MemCpy,
   if (mayBeVisibleThroughUnwinding(Dest, MemSet, MemCpy))
     return false;
 
+  // If the sizes are the same, simply drop the memset instead of generating
+  // a replacement with zero size.
+  if (DestSize == SrcSize) {
+    eraseInstruction(MemSet);
+    return true;
+  }
+
   // By default, create an unaligned memset.
   unsigned Align = 1;
   // If Dest is aligned, and SrcSize is constant, use the minimum alignment

diff  --git a/llvm/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll b/llvm/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll
index 933fbec4efad..ce313ffe93a0 100644
--- a/llvm/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll
+++ b/llvm/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll
@@ -239,9 +239,7 @@ define void @test_missing_noalias(i8* %src, i64 %src_size, i8* %dst, i64 %dst_si
 
 define void @test_same_const_size(i8* noalias %src, i8* noalias %dst, i8 %c) {
 ; CHECK-LABEL: @test_same_const_size(
-; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i8, i8* [[DST:%.*]], i64 16
-; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP1]], i8 [[C:%.*]], i64 0, i1 false)
-; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC:%.*]], i64 16, i1 false)
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 16, i1 false)
 ; CHECK-NEXT:    ret void
 ;
   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) {
 
 define void @test_same_dynamic_size(i8* noalias %src, i8* noalias %dst, i64 %size, i8 %c) {
 ; CHECK-LABEL: @test_same_dynamic_size(
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i64 [[SIZE:%.*]], [[SIZE]]
-; CHECK-NEXT:    [[TMP2:%.*]] = sub i64 [[SIZE]], [[SIZE]]
-; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr i8, i8* [[DST:%.*]], i64 [[SIZE]]
-; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP4]], i8 [[C:%.*]], i64 [[TMP3]], i1 false)
-; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC:%.*]], i64 [[SIZE]], i1 false)
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[SIZE:%.*]], i1 false)
 ; CHECK-NEXT:    ret void
 ;
   call void @llvm.memset.p0i8.i64(i8* %dst, i8 %c, i64 %size, i1 false)

diff  --git a/llvm/test/Transforms/MemCpyOpt/preserve-memssa.ll b/llvm/test/Transforms/MemCpyOpt/preserve-memssa.ll
index 1b11b5c6f763..a4b11078cd7b 100644
--- a/llvm/test/Transforms/MemCpyOpt/preserve-memssa.ll
+++ b/llvm/test/Transforms/MemCpyOpt/preserve-memssa.ll
@@ -40,8 +40,6 @@ define void @test2(i8* noalias %in) {
 ; CHECK-LABEL: @test2(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[CALL_I1_I:%.*]] = tail call i8* @get_ptr()
-; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr i8, i8* [[CALL_I1_I]], i64 10
-; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP0]], i8 0, i64 0, i1 false)
 ; CHECK-NEXT:    tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[CALL_I1_I]], i8* [[IN:%.*]], i64 10, i1 false)
 ; CHECK-NEXT:    ret void
 ;
@@ -69,8 +67,6 @@ define void @test4(i32 %n, i8* noalias %ptr.0, i8* noalias %ptr.1, i32* %ptr.2)
 ; CHECK-LABEL: @test4(
 ; CHECK-NEXT:    [[ELEM_I:%.*]] = getelementptr i8, i8* [[PTR_0:%.*]], i64 8
 ; CHECK-NEXT:    store i32 [[N:%.*]], i32* [[PTR_2:%.*]], align 8
-; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i8, i8* [[ELEM_I]], i64 10
-; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP1]], i8 0, i64 0, i1 false)
 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[ELEM_I]], i8* [[PTR_1:%.*]], i64 10, i1 false)
 ; CHECK-NEXT:    ret void
 ;


        


More information about the llvm-commits mailing list