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

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 9 12:43:25 PST 2021


fhahn created this revision.
fhahn added reviewers: asbirlea, nikic, ebrevnov.
Herald added a subscriber: hiraditya.
fhahn requested review of this revision.
Herald added a project: LLVM.

Currently DSE misses cases where the size is a non-const IR value, even
if they match. For example, this means that llvm.memcpy/llvm.memset
calls are not eliminated, even if they write the same number of bytes.

This patch extends isOverwite to try to get IR values for the number of
bytes written from the analyzed instructions. If the values match,
alias checks are performed and the result is returned.

At the moment this only covers llvm.memcpy/llvm.memset. In the future,
we may enable MemoryLocation to also track variable sizes, but this
simple approach should allow us to cover the important cases in DSE.


Repository:
  rG LLVM Github Monorepo

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)
@@ -48,7 +47,6 @@
 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)
Index: llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -371,6 +371,29 @@
   // 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) {
+      const Value *P1 = Earlier.Ptr->stripPointerCasts();
+      const Value *P2 = Later.Ptr->stripPointerCasts();
+      if (P1 == P2 || AA.isMustAlias(P1, P2))
+        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.329442.patch
Type: text/x-patch
Size: 2682 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210309/06d09b6e/attachment.bin>


More information about the llvm-commits mailing list