[llvm] [AMDGPU] Account for aliasing reads in RewriteOutArguments (PR #209908)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 16 10:12:51 PDT 2026


https://github.com/robertvirany updated https://github.com/llvm/llvm-project/pull/209908

>From 06a31d9b5f1d99311837220270964b19132e013b Mon Sep 17 00:00:00 2001
From: Robert Virany <robertvirany at gmail.com>
Date: Wed, 15 Jul 2026 13:46:53 -0600
Subject: [PATCH 1/3] [AMDGPU] Precommit test

---
 .../CodeGen/AMDGPU/rewrite-out-arguments-2.ll | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll b/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll
index 5a35d603e9703..354101b16d818 100644
--- a/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll
+++ b/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll
@@ -13,6 +13,31 @@ define i32 @load_out_ptr_after_store(ptr addrspace(5) %out) {
   ret i32 %load
 }
 
+define i32 @callee(ptr addrspace(5) %val, ptr addrspace(5) %other) {
+; CHECK-LABEL: define i32 @callee(ptr addrspace(5) %val, ptr addrspace(5) %other) {
+; CHECK-NEXT: store i32 0, ptr addrspace(5) %val, align 4
+; CHECK-NEXT: %load = load i32, ptr addrspace(5) %other, align 4
+; CHECK-NEXT: ret i32 %load
+  store i32 0, ptr addrspace(5) %val
+  %load = load i32, ptr addrspace(5) %other
+  ret i32 %load
+}
+
+define amdgpu_kernel void @caller(ptr addrspace(1) %out) {
+; CHECK-LABEL: define amdgpu_kernel void @caller(ptr addrspace(1) %out) {
+; CHECK-NEXT: %slot = alloca i32, align 4, addrspace(5)
+; CHECK-NEXT: store i32 1, ptr addrspace(5) %slot, align 4
+; CHECK-NEXT: %result = call i32 @callee(ptr addrspace(5) %slot, ptr addrspace(5) %slot)
+; CHECK-NEXT: store i32 %result, ptr addrspace(1) %out, align 4
+; CHECK-NEXT: ret void
+  %slot = alloca i32, addrspace(5)
+  store i32 1, ptr addrspace(5) %slot
+  %result = call i32 @callee(ptr addrspace(5) %slot,
+                            ptr addrspace(5) %slot)
+  store i32 %result, ptr addrspace(1) %out
+  ret void
+}
+
 define i32 @load_out_ptr_before_store(ptr addrspace(5) %out) {
 ; CHECK-LABEL: define i32 @load_out_ptr_before_store(
 ; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) {

>From 7c09529242ccce933b15b60931da4997feb5b23e Mon Sep 17 00:00:00 2001
From: Robert Virany <robertvirany at gmail.com>
Date: Wed, 15 Jul 2026 15:58:48 -0600
Subject: [PATCH 2/3] [AMDGPU] Account for aliasing reads in
 RewriteOutArguments

Reject rewriting an out argument when an intervening memory access may
read or write the out argument location.
---
 .../AMDGPU/AMDGPURewriteOutArguments.cpp      |  5 +-
 .../CodeGen/AMDGPU/rewrite-out-arguments-2.ll | 62 +++++++++----------
 2 files changed, 32 insertions(+), 35 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp
index 7db637eaa0745..30431cb54249c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp
@@ -207,10 +207,9 @@ static StoreInst *findStoreForOutArgument(BasicBlock *BB, Argument *OutArg,
       }
     }
 
-    // Any other memory access that writes the location prevents the
+    // Any other memory access that may read or write the location prevents the
     // rewrite.
-    // FIXME: should handle aliasing reads too.
-    if (isModSet(BAA.getModRefInfo(I, ArgLoc)))
+    if (isModOrRefSet(BAA.getModRefInfo(I, ArgLoc)))
       return nullptr;
   }
 
diff --git a/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll b/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll
index 354101b16d818..1e08b742bcb26 100644
--- a/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll
+++ b/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll
@@ -14,26 +14,30 @@ define i32 @load_out_ptr_after_store(ptr addrspace(5) %out) {
 }
 
 define i32 @callee(ptr addrspace(5) %val, ptr addrspace(5) %other) {
-; CHECK-LABEL: define i32 @callee(ptr addrspace(5) %val, ptr addrspace(5) %other) {
-; CHECK-NEXT: store i32 0, ptr addrspace(5) %val, align 4
-; CHECK-NEXT: %load = load i32, ptr addrspace(5) %other, align 4
-; CHECK-NEXT: ret i32 %load
+; CHECK-LABEL: define i32 @callee(
+; CHECK-SAME: ptr addrspace(5) [[VAL:%.*]], ptr addrspace(5) [[OTHER:%.*]]) {
+; CHECK-NEXT:    store i32 0, ptr addrspace(5) [[VAL]], align 4
+; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr addrspace(5) [[OTHER]], align 4
+; CHECK-NEXT:    ret i32 [[LOAD]]
+;
   store i32 0, ptr addrspace(5) %val
   %load = load i32, ptr addrspace(5) %other
   ret i32 %load
 }
 
 define amdgpu_kernel void @caller(ptr addrspace(1) %out) {
-; CHECK-LABEL: define amdgpu_kernel void @caller(ptr addrspace(1) %out) {
-; CHECK-NEXT: %slot = alloca i32, align 4, addrspace(5)
-; CHECK-NEXT: store i32 1, ptr addrspace(5) %slot, align 4
-; CHECK-NEXT: %result = call i32 @callee(ptr addrspace(5) %slot, ptr addrspace(5) %slot)
-; CHECK-NEXT: store i32 %result, ptr addrspace(1) %out, align 4
-; CHECK-NEXT: ret void
+; CHECK-LABEL: define amdgpu_kernel void @caller(
+; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) {
+; CHECK-NEXT:    [[SLOT:%.*]] = alloca i32, align 4, addrspace(5)
+; CHECK-NEXT:    store i32 1, ptr addrspace(5) [[SLOT]], align 4
+; CHECK-NEXT:    [[RESULT:%.*]] = call i32 @callee(ptr addrspace(5) [[SLOT]], ptr addrspace(5) [[SLOT]])
+; CHECK-NEXT:    store i32 [[RESULT]], ptr addrspace(1) [[OUT]], align 4
+; CHECK-NEXT:    ret void
+;
   %slot = alloca i32, addrspace(5)
   store i32 1, ptr addrspace(5) %slot
   %result = call i32 @callee(ptr addrspace(5) %slot,
-                            ptr addrspace(5) %slot)
+  ptr addrspace(5) %slot)
   store i32 %result, ptr addrspace(1) %out
   ret void
 }
@@ -108,12 +112,10 @@ define void @atomic_store_out_ptr_after_store(ptr addrspace(5) %out) {
 
 define i32 @load_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
 ; CHECK-LABEL: define i32 @load_ptr_after_store(
-; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT:    [[TMP3:%.*]] = call [[LOAD_PTR_AFTER_STORE:%.*]] @[[LOAD_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]])
-; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue [[LOAD_PTR_AFTER_STORE]] [[TMP3]], 1
-; CHECK-NEXT:    store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4
-; CHECK-NEXT:    [[TMP5:%.*]] = extractvalue [[LOAD_PTR_AFTER_STORE]] [[TMP3]], 0
-; CHECK-NEXT:    ret i32 [[TMP5]]
+; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) {
+; CHECK-NEXT:    store i32 0, ptr addrspace(5) [[OUT]], align 4
+; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr addrspace(5) [[PTR]], align 4
+; CHECK-NEXT:    ret i32 [[LOAD]]
 ;
   store i32 0, ptr addrspace(5) %out
   %load = load i32, ptr addrspace(5) %ptr
@@ -122,12 +124,10 @@ define i32 @load_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
 
 define i32 @volatile_load_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
 ; CHECK-LABEL: define i32 @volatile_load_ptr_after_store(
-; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT:    [[TMP3:%.*]] = call [[VOLATILE_LOAD_PTR_AFTER_STORE:%.*]] @[[VOLATILE_LOAD_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]])
-; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue [[VOLATILE_LOAD_PTR_AFTER_STORE]] [[TMP3]], 1
-; CHECK-NEXT:    store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4
-; CHECK-NEXT:    [[TMP5:%.*]] = extractvalue [[VOLATILE_LOAD_PTR_AFTER_STORE]] [[TMP3]], 0
-; CHECK-NEXT:    ret i32 [[TMP5]]
+; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) {
+; CHECK-NEXT:    store i32 0, ptr addrspace(5) [[OUT]], align 4
+; CHECK-NEXT:    [[LOAD:%.*]] = load volatile i32, ptr addrspace(5) [[PTR]], align 4
+; CHECK-NEXT:    ret i32 [[LOAD]]
 ;
   store i32 0, ptr addrspace(5) %out
   %load = load volatile i32, ptr addrspace(5) %ptr
@@ -148,7 +148,7 @@ define i32 @atomic_load_acquire_ptr_after_store(ptr addrspace(5) %out, ptr addrs
 
 define i32 @atomic_load_monotonic_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) {
 ; CHECK-LABEL: define i32 @atomic_load_monotonic_ptr_after_store(
-; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] {
+; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0:[0-9]+]] {
 ; CHECK-NEXT:    [[TMP3:%.*]] = call [[ATOMIC_LOAD_MONOTONIC_PTR_AFTER_STORE:%.*]] @[[ATOMIC_LOAD_MONOTONIC_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]])
 ; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue [[ATOMIC_LOAD_MONOTONIC_PTR_AFTER_STORE]] [[TMP3]], 1
 ; CHECK-NEXT:    store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4
@@ -198,10 +198,9 @@ define void @atomic_store_unordered_ptr_after_store(ptr addrspace(5) %out, ptr a
 
 define void @opaque_read_call_after_store(ptr addrspace(5) %out) {
 ; CHECK-LABEL: define void @opaque_read_call_after_store(
-; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT:    [[TMP2:%.*]] = call [[OPAQUE_READ_CALL_AFTER_STORE:%.*]] @[[OPAQUE_READ_CALL_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison)
-; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue [[OPAQUE_READ_CALL_AFTER_STORE]] [[TMP2]], 0
-; CHECK-NEXT:    store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4
+; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) {
+; CHECK-NEXT:    store i32 0, ptr addrspace(5) [[OUT]], align 4
+; CHECK-NEXT:    call void @opaque_read()
 ; CHECK-NEXT:    ret void
 ;
   store i32 0, ptr addrspace(5) %out
@@ -235,10 +234,9 @@ define void @opaque_call_after_store(ptr addrspace(5) %out) {
 
 define void @memcpy_after_store(ptr addrspace(5) %out, ptr addrspace(5) %src, ptr addrspace(5) noalias %dst) {
 ; CHECK-LABEL: define void @memcpy_after_store(
-; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]], ptr addrspace(5) noalias [[TMP2:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT:    [[TMP4:%.*]] = call [[MEMCPY_AFTER_STORE:%.*]] @[[MEMCPY_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[TMP2]])
-; CHECK-NEXT:    [[TMP5:%.*]] = extractvalue [[MEMCPY_AFTER_STORE]] [[TMP4]], 0
-; CHECK-NEXT:    store i32 [[TMP5]], ptr addrspace(5) [[TMP0]], align 4
+; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[SRC:%.*]], ptr addrspace(5) noalias [[DST:%.*]]) {
+; CHECK-NEXT:    store i32 0, ptr addrspace(5) [[OUT]], align 4
+; CHECK-NEXT:    call void @llvm.memcpy.p5.p5.i32(ptr addrspace(5) [[DST]], ptr addrspace(5) [[SRC]], i32 4, i1 false)
 ; CHECK-NEXT:    ret void
 ;
   store i32 0, ptr addrspace(5) %out

>From ee5e5ed014cf6841bb339762179d1c8305c1c4bc Mon Sep 17 00:00:00 2001
From: Robert Virany <robertvirany at gmail.com>
Date: Thu, 16 Jul 2026 11:11:32 -0600
Subject: [PATCH 3/3] [AMDGPU] Rename aliasing reads tests in
 rewrite-out-arguments-2.ll

---
 llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll b/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll
index 1e08b742bcb26..416f3f990ed5d 100644
--- a/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll
+++ b/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll
@@ -13,8 +13,8 @@ define i32 @load_out_ptr_after_store(ptr addrspace(5) %out) {
   ret i32 %load
 }
 
-define i32 @callee(ptr addrspace(5) %val, ptr addrspace(5) %other) {
-; CHECK-LABEL: define i32 @callee(
+define i32 @callee_with_aliasing_args(ptr addrspace(5) %val, ptr addrspace(5) %other) {
+; CHECK-LABEL: define i32 @callee_with_aliasing_args(
 ; CHECK-SAME: ptr addrspace(5) [[VAL:%.*]], ptr addrspace(5) [[OTHER:%.*]]) {
 ; CHECK-NEXT:    store i32 0, ptr addrspace(5) [[VAL]], align 4
 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr addrspace(5) [[OTHER]], align 4
@@ -25,8 +25,8 @@ define i32 @callee(ptr addrspace(5) %val, ptr addrspace(5) %other) {
   ret i32 %load
 }
 
-define amdgpu_kernel void @caller(ptr addrspace(1) %out) {
-; CHECK-LABEL: define amdgpu_kernel void @caller(
+define amdgpu_kernel void @caller_with_aliasing_args(ptr addrspace(1) %out) {
+; CHECK-LABEL: define amdgpu_kernel void @caller_with_aliasing_args(
 ; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) {
 ; CHECK-NEXT:    [[SLOT:%.*]] = alloca i32, align 4, addrspace(5)
 ; CHECK-NEXT:    store i32 1, ptr addrspace(5) [[SLOT]], align 4



More information about the llvm-commits mailing list