xref: /llvm-project/llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomicrmw-integer-ops-0-to-add-0.ll (revision 30dd1297fa2cc172ef7a1435775010d7efd673fd)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 4
2; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=atomic-expand -mcpu=gfx803 %s | FileCheck -check-prefixes=CHECK,GFX803 %s
3; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=atomic-expand -mcpu=gfx900 %s | FileCheck -check-prefixes=CHECK,GFX900 %s
4; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=atomic-expand -mcpu=gfx90a %s | FileCheck -check-prefixes=CHECK,GFX90A %s
5; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=atomic-expand -mcpu=gfx1030 %s | FileCheck -check-prefixes=CHECK,GFX10 %s
6; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=atomic-expand -mcpu=gfx1100 %s | FileCheck -check-prefixes=CHECK,GFX11 %s
7; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=atomic-expand -mcpu=gfx940 %s | FileCheck -check-prefixes=CHECK,GFX940 %s
8; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=atomic-expand -mcpu=gfx1200 %s | FileCheck -check-prefixes=CHECK,GFX12 %s
9
10; Test that system scoped atomicrmw or 0 is transformed to add 0.
11
12; Transform to add
13define i32 @test_atomicrmw_or_0_global_system(ptr addrspace(1) %ptr) {
14; CHECK-LABEL: define i32 @test_atomicrmw_or_0_global_system(
15; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0:[0-9]+]] {
16; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr addrspace(1) [[PTR]], i32 0 seq_cst, align 4, !foo.md [[META0:![0-9]+]]
17; CHECK-NEXT:    ret i32 [[RES]]
18;
19  %res = atomicrmw or ptr addrspace(1) %ptr, i32 0 seq_cst, !foo.md !0
20  ret i32 %res
21}
22
23; Transform to add
24define i32 @test_atomicrmw_or_0_global_one_as(ptr addrspace(1) %ptr) {
25; CHECK-LABEL: define i32 @test_atomicrmw_or_0_global_one_as(
26; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
27; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr addrspace(1) [[PTR]], i32 0 syncscope("one-as") seq_cst, align 4
28; CHECK-NEXT:    ret i32 [[RES]]
29;
30  %res = atomicrmw or ptr addrspace(1) %ptr, i32 0 syncscope("one-as") seq_cst
31  ret i32 %res
32}
33
34; Transform to add
35define i32 @test_atomicrmw_or_0_flat_system(ptr %ptr) {
36; CHECK-LABEL: define i32 @test_atomicrmw_or_0_flat_system(
37; CHECK-SAME: ptr [[PTR:%.*]]) #[[ATTR0]] {
38; CHECK-NEXT:    [[IS_PRIVATE:%.*]] = call i1 @llvm.amdgcn.is.private(ptr [[PTR]])
39; CHECK-NEXT:    br i1 [[IS_PRIVATE]], label [[ATOMICRMW_PRIVATE:%.*]], label [[ATOMICRMW_GLOBAL:%.*]]
40; CHECK:       atomicrmw.private:
41; CHECK-NEXT:    [[TMP1:%.*]] = addrspacecast ptr [[PTR]] to ptr addrspace(5)
42; CHECK-NEXT:    [[LOADED_PRIVATE:%.*]] = load i32, ptr addrspace(5) [[TMP1]], align 4
43; CHECK-NEXT:    [[NEW:%.*]] = add i32 [[LOADED_PRIVATE]], 0
44; CHECK-NEXT:    store i32 [[NEW]], ptr addrspace(5) [[TMP1]], align 4
45; CHECK-NEXT:    br label [[ATOMICRMW_PHI:%.*]]
46; CHECK:       atomicrmw.global:
47; CHECK-NEXT:    [[TMP2:%.*]] = atomicrmw add ptr [[PTR]], i32 0 seq_cst, align 4, !noalias.addrspace [[META1:![0-9]+]]
48; CHECK-NEXT:    br label [[ATOMICRMW_PHI]]
49; CHECK:       atomicrmw.phi:
50; CHECK-NEXT:    [[RES1:%.*]] = phi i32 [ [[LOADED_PRIVATE]], [[ATOMICRMW_PRIVATE]] ], [ [[TMP2]], [[ATOMICRMW_GLOBAL]] ]
51; CHECK-NEXT:    br label [[ATOMICRMW_END:%.*]]
52; CHECK:       atomicrmw.end:
53; CHECK-NEXT:    ret i32 [[RES1]]
54;
55  %res = atomicrmw or ptr %ptr, i32 0 seq_cst
56  ret i32 %res
57}
58
59; Transform to add
60define i32 @test_atomicrmw_or_0_as999_system(ptr addrspace(999) %ptr) {
61; CHECK-LABEL: define i32 @test_atomicrmw_or_0_as999_system(
62; CHECK-SAME: ptr addrspace(999) [[PTR:%.*]]) #[[ATTR0]] {
63; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr addrspace(999) [[PTR]], i32 0 seq_cst, align 4
64; CHECK-NEXT:    ret i32 [[RES]]
65;
66  %res = atomicrmw or ptr addrspace(999) %ptr, i32 0 seq_cst
67  ret i32 %res
68}
69
70; Leave as-is, only system scope should be changed.
71define i32 @test_atomicrmw_or_0_global_agent(ptr addrspace(1) %ptr) {
72; CHECK-LABEL: define i32 @test_atomicrmw_or_0_global_agent(
73; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
74; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr addrspace(1) [[PTR]], i32 0 syncscope("agent") seq_cst, align 4
75; CHECK-NEXT:    ret i32 [[RES]]
76;
77  %res = atomicrmw or ptr addrspace(1) %ptr, i32 0 syncscope("agent") seq_cst
78  ret i32 %res
79}
80
81; Leave as-is, LDS atomics aren't relevant.
82define i32 @test_atomicrmw_or_0_local(ptr addrspace(3) %ptr) {
83; CHECK-LABEL: define i32 @test_atomicrmw_or_0_local(
84; CHECK-SAME: ptr addrspace(3) [[PTR:%.*]]) #[[ATTR0]] {
85; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr addrspace(3) [[PTR]], i32 0 seq_cst, align 4
86; CHECK-NEXT:    ret i32 [[RES]]
87;
88  %res = atomicrmw or ptr addrspace(3) %ptr, i32 0 seq_cst
89  ret i32 %res
90}
91
92; Leave non-0 values alone.
93define i32 @test_atomicrmw_or_1_global_system(ptr addrspace(1) %ptr) {
94; CHECK-LABEL: define i32 @test_atomicrmw_or_1_global_system(
95; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
96; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr addrspace(1) [[PTR]], i32 1 seq_cst, align 4
97; CHECK-NEXT:    ret i32 [[RES]]
98;
99  %res = atomicrmw or ptr addrspace(1) %ptr, i32 1 seq_cst
100  ret i32 %res
101}
102
103define i32 @test_atomicrmw_or_var_global_system(ptr addrspace(1) %ptr, i32 %val) {
104; CHECK-LABEL: define i32 @test_atomicrmw_or_var_global_system(
105; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] {
106; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr addrspace(1) [[PTR]], i32 [[VAL]] seq_cst, align 4
107; CHECK-NEXT:    ret i32 [[RES]]
108;
109  %res = atomicrmw or ptr addrspace(1) %ptr, i32 %val seq_cst
110  ret i32 %res
111}
112
113; Leave as-is
114define i32 @test_atomicrmw_add_0_global_system(ptr addrspace(1) %ptr) {
115; CHECK-LABEL: define i32 @test_atomicrmw_add_0_global_system(
116; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
117; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr addrspace(1) [[PTR]], i32 0 seq_cst, align 4
118; CHECK-NEXT:    ret i32 [[RES]]
119;
120  %res = atomicrmw add ptr addrspace(1) %ptr, i32 0 seq_cst
121  ret i32 %res
122}
123
124; Transform to add
125define i32 @test_atomicrmw_sub_0_global_system(ptr addrspace(1) %ptr) {
126; CHECK-LABEL: define i32 @test_atomicrmw_sub_0_global_system(
127; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
128; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr addrspace(1) [[PTR]], i32 0 seq_cst, align 4, !foo.md [[META0]]
129; CHECK-NEXT:    ret i32 [[RES]]
130;
131  %res = atomicrmw sub ptr addrspace(1) %ptr, i32 0 seq_cst, !foo.md !0
132  ret i32 %res
133}
134
135; Transform to add
136define i32 @test_atomicrmw_xor_0_global_system(ptr addrspace(1) %ptr) {
137; CHECK-LABEL: define i32 @test_atomicrmw_xor_0_global_system(
138; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
139; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr addrspace(1) [[PTR]], i32 0 seq_cst, align 4, !foo.md [[META0]]
140; CHECK-NEXT:    ret i32 [[RES]]
141;
142  %res = atomicrmw xor ptr addrspace(1) %ptr, i32 0 seq_cst, !foo.md !0
143  ret i32 %res
144}
145
146define i32 @test_atomicrmw_or_0_global_system__amdgpu_no_fine_grained_memory(ptr addrspace(1) %ptr) {
147; CHECK-LABEL: define i32 @test_atomicrmw_or_0_global_system__amdgpu_no_fine_grained_memory(
148; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
149; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr addrspace(1) [[PTR]], i32 0 seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META0]]
150; CHECK-NEXT:    ret i32 [[RES]]
151;
152  %res = atomicrmw or ptr addrspace(1) %ptr, i32 0 seq_cst, !amdgpu.no.fine.grained.memory !0
153  ret i32 %res
154}
155
156define i32 @test_atomicrmw_or_0_global_system__amdgpu_no_remote_memory(ptr addrspace(1) %ptr) {
157; CHECK-LABEL: define i32 @test_atomicrmw_or_0_global_system__amdgpu_no_remote_memory(
158; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
159; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr addrspace(1) [[PTR]], i32 0 seq_cst, align 4, !amdgpu.no.remote.memory [[META0]]
160; CHECK-NEXT:    ret i32 [[RES]]
161;
162  %res = atomicrmw or ptr addrspace(1) %ptr, i32 0 seq_cst, !amdgpu.no.remote.memory !0
163  ret i32 %res
164}
165
166define i32 @test_atomicrmw_or_0_global_system__amdgpu_no_fine_grained_memory__amdgpu_no_remote_memory(ptr addrspace(1) %ptr) {
167; CHECK-LABEL: define i32 @test_atomicrmw_or_0_global_system__amdgpu_no_fine_grained_memory__amdgpu_no_remote_memory(
168; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
169; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr addrspace(1) [[PTR]], i32 0 seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META0]], !amdgpu.no.remote.memory [[META0]]
170; CHECK-NEXT:    ret i32 [[RES]]
171;
172  %res = atomicrmw or ptr addrspace(1) %ptr, i32 0 seq_cst, !amdgpu.no.fine.grained.memory !0, !amdgpu.no.remote.memory !0
173  ret i32 %res
174}
175
176define i32 @test_atomicrmw_xor_0_global_system__amdgpu_no_fine_grained_memory(ptr addrspace(1) %ptr) {
177; CHECK-LABEL: define i32 @test_atomicrmw_xor_0_global_system__amdgpu_no_fine_grained_memory(
178; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
179; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr addrspace(1) [[PTR]], i32 0 seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META0]]
180; CHECK-NEXT:    ret i32 [[RES]]
181;
182  %res = atomicrmw xor ptr addrspace(1) %ptr, i32 0 seq_cst, !amdgpu.no.fine.grained.memory !0
183  ret i32 %res
184}
185
186define i32 @test_atomicrmw_xor_0_global_system__amdgpu_no_remote_memory(ptr addrspace(1) %ptr) {
187; CHECK-LABEL: define i32 @test_atomicrmw_xor_0_global_system__amdgpu_no_remote_memory(
188; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
189; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr addrspace(1) [[PTR]], i32 0 seq_cst, align 4, !amdgpu.no.remote.memory [[META0]]
190; CHECK-NEXT:    ret i32 [[RES]]
191;
192  %res = atomicrmw xor ptr addrspace(1) %ptr, i32 0 seq_cst, !amdgpu.no.remote.memory !0
193  ret i32 %res
194}
195
196define i32 @test_atomicrmw_xor_0_global_system__amdgpu_no_fine_grained_memory__amdgpu_no_remote_memory(ptr addrspace(1) %ptr) {
197; CHECK-LABEL: define i32 @test_atomicrmw_xor_0_global_system__amdgpu_no_fine_grained_memory__amdgpu_no_remote_memory(
198; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
199; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr addrspace(1) [[PTR]], i32 0 seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META0]], !amdgpu.no.remote.memory [[META0]]
200; CHECK-NEXT:    ret i32 [[RES]]
201;
202  %res = atomicrmw xor ptr addrspace(1) %ptr, i32 0 seq_cst, !amdgpu.no.fine.grained.memory !0, !amdgpu.no.remote.memory !0
203  ret i32 %res
204}
205
206define i32 @test_atomicrmw_sub_0_global_system__amdgpu_no_fine_grained_memory(ptr addrspace(1) %ptr) {
207; CHECK-LABEL: define i32 @test_atomicrmw_sub_0_global_system__amdgpu_no_fine_grained_memory(
208; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
209; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr addrspace(1) [[PTR]], i32 0 seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META0]]
210; CHECK-NEXT:    ret i32 [[RES]]
211;
212  %res = atomicrmw sub ptr addrspace(1) %ptr, i32 0 seq_cst, !amdgpu.no.fine.grained.memory !0
213  ret i32 %res
214}
215
216define i32 @test_atomicrmw_sub_0_global_system__amdgpu_no_remote_memory(ptr addrspace(1) %ptr) {
217; CHECK-LABEL: define i32 @test_atomicrmw_sub_0_global_system__amdgpu_no_remote_memory(
218; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
219; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr addrspace(1) [[PTR]], i32 0 seq_cst, align 4, !amdgpu.no.remote.memory [[META0]]
220; CHECK-NEXT:    ret i32 [[RES]]
221;
222  %res = atomicrmw sub ptr addrspace(1) %ptr, i32 0 seq_cst, !amdgpu.no.remote.memory !0
223  ret i32 %res
224}
225
226define i32 @test_atomicrmw_sub_0_global_system__amdgpu_no_fine_grained_memory__amdgpu_no_remote_memory(ptr addrspace(1) %ptr) {
227; CHECK-LABEL: define i32 @test_atomicrmw_sub_0_global_system__amdgpu_no_fine_grained_memory__amdgpu_no_remote_memory(
228; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
229; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr addrspace(1) [[PTR]], i32 0 seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META0]], !amdgpu.no.remote.memory [[META0]]
230; CHECK-NEXT:    ret i32 [[RES]]
231;
232  %res = atomicrmw sub ptr addrspace(1) %ptr, i32 0 seq_cst, !amdgpu.no.fine.grained.memory !0, !amdgpu.no.remote.memory !0
233  ret i32 %res
234}
235
236define i32 @test_atomicrmw_or_0_global_agent__amdgpu_no_fine_grained_memory(ptr addrspace(1) %ptr) {
237; CHECK-LABEL: define i32 @test_atomicrmw_or_0_global_agent__amdgpu_no_fine_grained_memory(
238; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
239; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr addrspace(1) [[PTR]], i32 0 syncscope("agent") seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META0]]
240; CHECK-NEXT:    ret i32 [[RES]]
241;
242  %res = atomicrmw or ptr addrspace(1) %ptr, i32 0 syncscope("agent") seq_cst, !amdgpu.no.fine.grained.memory !0
243  ret i32 %res
244}
245
246define i32 @test_atomicrmw_or_0_global_agent__amdgpu_no_remote_memory(ptr addrspace(1) %ptr) {
247; CHECK-LABEL: define i32 @test_atomicrmw_or_0_global_agent__amdgpu_no_remote_memory(
248; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
249; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr addrspace(1) [[PTR]], i32 0 syncscope("agent") seq_cst, align 4, !amdgpu.no.remote.memory [[META0]]
250; CHECK-NEXT:    ret i32 [[RES]]
251;
252  %res = atomicrmw or ptr addrspace(1) %ptr, i32 0 syncscope("agent") seq_cst, !amdgpu.no.remote.memory !0
253  ret i32 %res
254}
255
256define i32 @test_atomicrmw_or_0_global_agent__amdgpu_no_fine_grained_memory__amdgpu_no_remote_memory(ptr addrspace(1) %ptr) {
257; CHECK-LABEL: define i32 @test_atomicrmw_or_0_global_agent__amdgpu_no_fine_grained_memory__amdgpu_no_remote_memory(
258; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
259; CHECK-NEXT:    [[RES:%.*]] = atomicrmw or ptr addrspace(1) [[PTR]], i32 0 syncscope("agent") seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META0]], !amdgpu.no.remote.memory [[META0]]
260; CHECK-NEXT:    ret i32 [[RES]]
261;
262  %res = atomicrmw or ptr addrspace(1) %ptr, i32 0 syncscope("agent") seq_cst, !amdgpu.no.fine.grained.memory !0, !amdgpu.no.remote.memory !0
263  ret i32 %res
264}
265
266define i32 @test_atomicrmw_xor_0_global_agent__amdgpu_no_fine_grained_memory(ptr addrspace(1) %ptr) {
267; CHECK-LABEL: define i32 @test_atomicrmw_xor_0_global_agent__amdgpu_no_fine_grained_memory(
268; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
269; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xor ptr addrspace(1) [[PTR]], i32 0 syncscope("agent") seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META0]]
270; CHECK-NEXT:    ret i32 [[RES]]
271;
272  %res = atomicrmw xor ptr addrspace(1) %ptr, i32 0 syncscope("agent") seq_cst, !amdgpu.no.fine.grained.memory !0
273  ret i32 %res
274}
275
276define i32 @test_atomicrmw_xor_0_global_agent__amdgpu_no_remote_memory(ptr addrspace(1) %ptr) {
277; CHECK-LABEL: define i32 @test_atomicrmw_xor_0_global_agent__amdgpu_no_remote_memory(
278; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
279; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xor ptr addrspace(1) [[PTR]], i32 0 syncscope("agent") seq_cst, align 4, !amdgpu.no.remote.memory [[META0]]
280; CHECK-NEXT:    ret i32 [[RES]]
281;
282  %res = atomicrmw xor ptr addrspace(1) %ptr, i32 0 syncscope("agent") seq_cst, !amdgpu.no.remote.memory !0
283  ret i32 %res
284}
285
286define i32 @test_atomicrmw_xor_0_global_agent__amdgpu_no_fine_grained_memory__amdgpu_no_remote_memory(ptr addrspace(1) %ptr) {
287; CHECK-LABEL: define i32 @test_atomicrmw_xor_0_global_agent__amdgpu_no_fine_grained_memory__amdgpu_no_remote_memory(
288; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
289; CHECK-NEXT:    [[RES:%.*]] = atomicrmw xor ptr addrspace(1) [[PTR]], i32 0 syncscope("agent") seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META0]], !amdgpu.no.remote.memory [[META0]]
290; CHECK-NEXT:    ret i32 [[RES]]
291;
292  %res = atomicrmw xor ptr addrspace(1) %ptr, i32 0 syncscope("agent") seq_cst, !amdgpu.no.fine.grained.memory !0, !amdgpu.no.remote.memory !0
293  ret i32 %res
294}
295
296define i32 @test_atomicrmw_sub_0_global_agent__amdgpu_no_fine_grained_memory(ptr addrspace(1) %ptr) {
297; CHECK-LABEL: define i32 @test_atomicrmw_sub_0_global_agent__amdgpu_no_fine_grained_memory(
298; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
299; CHECK-NEXT:    [[RES:%.*]] = atomicrmw sub ptr addrspace(1) [[PTR]], i32 0 syncscope("agent") seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META0]]
300; CHECK-NEXT:    ret i32 [[RES]]
301;
302  %res = atomicrmw sub ptr addrspace(1) %ptr, i32 0 syncscope("agent") seq_cst, !amdgpu.no.fine.grained.memory !0
303  ret i32 %res
304}
305
306define i32 @test_atomicrmw_sub_0_global_agent__amdgpu_no_remote_memory(ptr addrspace(1) %ptr) {
307; CHECK-LABEL: define i32 @test_atomicrmw_sub_0_global_agent__amdgpu_no_remote_memory(
308; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
309; CHECK-NEXT:    [[RES:%.*]] = atomicrmw sub ptr addrspace(1) [[PTR]], i32 0 syncscope("agent") seq_cst, align 4, !amdgpu.no.remote.memory [[META0]]
310; CHECK-NEXT:    ret i32 [[RES]]
311;
312  %res = atomicrmw sub ptr addrspace(1) %ptr, i32 0 syncscope("agent") seq_cst, !amdgpu.no.remote.memory !0
313  ret i32 %res
314}
315
316define i32 @test_atomicrmw_sub_0_global_agent__amdgpu_no_fine_grained_memory__amdgpu_no_remote_memory(ptr addrspace(1) %ptr) {
317; CHECK-LABEL: define i32 @test_atomicrmw_sub_0_global_agent__amdgpu_no_fine_grained_memory__amdgpu_no_remote_memory(
318; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] {
319; CHECK-NEXT:    [[RES:%.*]] = atomicrmw sub ptr addrspace(1) [[PTR]], i32 0 syncscope("agent") seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META0]], !amdgpu.no.remote.memory [[META0]]
320; CHECK-NEXT:    ret i32 [[RES]]
321;
322  %res = atomicrmw sub ptr addrspace(1) %ptr, i32 0 syncscope("agent") seq_cst, !amdgpu.no.fine.grained.memory !0, !amdgpu.no.remote.memory !0
323  ret i32 %res
324}
325
326!0 = !{}
327
328;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
329; GFX10: {{.*}}
330; GFX11: {{.*}}
331; GFX12: {{.*}}
332; GFX803: {{.*}}
333; GFX900: {{.*}}
334; GFX90A: {{.*}}
335; GFX940: {{.*}}
336