xref: /llvm-project/llvm/test/Transforms/InferAddressSpaces/AMDGPU/store-pointer-to-self.ll (revision 29441e4f5fa5f5c7709f7cf180815ba97f611297)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=infer-address-spaces %s | FileCheck %s
3
4; Make sure memory instructions where the pointer appears in both a
5; pointer and value operand work correctly.
6
7declare void @user(ptr)
8
9; Make sure only the pointer operand use of the store is replaced
10define void @store_flat_pointer_to_self() {
11; CHECK-LABEL: define void @store_flat_pointer_to_self() {
12; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5)
13; CHECK-NEXT:    [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr
14; CHECK-NEXT:    store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8
15; CHECK-NEXT:    call void @user(ptr [[FLAT]])
16; CHECK-NEXT:    ret void
17;
18  %alloca = alloca ptr, align 8, addrspace(5)
19  %flat = addrspacecast ptr addrspace(5) %alloca to ptr
20  store ptr %flat, ptr %flat, align 8
21  call void @user(ptr %flat)
22  ret void
23}
24
25define void @store_volatile_flat_pointer_to_self() {
26; CHECK-LABEL: define void @store_volatile_flat_pointer_to_self() {
27; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5)
28; CHECK-NEXT:    [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr
29; CHECK-NEXT:    store volatile ptr [[FLAT]], ptr [[FLAT]], align 8
30; CHECK-NEXT:    call void @user(ptr [[FLAT]])
31; CHECK-NEXT:    ret void
32;
33  %alloca = alloca ptr, align 8, addrspace(5)
34  %flat = addrspacecast ptr addrspace(5) %alloca to ptr
35  store volatile ptr %flat, ptr %flat, align 8
36  call void @user(ptr %flat)
37  ret void
38}
39
40define ptr @atomicrmw_xchg_flat_pointer_to_self() {
41; CHECK-LABEL: define ptr @atomicrmw_xchg_flat_pointer_to_self() {
42; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5)
43; CHECK-NEXT:    [[FLAT1:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr
44; CHECK-NEXT:    [[XCHG:%.*]] = atomicrmw xchg ptr addrspace(5) [[ALLOCA]], ptr [[FLAT1]] seq_cst, align 8
45; CHECK-NEXT:    call void @user(ptr [[FLAT1]])
46; CHECK-NEXT:    ret ptr [[XCHG]]
47;
48  %alloca = alloca ptr, align 8, addrspace(5)
49  %flat = addrspacecast ptr addrspace(5) %alloca to ptr
50  %xchg = atomicrmw xchg ptr %flat, ptr %flat seq_cst, align 8
51  call void @user(ptr %flat)
52  ret ptr %xchg
53}
54
55define ptr @atomicrmw_volatile_xchg_flat_pointer_to_self() {
56; CHECK-LABEL: define ptr @atomicrmw_volatile_xchg_flat_pointer_to_self() {
57; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5)
58; CHECK-NEXT:    [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr
59; CHECK-NEXT:    [[XCHG:%.*]] = atomicrmw volatile xchg ptr [[FLAT]], ptr [[FLAT]] seq_cst, align 8
60; CHECK-NEXT:    call void @user(ptr [[FLAT]])
61; CHECK-NEXT:    ret ptr [[XCHG]]
62;
63  %alloca = alloca ptr, align 8, addrspace(5)
64  %flat = addrspacecast ptr addrspace(5) %alloca to ptr
65  %xchg = atomicrmw volatile xchg ptr %flat, ptr %flat seq_cst, align 8
66  call void @user(ptr %flat)
67  ret ptr %xchg
68}
69
70define { ptr, i1 } @cmpxchg_flat_pointer_new_to_self(ptr %cmp) {
71; CHECK-LABEL: define { ptr, i1 } @cmpxchg_flat_pointer_new_to_self(
72; CHECK-SAME: ptr [[CMP:%.*]]) {
73; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5)
74; CHECK-NEXT:    [[FLAT1:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr
75; CHECK-NEXT:    [[CMPX:%.*]] = cmpxchg ptr addrspace(5) [[ALLOCA]], ptr [[CMP]], ptr [[FLAT1]] seq_cst seq_cst, align 8
76; CHECK-NEXT:    call void @user(ptr [[FLAT1]])
77; CHECK-NEXT:    ret { ptr, i1 } [[CMPX]]
78;
79  %alloca = alloca ptr, align 8, addrspace(5)
80  %flat = addrspacecast ptr addrspace(5) %alloca to ptr
81  %cmpx = cmpxchg ptr %flat, ptr %cmp, ptr %flat seq_cst seq_cst, align 8
82  call void @user(ptr %flat)
83  ret { ptr, i1 } %cmpx
84}
85
86define { ptr, i1 } @cmpxchg_volatile_flat_pointer_new_to_self(ptr %cmp) {
87; CHECK-LABEL: define { ptr, i1 } @cmpxchg_volatile_flat_pointer_new_to_self(
88; CHECK-SAME: ptr [[CMP:%.*]]) {
89; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5)
90; CHECK-NEXT:    [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr
91; CHECK-NEXT:    [[CMPX:%.*]] = cmpxchg volatile ptr [[FLAT]], ptr [[CMP]], ptr [[FLAT]] seq_cst seq_cst, align 8
92; CHECK-NEXT:    call void @user(ptr [[FLAT]])
93; CHECK-NEXT:    ret { ptr, i1 } [[CMPX]]
94;
95  %alloca = alloca ptr, align 8, addrspace(5)
96  %flat = addrspacecast ptr addrspace(5) %alloca to ptr
97  %cmpx = cmpxchg volatile ptr %flat, ptr %cmp, ptr %flat seq_cst seq_cst, align 8
98  call void @user(ptr %flat)
99  ret { ptr, i1 } %cmpx
100}
101
102define { ptr, i1 } @volatile_cmpxchg_flat_pointer_new_to_self(ptr %cmp) {
103; CHECK-LABEL: define { ptr, i1 } @volatile_cmpxchg_flat_pointer_new_to_self(
104; CHECK-SAME: ptr [[CMP:%.*]]) {
105; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5)
106; CHECK-NEXT:    [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr
107; CHECK-NEXT:    [[CMPX:%.*]] = cmpxchg volatile ptr [[FLAT]], ptr [[CMP]], ptr [[FLAT]] seq_cst seq_cst, align 8
108; CHECK-NEXT:    call void @user(ptr [[FLAT]])
109; CHECK-NEXT:    ret { ptr, i1 } [[CMPX]]
110;
111  %alloca = alloca ptr, align 8, addrspace(5)
112  %flat = addrspacecast ptr addrspace(5) %alloca to ptr
113  %cmpx = cmpxchg volatile ptr %flat, ptr %cmp, ptr %flat seq_cst seq_cst, align 8
114  call void @user(ptr %flat)
115  ret { ptr, i1 } %cmpx
116}
117
118define { ptr, i1 } @cmpxchg_flat_pointer_cmp_to_self(ptr %new) {
119; CHECK-LABEL: define { ptr, i1 } @cmpxchg_flat_pointer_cmp_to_self(
120; CHECK-SAME: ptr [[NEW:%.*]]) {
121; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5)
122; CHECK-NEXT:    [[FLAT1:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr
123; CHECK-NEXT:    [[CMPX:%.*]] = cmpxchg ptr addrspace(5) [[ALLOCA]], ptr [[FLAT1]], ptr [[NEW]] seq_cst seq_cst, align 8
124; CHECK-NEXT:    call void @user(ptr [[FLAT1]])
125; CHECK-NEXT:    ret { ptr, i1 } [[CMPX]]
126;
127  %alloca = alloca ptr, align 8, addrspace(5)
128  %flat = addrspacecast ptr addrspace(5) %alloca to ptr
129  %cmpx = cmpxchg ptr %flat, ptr %flat, ptr %new seq_cst seq_cst, align 8
130  call void @user(ptr %flat)
131  ret { ptr, i1 } %cmpx
132}
133
134define { ptr, i1 } @cmpxchg_flat_pointer_cmp_new_self() {
135; CHECK-LABEL: define { ptr, i1 } @cmpxchg_flat_pointer_cmp_new_self() {
136; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5)
137; CHECK-NEXT:    [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr
138; CHECK-NEXT:    [[CMPX:%.*]] = cmpxchg ptr addrspace(5) [[ALLOCA]], ptr [[FLAT]], ptr [[FLAT]] seq_cst seq_cst, align 8
139; CHECK-NEXT:    call void @user(ptr [[FLAT]])
140; CHECK-NEXT:    ret { ptr, i1 } [[CMPX]]
141;
142  %alloca = alloca ptr, align 8, addrspace(5)
143  %flat = addrspacecast ptr addrspace(5) %alloca to ptr
144  %cmpx = cmpxchg ptr %flat, ptr %flat, ptr %flat seq_cst seq_cst, align 8
145  call void @user(ptr %flat)
146  ret { ptr, i1 } %cmpx
147}
148
149define void @multi_store_flat_pointer_to_self() {
150; CHECK-LABEL: define void @multi_store_flat_pointer_to_self() {
151; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5)
152; CHECK-NEXT:    [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr
153; CHECK-NEXT:    store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8
154; CHECK-NEXT:    store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8
155; CHECK-NEXT:    call void @user(ptr [[FLAT]])
156; CHECK-NEXT:    store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8
157; CHECK-NEXT:    store ptr addrspace(5) [[ALLOCA]], ptr addrspace(5) [[ALLOCA]], align 8
158; CHECK-NEXT:    ret void
159;
160  %alloca = alloca ptr, align 8, addrspace(5)
161  %flat = addrspacecast ptr addrspace(5) %alloca to ptr
162  store ptr %flat, ptr %flat, align 8
163  store ptr %flat, ptr %flat, align 8
164  call void @user(ptr %flat)
165  store ptr %flat, ptr addrspace(5) %alloca, align 8
166  store ptr addrspace(5) %alloca, ptr %flat, align 8
167  ret void
168}
169
170define void @mixed_volatile_multi_store_flat_pointer_to_self() {
171; CHECK-LABEL: define void @mixed_volatile_multi_store_flat_pointer_to_self() {
172; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca ptr, align 8, addrspace(5)
173; CHECK-NEXT:    [[FLAT:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr
174; CHECK-NEXT:    store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8
175; CHECK-NEXT:    store volatile ptr [[FLAT]], ptr [[FLAT]], align 8
176; CHECK-NEXT:    store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8
177; CHECK-NEXT:    call void @user(ptr [[FLAT]])
178; CHECK-NEXT:    store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8
179; CHECK-NEXT:    store ptr addrspace(5) [[ALLOCA]], ptr addrspace(5) [[ALLOCA]], align 8
180; CHECK-NEXT:    store volatile ptr [[FLAT]], ptr [[FLAT]], align 8
181; CHECK-NEXT:    store ptr [[FLAT]], ptr addrspace(5) [[ALLOCA]], align 8
182; CHECK-NEXT:    ret void
183;
184  %alloca = alloca ptr, align 8, addrspace(5)
185  %flat = addrspacecast ptr addrspace(5) %alloca to ptr
186  store ptr %flat, ptr %flat, align 8
187  store volatile ptr %flat, ptr %flat, align 8
188  store ptr %flat, ptr %flat, align 8
189  call void @user(ptr %flat)
190  store ptr %flat, ptr addrspace(5) %alloca, align 8
191  store ptr addrspace(5) %alloca, ptr %flat, align 8
192  store volatile ptr %flat, ptr %flat, align 8
193  store ptr %flat, ptr %flat, align 8
194  ret void
195}
196
197define amdgpu_kernel void @uselist_regression_skipped_load(ptr nocapture readonly %Arg, i32 %i) {
198; CHECK-LABEL: define amdgpu_kernel void @uselist_regression_skipped_load(
199; CHECK-SAME: ptr readonly captures(none) [[ARG:%.*]], i32 [[I:%.*]]) {
200; CHECK-NEXT:  [[ENTRY:.*:]]
201; CHECK-NEXT:    [[ARG_GLOBAL:%.*]] = addrspacecast ptr [[ARG]] to ptr addrspace(1)
202; CHECK-NEXT:    [[P1:%.*]] = getelementptr inbounds ptr, ptr addrspace(1) [[ARG_GLOBAL]], i32 [[I]]
203; CHECK-NEXT:    [[TMP0:%.*]] = addrspacecast ptr addrspace(1) [[P1]] to ptr
204; CHECK-NEXT:    [[P2:%.*]] = load volatile ptr, ptr [[TMP0]], align 8
205; CHECK-NEXT:    [[P2_GLOBAL:%.*]] = addrspacecast ptr [[P2]] to ptr addrspace(1)
206; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(1) [[P2_GLOBAL]], align 4
207; CHECK-NEXT:    ret void
208;
209entry:
210  %Arg.global = addrspacecast ptr %Arg to ptr addrspace(1)
211  %Arg.flat = addrspacecast ptr addrspace(1) %Arg.global to ptr
212  %p1 = getelementptr inbounds ptr, ptr %Arg.flat, i32 %i
213  %p2 = load volatile ptr, ptr %p1, align 8
214  %p2.global = addrspacecast ptr %p2 to ptr addrspace(1)
215  %p2.flat = addrspacecast ptr addrspace(1) %p2.global to ptr
216  store float 0.000000e+00, ptr %p2.flat, align 4
217  ret void
218}
219