diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/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(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); diff --git a/llvm/test/Transforms/DeadStoreElimination/memory-intrinsics-sizes.ll b/llvm/test/Transforms/DeadStoreElimination/memory-intrinsics-sizes.ll --- a/llvm/test/Transforms/DeadStoreElimination/memory-intrinsics-sizes.ll +++ b/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)