[PATCH] D98284: [DSE] Handle memcpy/memset with equal non-const sizes.

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 10 02:14:54 PST 2021


This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG8d9b9c0edceb: [DSE] Handle memcpy/memset with equal non-const sizes. (authored by fhahn).

Changed prior to commit:
  https://reviews.llvm.org/D98284?vs=329442&id=329580#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98284/new/

https://reviews.llvm.org/D98284

Files:
  llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
  llvm/test/Transforms/DeadStoreElimination/memory-intrinsics-sizes.ll


Index: llvm/test/Transforms/DeadStoreElimination/memory-intrinsics-sizes.ll
===================================================================
--- llvm/test/Transforms/DeadStoreElimination/memory-intrinsics-sizes.ll
+++ llvm/test/Transforms/DeadStoreElimination/memory-intrinsics-sizes.ll
@@ -4,7 +4,6 @@
 define void @memset_equal_size_values(i8* %ptr, i64 %len) {
 ; CHECK-LABEL: @memset_equal_size_values(
 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR:%.*]], i8 0, i64 [[LEN:%.*]], i1 false)
-; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR]], i8 0, i64 [[LEN]], i1 false)
 ; CHECK-NEXT:    ret void
 ;
   call void @llvm.memset.p0i8.i64(i8* align 1 %ptr, i8 0, i64 %len, i1 false)
@@ -45,10 +44,35 @@
   ret void
 }
 
+define void @memset_and_store_1(i8* %ptr, i64 %len) {
+; CHECK-LABEL: @memset_and_store_1(
+; CHECK-NEXT:    [[BC:%.*]] = bitcast i8* [[PTR:%.*]] to i64*
+; CHECK-NEXT:    store i64 123, i64* [[BC]], align 4
+; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR]], i8 0, i64 [[LEN:%.*]], i1 false)
+; CHECK-NEXT:    ret void
+;
+  %bc = bitcast i8* %ptr to i64*
+  store i64 123, i64* %bc
+  call void @llvm.memset.p0i8.i64(i8* align 1 %ptr, i8 0, i64 %len, i1 false)
+  ret void
+}
+
+define void @memset_and_store_2(i8* %ptr, i64 %len) {
+; CHECK-LABEL: @memset_and_store_2(
+; CHECK-NEXT:    [[BC:%.*]] = bitcast i8* [[PTR:%.*]] to i64*
+; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR]], i8 0, i64 [[LEN:%.*]], i1 false)
+; CHECK-NEXT:    store i64 123, i64* [[BC]], align 4
+; CHECK-NEXT:    ret void
+;
+  %bc = bitcast i8* %ptr to i64*
+  call void @llvm.memset.p0i8.i64(i8* align 1 %ptr, i8 0, i64 %len, i1 false)
+  store i64 123, i64* %bc
+  ret void
+}
+
 define void @memcpy_equal_size_values(i8* noalias %src, i8* noalias %dst, i64 %len) {
 ; CHECK-LABEL: @memcpy_equal_size_values(
 ; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
-; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC]], i64 [[LEN]], i1 false)
 ; CHECK-NEXT:    ret void
 ;
   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
@@ -91,8 +115,7 @@
 
 define void @memset_and_memcpy_equal_size_values(i8* noalias %src, i8* noalias %dst, i64 %len) {
 ; CHECK-LABEL: @memset_and_memcpy_equal_size_values(
-; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 1 [[DST:%.*]], i8 0, i64 [[LEN:%.*]], i1 false)
-; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC:%.*]], i64 [[LEN]], i1 false)
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
 ; CHECK-NEXT:    ret void
 ;
   call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 %len, i1 false)
@@ -135,8 +158,7 @@
 
 define void @memcpy_and_memset_equal_size_values(i8* noalias %src, i8* noalias %dst, i64 %len) {
 ; CHECK-LABEL: @memcpy_and_memset_equal_size_values(
-; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
-; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 1 [[DST]], i8 0, i64 [[LEN]], i1 false)
+; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 1 [[DST:%.*]], i8 0, i64 [[LEN:%.*]], i1 false)
 ; CHECK-NEXT:    ret void
 ;
   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
Index: llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -371,6 +371,25 @@
   // FIXME: Vet that this works for size upper-bounds. Seems unlikely that we'll
   // get imprecise values here, though (except for unknown sizes).
   if (!Later.Size.isPrecise() || !Earlier.Size.isPrecise()) {
+    // In case no constant size is known, try to an IR values for the number
+    // of bytes written and check if they match.
+    auto GetSizeFromInstr = [](const Instruction *I) -> Value * {
+      if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
+        switch (II->getIntrinsicID()) {
+        default:
+          return nullptr;
+        case Intrinsic::memcpy:
+        case Intrinsic::memset:
+          return II->getArgOperand(2);
+        }
+      }
+      return nullptr;
+    };
+    Value *LaterV = GetSizeFromInstr(LaterI);
+    Value *EarlierV = GetSizeFromInstr(EarlierI);
+    if (LaterV && LaterV == EarlierV && AA.isMustAlias(Earlier, Later))
+      return OW_Complete;
+
     // Masked stores have imprecise locations, but we can reason about them
     // to some extent.
     return isMaskedStoreOverwrite(LaterI, EarlierI, AA);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D98284.329580.patch
Type: text/x-patch
Size: 4783 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210310/89b3ed6a/attachment.bin>


More information about the llvm-commits mailing list