[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