[llvm] [MemoryLocation][DSE] Allow other read effects in MemoryLocation::getForDest() (PR #144343)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 16 05:36:42 PDT 2025


https://github.com/nikic created https://github.com/llvm/llvm-project/pull/144343

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.


>From ffbf398f4a68a9fd177af966322ccdc20f6c8f55 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 16 Jun 2025 14:27:02 +0200
Subject: [PATCH 1/2] 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 <npopov at redhat.com>
Date: Mon, 16 Jun 2025 14:33:18 +0200
Subject: [PATCH 2/2] [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>
 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]]
 ;



More information about the llvm-commits mailing list