From ffbf398f4a68a9fd177af966322ccdc20f6c8f55 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 16 Jun 2025 14:27:02 +0200 Subject: [PATCH 1/3] Add test for call dse with additional read effects --- .../DeadStoreElimination/trivial-dse-calls.ll | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll b/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll index 030d315bfd925..f72a68f9796b2 100644 --- a/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll +++ b/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll @@ -286,3 +286,26 @@ define void @test_dse_non_alloca() { ret void } +define void @test_other_read_effects() { +; CHECK-LABEL: @test_other_read_effects( +; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 +; CHECK-NEXT: call void @f(ptr [[A]]) #[[ATTR5:[0-9]+]] +; CHECK-NEXT: ret void +; + %a = alloca i32, align 4 + call void @f(ptr %a) memory(read, argmem: readwrite) nounwind willreturn + ret void +} + +define i32 @test_other_read_effects_read_after() { +; CHECK-LABEL: @test_other_read_effects_read_after( +; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 +; CHECK-NEXT: call void @f(ptr [[A]]) #[[ATTR5]] +; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4 +; CHECK-NEXT: ret i32 [[V]] +; + %a = alloca i32, align 4 + call void @f(ptr %a) memory(read, argmem: readwrite) nounwind willreturn + %v = load i32, ptr %a + ret i32 %v +} From 18a2cd3690bb185488fe4a29498e27a92be71d3c Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 16 Jun 2025 14:33:18 +0200 Subject: [PATCH 2/3] [MemoryLocation][DSE] Allow other read effects in MemoryLocation::getForDest() MemoryLocation::getForDest() returns a (potentially) written location, while still allowing other reads. Currently, this is limited to argmemonly functions. However, we can ignore other (non-argmem) read effects here for the same reason we can ignore argument reads. Fixes https://github.com/llvm/llvm-project/issues/144300. --- llvm/lib/Analysis/MemoryLocation.cpp | 4 +++- .../test/Transforms/DeadStoreElimination/trivial-dse-calls.ll | 4 +--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Analysis/MemoryLocation.cpp b/llvm/lib/Analysis/MemoryLocation.cpp index 3b42bb412b9ba..c8daab7abde18 100644 --- a/llvm/lib/Analysis/MemoryLocation.cpp +++ b/llvm/lib/Analysis/MemoryLocation.cpp @@ -111,7 +111,9 @@ MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) { std::optional MemoryLocation::getForDest(const CallBase *CB, const TargetLibraryInfo &TLI) { - if (!CB->onlyAccessesArgMemory()) + // Check that the only possible writes are to arguments. + MemoryEffects WriteME = CB->getMemoryEffects() & MemoryEffects::writeOnly(); + if (!WriteME.onlyAccessesArgPointees()) return std::nullopt; if (CB->hasOperandBundles()) diff --git a/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll b/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll index f72a68f9796b2..8a69f1f55d491 100644 --- a/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll +++ b/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll @@ -288,8 +288,6 @@ define void @test_dse_non_alloca() { define void @test_other_read_effects() { ; CHECK-LABEL: @test_other_read_effects( -; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 -; CHECK-NEXT: call void @f(ptr [[A]]) #[[ATTR5:[0-9]+]] ; CHECK-NEXT: ret void ; %a = alloca i32, align 4 @@ -300,7 +298,7 @@ define void @test_other_read_effects() { define i32 @test_other_read_effects_read_after() { ; CHECK-LABEL: @test_other_read_effects_read_after( ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 -; CHECK-NEXT: call void @f(ptr [[A]]) #[[ATTR5]] +; CHECK-NEXT: call void @f(ptr [[A]]) #[[ATTR5:[0-9]+]] ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4 ; CHECK-NEXT: ret i32 [[V]] ; From cf14cfa674d40a809f0be934ebd466c89bcbb797 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 16 Jun 2025 14:37:44 +0200 Subject: [PATCH 3/3] Add additional negative test with write effect --- .../DeadStoreElimination/trivial-dse-calls.ll | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll b/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll index 8a69f1f55d491..df2feb087e397 100644 --- a/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll +++ b/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll @@ -307,3 +307,14 @@ define i32 @test_other_read_effects_read_after() { %v = load i32, ptr %a ret i32 %v } + +define void @test_other_write_effects() { +; CHECK-LABEL: @test_other_write_effects( +; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 +; CHECK-NEXT: call void @f(ptr [[A]]) #[[ATTR6:[0-9]+]] +; CHECK-NEXT: ret void +; + %a = alloca i32, align 4 + call void @f(ptr %a) memory(write, argmem: readwrite) nounwind willreturn + ret void +}