1; RUN: llc -march=amdgcn -mcpu=gfx1010 -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,SPLIT %s
2; RUN: llc -march=amdgcn -mcpu=gfx1010 -verify-machineinstrs -mattr=+cumode < %s | FileCheck -check-prefixes=GCN,VECT %s
3
4; GCN-LABEL: test_local_misaligned_v2:
5; GCN-DAG: ds_read2_b32
6; GCN-DAG: ds_write2_b32
7define amdgpu_kernel void @test_local_misaligned_v2(i32 addrspace(3)* %arg) {
8bb:
9  %lid = tail call i32 @llvm.amdgcn.workitem.id.x()
10  %gep = getelementptr inbounds i32, i32 addrspace(3)* %arg, i32 %lid
11  %ptr = bitcast i32 addrspace(3)* %gep to <2 x i32> addrspace(3)*
12  %load = load <2 x i32>, <2 x i32> addrspace(3)* %ptr, align 4
13  %v1 = extractelement <2 x i32> %load, i32 0
14  %v2 = extractelement <2 x i32> %load, i32 1
15  %v3 = insertelement <2 x i32> undef, i32 %v2, i32 0
16  %v4 = insertelement <2 x i32> %v3, i32 %v1, i32 1
17  store <2 x i32> %v4, <2 x i32> addrspace(3)* %ptr, align 4
18  ret void
19}
20
21; GCN-LABEL: test_local_misaligned_v4:
22; GCN-DAG: ds_read2_b32
23; GCN-DAG: ds_read2_b32
24; GCN-DAG: ds_write2_b32
25; GCN-DAG: ds_write2_b32
26define amdgpu_kernel void @test_local_misaligned_v4(i32 addrspace(3)* %arg) {
27bb:
28  %lid = tail call i32 @llvm.amdgcn.workitem.id.x()
29  %gep = getelementptr inbounds i32, i32 addrspace(3)* %arg, i32 %lid
30  %ptr = bitcast i32 addrspace(3)* %gep to <4 x i32> addrspace(3)*
31  %load = load <4 x i32>, <4 x i32> addrspace(3)* %ptr, align 4
32  %v1 = extractelement <4 x i32> %load, i32 0
33  %v2 = extractelement <4 x i32> %load, i32 1
34  %v3 = extractelement <4 x i32> %load, i32 2
35  %v4 = extractelement <4 x i32> %load, i32 3
36  %v5 = insertelement <4 x i32> undef, i32 %v4, i32 0
37  %v6 = insertelement <4 x i32> %v5, i32 %v3, i32 1
38  %v7 = insertelement <4 x i32> %v6, i32 %v2, i32 2
39  %v8 = insertelement <4 x i32> %v7, i32 %v1, i32 3
40  store <4 x i32> %v8, <4 x i32> addrspace(3)* %ptr, align 4
41  ret void
42}
43
44; GCN-LABEL: test_local_misaligned_v3:
45; GCN-DAG: ds_read2_b32
46; GCN-DAG: ds_read_b32
47; GCN-DAG: ds_write2_b32
48; GCN-DAG: ds_write_b32
49define amdgpu_kernel void @test_local_misaligned_v3(i32 addrspace(3)* %arg) {
50bb:
51  %lid = tail call i32 @llvm.amdgcn.workitem.id.x()
52  %gep = getelementptr inbounds i32, i32 addrspace(3)* %arg, i32 %lid
53  %ptr = bitcast i32 addrspace(3)* %gep to <3 x i32> addrspace(3)*
54  %load = load <3 x i32>, <3 x i32> addrspace(3)* %ptr, align 4
55  %v1 = extractelement <3 x i32> %load, i32 0
56  %v2 = extractelement <3 x i32> %load, i32 1
57  %v3 = extractelement <3 x i32> %load, i32 2
58  %v5 = insertelement <3 x i32> undef, i32 %v3, i32 0
59  %v6 = insertelement <3 x i32> %v5, i32 %v1, i32 1
60  %v7 = insertelement <3 x i32> %v6, i32 %v2, i32 2
61  store <3 x i32> %v7, <3 x i32> addrspace(3)* %ptr, align 4
62  ret void
63}
64
65; GCN-LABEL: test_flat_misaligned_v2:
66; VECT-DAG:  flat_load_dwordx2 v
67; VECT-DAG:  flat_store_dwordx2 v
68; SPLIT-DAG: flat_load_dword v
69; SPLIT-DAG: flat_load_dword v
70; SPLIT-DAG: flat_store_dword v
71; SPLIT-DAG: flat_store_dword v
72define amdgpu_kernel void @test_flat_misaligned_v2(i32* %arg) {
73bb:
74  %lid = tail call i32 @llvm.amdgcn.workitem.id.x()
75  %gep = getelementptr inbounds i32, i32* %arg, i32 %lid
76  %ptr = bitcast i32* %gep to <2 x i32>*
77  %load = load <2 x i32>, <2 x i32>* %ptr, align 4
78  %v1 = extractelement <2 x i32> %load, i32 0
79  %v2 = extractelement <2 x i32> %load, i32 1
80  %v3 = insertelement <2 x i32> undef, i32 %v2, i32 0
81  %v4 = insertelement <2 x i32> %v3, i32 %v1, i32 1
82  store <2 x i32> %v4, <2 x i32>* %ptr, align 4
83  ret void
84}
85
86; GCN-LABEL: test_flat_misaligned_v4:
87; VECT-DAG:  flat_load_dwordx4 v
88; VECT-DAG:  flat_store_dwordx4 v
89; SPLIT-DAG: flat_load_dword v
90; SPLIT-DAG: flat_load_dword v
91; SPLIT-DAG: flat_load_dword v
92; SPLIT-DAG: flat_load_dword v
93; SPLIT-DAG: flat_store_dword v
94; SPLIT-DAG: flat_store_dword v
95; SPLIT-DAG: flat_store_dword v
96; SPLIT-DAG: flat_store_dword v
97define amdgpu_kernel void @test_flat_misaligned_v4(i32* %arg) {
98bb:
99  %lid = tail call i32 @llvm.amdgcn.workitem.id.x()
100  %gep = getelementptr inbounds i32, i32* %arg, i32 %lid
101  %ptr = bitcast i32* %gep to <4 x i32>*
102  %load = load <4 x i32>, <4 x i32>* %ptr, align 4
103  %v1 = extractelement <4 x i32> %load, i32 0
104  %v2 = extractelement <4 x i32> %load, i32 1
105  %v3 = extractelement <4 x i32> %load, i32 2
106  %v4 = extractelement <4 x i32> %load, i32 3
107  %v5 = insertelement <4 x i32> undef, i32 %v4, i32 0
108  %v6 = insertelement <4 x i32> %v5, i32 %v3, i32 1
109  %v7 = insertelement <4 x i32> %v6, i32 %v2, i32 2
110  %v8 = insertelement <4 x i32> %v7, i32 %v1, i32 3
111  store <4 x i32> %v8, <4 x i32>* %ptr, align 4
112  ret void
113}
114
115; GCN-LABEL: test_flat_misaligned_v3:
116; VECT-DAG:  flat_load_dwordx3 v
117; VECT-DAG:  flat_store_dwordx3 v
118; SPLIT-DAG: flat_load_dword v
119; SPLIT-DAG: flat_load_dword v
120; SPLIT-DAG: flat_load_dword v
121; SPLIT-DAG: flat_store_dword v
122; SPLIT-DAG: flat_store_dword v
123; SPLIT-DAG: flat_store_dword v
124define amdgpu_kernel void @test_flat_misaligned_v3(i32* %arg) {
125bb:
126  %lid = tail call i32 @llvm.amdgcn.workitem.id.x()
127  %gep = getelementptr inbounds i32, i32* %arg, i32 %lid
128  %ptr = bitcast i32* %gep to <3 x i32>*
129  %load = load <3 x i32>, <3 x i32>* %ptr, align 4
130  %v1 = extractelement <3 x i32> %load, i32 0
131  %v2 = extractelement <3 x i32> %load, i32 1
132  %v3 = extractelement <3 x i32> %load, i32 2
133  %v5 = insertelement <3 x i32> undef, i32 %v3, i32 0
134  %v6 = insertelement <3 x i32> %v5, i32 %v1, i32 1
135  %v7 = insertelement <3 x i32> %v6, i32 %v2, i32 2
136  store <3 x i32> %v7, <3 x i32>* %ptr, align 4
137  ret void
138}
139
140; GCN-LABEL: test_local_aligned_v2:
141; GCN-DAG: ds_read_b64
142; GCN-DAG: ds_write_b64
143define amdgpu_kernel void @test_local_aligned_v2(i32 addrspace(3)* %arg) {
144bb:
145  %lid = tail call i32 @llvm.amdgcn.workitem.id.x()
146  %gep = getelementptr inbounds i32, i32 addrspace(3)* %arg, i32 %lid
147  %ptr = bitcast i32 addrspace(3)* %gep to <2 x i32> addrspace(3)*
148  %load = load <2 x i32>, <2 x i32> addrspace(3)* %ptr, align 8
149  %v1 = extractelement <2 x i32> %load, i32 0
150  %v2 = extractelement <2 x i32> %load, i32 1
151  %v3 = insertelement <2 x i32> undef, i32 %v2, i32 0
152  %v4 = insertelement <2 x i32> %v3, i32 %v1, i32 1
153  store <2 x i32> %v4, <2 x i32> addrspace(3)* %ptr, align 8
154  ret void
155}
156
157; GCN-LABEL: test_local_aligned_v3:
158; GCN-DAG: ds_read_b64
159; GCN-DAG: ds_read_b32
160; GCN-DAG: ds_write_b64
161; GCN-DAG: ds_write_b32
162define amdgpu_kernel void @test_local_aligned_v3(i32 addrspace(3)* %arg) {
163bb:
164  %lid = tail call i32 @llvm.amdgcn.workitem.id.x()
165  %gep = getelementptr inbounds i32, i32 addrspace(3)* %arg, i32 %lid
166  %ptr = bitcast i32 addrspace(3)* %gep to <3 x i32> addrspace(3)*
167  %load = load <3 x i32>, <3 x i32> addrspace(3)* %ptr, align 16
168  %v1 = extractelement <3 x i32> %load, i32 0
169  %v2 = extractelement <3 x i32> %load, i32 1
170  %v3 = extractelement <3 x i32> %load, i32 2
171  %v5 = insertelement <3 x i32> undef, i32 %v3, i32 0
172  %v6 = insertelement <3 x i32> %v5, i32 %v1, i32 1
173  %v7 = insertelement <3 x i32> %v6, i32 %v2, i32 2
174  store <3 x i32> %v7, <3 x i32> addrspace(3)* %ptr, align 16
175  ret void
176}
177
178; GCN-LABEL: test_flat_aligned_v2:
179; GCN-DAG: flat_load_dwordx2 v
180; GCN-DAG: flat_store_dwordx2 v
181define amdgpu_kernel void @test_flat_aligned_v2(i32* %arg) {
182bb:
183  %lid = tail call i32 @llvm.amdgcn.workitem.id.x()
184  %gep = getelementptr inbounds i32, i32* %arg, i32 %lid
185  %ptr = bitcast i32* %gep to <2 x i32>*
186  %load = load <2 x i32>, <2 x i32>* %ptr, align 8
187  %v1 = extractelement <2 x i32> %load, i32 0
188  %v2 = extractelement <2 x i32> %load, i32 1
189  %v3 = insertelement <2 x i32> undef, i32 %v2, i32 0
190  %v4 = insertelement <2 x i32> %v3, i32 %v1, i32 1
191  store <2 x i32> %v4, <2 x i32>* %ptr, align 8
192  ret void
193}
194
195; GCN-LABEL: test_flat_aligned_v4:
196; GCN-DAG: flat_load_dwordx4 v
197; GCN-DAG: flat_store_dwordx4 v
198define amdgpu_kernel void @test_flat_aligned_v4(i32* %arg) {
199bb:
200  %lid = tail call i32 @llvm.amdgcn.workitem.id.x()
201  %gep = getelementptr inbounds i32, i32* %arg, i32 %lid
202  %ptr = bitcast i32* %gep to <4 x i32>*
203  %load = load <4 x i32>, <4 x i32>* %ptr, align 16
204  %v1 = extractelement <4 x i32> %load, i32 0
205  %v2 = extractelement <4 x i32> %load, i32 1
206  %v3 = extractelement <4 x i32> %load, i32 2
207  %v4 = extractelement <4 x i32> %load, i32 3
208  %v5 = insertelement <4 x i32> undef, i32 %v4, i32 0
209  %v6 = insertelement <4 x i32> %v5, i32 %v3, i32 1
210  %v7 = insertelement <4 x i32> %v6, i32 %v2, i32 2
211  %v8 = insertelement <4 x i32> %v7, i32 %v1, i32 3
212  store <4 x i32> %v8, <4 x i32>* %ptr, align 16
213  ret void
214}
215
216; GCN-LABEL: test_local_v4_aligned8:
217; GCN-DAG: ds_read2_b64
218; GCN-DAG: ds_write2_b64
219define amdgpu_kernel void @test_local_v4_aligned8(i32 addrspace(3)* %arg) {
220bb:
221  %lid = tail call i32 @llvm.amdgcn.workitem.id.x()
222  %gep = getelementptr inbounds i32, i32 addrspace(3)* %arg, i32 %lid
223  %ptr = bitcast i32 addrspace(3)* %gep to <4 x i32> addrspace(3)*
224  %load = load <4 x i32>, <4 x i32> addrspace(3)* %ptr, align 8
225  %v1 = extractelement <4 x i32> %load, i32 0
226  %v2 = extractelement <4 x i32> %load, i32 1
227  %v3 = extractelement <4 x i32> %load, i32 2
228  %v4 = extractelement <4 x i32> %load, i32 3
229  %v5 = insertelement <4 x i32> undef, i32 %v4, i32 0
230  %v6 = insertelement <4 x i32> %v5, i32 %v3, i32 1
231  %v7 = insertelement <4 x i32> %v6, i32 %v2, i32 2
232  %v8 = insertelement <4 x i32> %v7, i32 %v1, i32 3
233  store <4 x i32> %v8, <4 x i32> addrspace(3)* %ptr, align 8
234  ret void
235}
236
237; GCN-LABEL: test_flat_v4_aligned8:
238; VECT-DAG:  flat_load_dwordx4 v
239; VECT-DAG:  flat_store_dwordx4 v
240; SPLIT-DAG: flat_load_dwordx2 v
241; SPLIT-DAG: flat_load_dwordx2 v
242; SPLIT-DAG: flat_store_dwordx2 v
243; SPLIT-DAG: flat_store_dwordx2 v
244define amdgpu_kernel void @test_flat_v4_aligned8(i32* %arg) {
245bb:
246  %lid = tail call i32 @llvm.amdgcn.workitem.id.x()
247  %gep = getelementptr inbounds i32, i32* %arg, i32 %lid
248  %ptr = bitcast i32* %gep to <4 x i32>*
249  %load = load <4 x i32>, <4 x i32>* %ptr, align 8
250  %v1 = extractelement <4 x i32> %load, i32 0
251  %v2 = extractelement <4 x i32> %load, i32 1
252  %v3 = extractelement <4 x i32> %load, i32 2
253  %v4 = extractelement <4 x i32> %load, i32 3
254  %v5 = insertelement <4 x i32> undef, i32 %v4, i32 0
255  %v6 = insertelement <4 x i32> %v5, i32 %v3, i32 1
256  %v7 = insertelement <4 x i32> %v6, i32 %v2, i32 2
257  %v8 = insertelement <4 x i32> %v7, i32 %v1, i32 3
258  store <4 x i32> %v8, <4 x i32>* %ptr, align 8
259  ret void
260}
261
262declare i32 @llvm.amdgcn.workitem.id.x()
263