[PowerPC] Generate Power9 extswsli extend sign and shift immediate instruction
[llvm-core.git] / test / CodeGen / AMDGPU / merge-stores.ll
blob2b2f67cd1b3d59cb1829fe515eda1cfbbde27aa0
1 ; RUN: llc -amdgpu-scalarize-global-loads=false -march=amdgcn -mcpu=tahiti -verify-machineinstrs -amdgpu-load-store-vectorizer=0 < %s | FileCheck -check-prefix=SI -check-prefix=GCN -check-prefix=GCN-AA %s
2 ; RUN: llc -amdgpu-scalarize-global-loads=false -march=amdgcn -mcpu=bonaire -verify-machineinstrs -amdgpu-load-store-vectorizer=0 < %s | FileCheck -check-prefix=SI -check-prefix=GCN -check-prefix=GCN-AA %s
4 ; This test is mostly to test DAG store merging, so disable the vectorizer.
5 ; Run with devices with different unaligned load restrictions.
7 ; TODO: Vector element tests
8 ; TODO: Non-zero base offset for load and store combinations
9 ; TODO: Same base addrspacecasted
12 ; GCN-LABEL: {{^}}merge_global_store_2_constants_i8:
13 ; GCN: buffer_store_short
14 ; GCN: s_endpgm
15 define amdgpu_kernel void @merge_global_store_2_constants_i8(i8 addrspace(1)* %out) #0 {
16   %out.gep.1 = getelementptr i8, i8 addrspace(1)* %out, i32 1
18   store i8 123, i8 addrspace(1)* %out.gep.1
19   store i8 456, i8 addrspace(1)* %out, align 2
20   ret void
23 ; GCN-LABEL: {{^}}merge_global_store_2_constants_i8_natural_align:
24 ; GCN: buffer_store_byte
25 ; GCN: buffer_store_byte
26 ; GCN: s_endpgm
27 define amdgpu_kernel void @merge_global_store_2_constants_i8_natural_align(i8 addrspace(1)* %out) #0 {
28   %out.gep.1 = getelementptr i8, i8 addrspace(1)* %out, i32 1
30   store i8 123, i8 addrspace(1)* %out.gep.1
31   store i8 456, i8 addrspace(1)* %out
32   ret void
35 ; GCN-LABEL: {{^}}merge_global_store_2_constants_i16:
36 ; GCN: buffer_store_dword v
37 define amdgpu_kernel void @merge_global_store_2_constants_i16(i16 addrspace(1)* %out) #0 {
38   %out.gep.1 = getelementptr i16, i16 addrspace(1)* %out, i32 1
40   store i16 123, i16 addrspace(1)* %out.gep.1
41   store i16 456, i16 addrspace(1)* %out, align 4
42   ret void
45 ; GCN-LABEL: {{^}}merge_global_store_2_constants_0_i16:
46 ; GCN: buffer_store_dword v
47 define amdgpu_kernel void @merge_global_store_2_constants_0_i16(i16 addrspace(1)* %out) #0 {
48   %out.gep.1 = getelementptr i16, i16 addrspace(1)* %out, i32 1
50   store i16 0, i16 addrspace(1)* %out.gep.1
51   store i16 0, i16 addrspace(1)* %out, align 4
52   ret void
55 ; GCN-LABEL: {{^}}merge_global_store_2_constants_i16_natural_align:
56 ; GCN: buffer_store_short
57 ; GCN: buffer_store_short
58 ; GCN: s_endpgm
59 define amdgpu_kernel void @merge_global_store_2_constants_i16_natural_align(i16 addrspace(1)* %out) #0 {
60   %out.gep.1 = getelementptr i16, i16 addrspace(1)* %out, i32 1
62   store i16 123, i16 addrspace(1)* %out.gep.1
63   store i16 456, i16 addrspace(1)* %out
64   ret void
67 ; GCN-LABEL: {{^}}merge_global_store_2_constants_i32:
68 ; SI-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0x1c8
69 ; SI-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0x7b
70 ; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
71 define amdgpu_kernel void @merge_global_store_2_constants_i32(i32 addrspace(1)* %out) #0 {
72   %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
74   store i32 123, i32 addrspace(1)* %out.gep.1
75   store i32 456, i32 addrspace(1)* %out
76   ret void
79 ; GCN-LABEL: {{^}}merge_global_store_2_constants_i32_f32:
80 ; GCN: buffer_store_dwordx2
81 define amdgpu_kernel void @merge_global_store_2_constants_i32_f32(i32 addrspace(1)* %out) #0 {
82   %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
83   %out.gep.1.bc = bitcast i32 addrspace(1)* %out.gep.1 to float addrspace(1)*
84   store float 1.0, float addrspace(1)* %out.gep.1.bc
85   store i32 456, i32 addrspace(1)* %out
86   ret void
89 ; GCN-LABEL: {{^}}merge_global_store_2_constants_f32_i32:
90 ; SI-DAG: v_mov_b32_e32 v[[VLO:[0-9]+]], 4.0
91 ; SI-DAG: v_mov_b32_e32 v[[VHI:[0-9]+]], 0x7b
92 ; GCN: buffer_store_dwordx2 v{{\[}}[[VLO]]:[[VHI]]{{\]}}
93 define amdgpu_kernel void @merge_global_store_2_constants_f32_i32(float addrspace(1)* %out) #0 {
94   %out.gep.1 = getelementptr float, float addrspace(1)* %out, i32 1
95   %out.gep.1.bc = bitcast float addrspace(1)* %out.gep.1 to i32 addrspace(1)*
96   store i32 123, i32 addrspace(1)* %out.gep.1.bc
97   store float 4.0, float addrspace(1)* %out
98   ret void
101 ; GCN-LABEL: {{^}}merge_global_store_4_constants_i32:
102 ; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0x14d{{$}}
103 ; GCN-DAG: v_mov_b32_e32 v{{[0-9]+}}, 0x1c8{{$}}
104 ; GCN-DAG: v_mov_b32_e32 v{{[0-9]+}}, 0x7b{{$}}
105 ; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0x4d2{{$}}
106 ; GCN: buffer_store_dwordx4 v{{\[}}[[LO]]:[[HI]]{{\]}}
107 define amdgpu_kernel void @merge_global_store_4_constants_i32(i32 addrspace(1)* %out) #0 {
108   %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
109   %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
110   %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 3
112   store i32 123, i32 addrspace(1)* %out.gep.1
113   store i32 456, i32 addrspace(1)* %out.gep.2
114   store i32 333, i32 addrspace(1)* %out.gep.3
115   store i32 1234, i32 addrspace(1)* %out
116   ret void
119 ; GCN-LABEL: {{^}}merge_global_store_4_constants_f32_order:
120 ; GCN: buffer_store_dwordx4
121 define amdgpu_kernel void @merge_global_store_4_constants_f32_order(float addrspace(1)* %out) #0 {
122   %out.gep.1 = getelementptr float, float addrspace(1)* %out, i32 1
123   %out.gep.2 = getelementptr float, float addrspace(1)* %out, i32 2
124   %out.gep.3 = getelementptr float, float addrspace(1)* %out, i32 3
126   store float 8.0, float addrspace(1)* %out
127   store float 1.0, float addrspace(1)* %out.gep.1
128   store float 2.0, float addrspace(1)* %out.gep.2
129   store float 4.0, float addrspace(1)* %out.gep.3
130   ret void
133 ; First store is out of order.
134 ; GCN-LABEL: {{^}}merge_global_store_4_constants_f32:
135 ; GCN: buffer_store_dwordx4
136 define amdgpu_kernel void @merge_global_store_4_constants_f32(float addrspace(1)* %out) #0 {
137   %out.gep.1 = getelementptr float, float addrspace(1)* %out, i32 1
138   %out.gep.2 = getelementptr float, float addrspace(1)* %out, i32 2
139   %out.gep.3 = getelementptr float, float addrspace(1)* %out, i32 3
141   store float 1.0, float addrspace(1)* %out.gep.1
142   store float 2.0, float addrspace(1)* %out.gep.2
143   store float 4.0, float addrspace(1)* %out.gep.3
144   store float 8.0, float addrspace(1)* %out
145   ret void
148 ; GCN-LABEL: {{^}}merge_global_store_4_constants_mixed_i32_f32:
149 ; GCN-AA: buffer_store_dwordx4 v
150 ; GCN: s_endpgm
151 define amdgpu_kernel void @merge_global_store_4_constants_mixed_i32_f32(float addrspace(1)* %out) #0 {
152   %out.gep.1 = getelementptr float, float addrspace(1)* %out, i32 1
153   %out.gep.2 = getelementptr float, float addrspace(1)* %out, i32 2
154   %out.gep.3 = getelementptr float, float addrspace(1)* %out, i32 3
156   %out.gep.1.bc = bitcast float addrspace(1)* %out.gep.1 to i32 addrspace(1)*
157   %out.gep.3.bc = bitcast float addrspace(1)* %out.gep.3 to i32 addrspace(1)*
159   store i32 11, i32 addrspace(1)* %out.gep.1.bc
160   store float 2.0, float addrspace(1)* %out.gep.2
161   store i32 17, i32 addrspace(1)* %out.gep.3.bc
162   store float 8.0, float addrspace(1)* %out
163   ret void
166 ; GCN-LABEL: {{^}}merge_global_store_3_constants_i32:
167 ; SI-DAG: buffer_store_dwordx2
168 ; SI-DAG: buffer_store_dword
169 ; SI-NOT: buffer_store_dword
170 ; GCN: s_endpgm
171 define amdgpu_kernel void @merge_global_store_3_constants_i32(i32 addrspace(1)* %out) #0 {
172   %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
173   %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
175   store i32 123, i32 addrspace(1)* %out.gep.1
176   store i32 456, i32 addrspace(1)* %out.gep.2
177   store i32 1234, i32 addrspace(1)* %out
178   ret void
181 ; GCN-LABEL: {{^}}merge_global_store_2_constants_i64:
182 ; GCN: buffer_store_dwordx4
183 define amdgpu_kernel void @merge_global_store_2_constants_i64(i64 addrspace(1)* %out) #0 {
184   %out.gep.1 = getelementptr i64, i64 addrspace(1)* %out, i64 1
186   store i64 123, i64 addrspace(1)* %out.gep.1
187   store i64 456, i64 addrspace(1)* %out
188   ret void
191 ; GCN-LABEL: {{^}}merge_global_store_4_constants_i64:
192 ; GCN: buffer_store_dwordx4
193 ; GCN: buffer_store_dwordx4
194 define amdgpu_kernel void @merge_global_store_4_constants_i64(i64 addrspace(1)* %out) #0 {
195   %out.gep.1 = getelementptr i64, i64 addrspace(1)* %out, i64 1
196   %out.gep.2 = getelementptr i64, i64 addrspace(1)* %out, i64 2
197   %out.gep.3 = getelementptr i64, i64 addrspace(1)* %out, i64 3
199   store i64 123, i64 addrspace(1)* %out.gep.1
200   store i64 456, i64 addrspace(1)* %out.gep.2
201   store i64 333, i64 addrspace(1)* %out.gep.3
202   store i64 1234, i64 addrspace(1)* %out
203   ret void
206 ; GCN-LABEL: {{^}}merge_global_store_2_adjacent_loads_i32:
207 ; GCN: buffer_load_dwordx2 [[LOAD:v\[[0-9]+:[0-9]+\]]]
208 ; GCN: buffer_store_dwordx2 [[LOAD]]
209 define amdgpu_kernel void @merge_global_store_2_adjacent_loads_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
210   %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
211   %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
213   %lo = load i32, i32 addrspace(1)* %in
214   %hi = load i32, i32 addrspace(1)* %in.gep.1
216   store i32 %lo, i32 addrspace(1)* %out
217   store i32 %hi, i32 addrspace(1)* %out.gep.1
218   ret void
221 ; GCN-LABEL: {{^}}merge_global_store_2_adjacent_loads_i32_nonzero_base:
222 ; GCN: buffer_load_dwordx2 [[LOAD:v\[[0-9]+:[0-9]+\]]], off, s{{\[[0-9]+:[0-9]+\]}}, 0 offset:8
223 ; GCN: buffer_store_dwordx2 [[LOAD]], off, s{{\[[0-9]+:[0-9]+\]}}, 0 offset:8
224 define amdgpu_kernel void @merge_global_store_2_adjacent_loads_i32_nonzero_base(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
225   %in.gep.0 = getelementptr i32, i32 addrspace(1)* %in, i32 2
226   %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 3
228   %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i32 2
229   %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 3
230   %lo = load i32, i32 addrspace(1)* %in.gep.0
231   %hi = load i32, i32 addrspace(1)* %in.gep.1
233   store i32 %lo, i32 addrspace(1)* %out.gep.0
234   store i32 %hi, i32 addrspace(1)* %out.gep.1
235   ret void
238 ; GCN-LABEL: {{^}}merge_global_store_2_adjacent_loads_shuffle_i32:
239 ; GCN: buffer_load_dwordx2 v
240 ; GCN: buffer_store_dwordx2 v
241 define amdgpu_kernel void @merge_global_store_2_adjacent_loads_shuffle_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
242   %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
243   %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
245   %lo = load i32, i32 addrspace(1)* %in
246   %hi = load i32, i32 addrspace(1)* %in.gep.1
248   store i32 %hi, i32 addrspace(1)* %out
249   store i32 %lo, i32 addrspace(1)* %out.gep.1
250   ret void
253 ; GCN-LABEL: {{^}}merge_global_store_4_adjacent_loads_i32:
254 ; GCN: buffer_load_dwordx4 [[LOAD:v\[[0-9]+:[0-9]+\]]]
255 ; GCN: buffer_store_dwordx4 [[LOAD]]
256 define amdgpu_kernel void @merge_global_store_4_adjacent_loads_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
257   %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
258   %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
259   %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 3
260   %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
261   %in.gep.2 = getelementptr i32, i32 addrspace(1)* %in, i32 2
262   %in.gep.3 = getelementptr i32, i32 addrspace(1)* %in, i32 3
264   %x = load i32, i32 addrspace(1)* %in
265   %y = load i32, i32 addrspace(1)* %in.gep.1
266   %z = load i32, i32 addrspace(1)* %in.gep.2
267   %w = load i32, i32 addrspace(1)* %in.gep.3
269   store i32 %x, i32 addrspace(1)* %out
270   store i32 %y, i32 addrspace(1)* %out.gep.1
271   store i32 %z, i32 addrspace(1)* %out.gep.2
272   store i32 %w, i32 addrspace(1)* %out.gep.3
273   ret void
276 ; GCN-LABEL: {{^}}merge_global_store_3_adjacent_loads_i32:
277 ; SI-DAG: buffer_load_dwordx2
278 ; SI-DAG: buffer_load_dword v
279 ; GCN: s_waitcnt
280 ; SI-DAG: buffer_store_dword v
281 ; SI-DAG: buffer_store_dwordx2 v
282 ; GCN: s_endpgm
283 define amdgpu_kernel void @merge_global_store_3_adjacent_loads_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
284   %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
285   %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
286   %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
287   %in.gep.2 = getelementptr i32, i32 addrspace(1)* %in, i32 2
289   %x = load i32, i32 addrspace(1)* %in
290   %y = load i32, i32 addrspace(1)* %in.gep.1
291   %z = load i32, i32 addrspace(1)* %in.gep.2
293   store i32 %x, i32 addrspace(1)* %out
294   store i32 %y, i32 addrspace(1)* %out.gep.1
295   store i32 %z, i32 addrspace(1)* %out.gep.2
296   ret void
299 ; GCN-LABEL: {{^}}merge_global_store_4_adjacent_loads_f32:
300 ; GCN: buffer_load_dwordx4 [[LOAD:v\[[0-9]+:[0-9]+\]]]
301 ; GCN: buffer_store_dwordx4 [[LOAD]]
302 define amdgpu_kernel void @merge_global_store_4_adjacent_loads_f32(float addrspace(1)* %out, float addrspace(1)* %in) #0 {
303   %out.gep.1 = getelementptr float, float addrspace(1)* %out, i32 1
304   %out.gep.2 = getelementptr float, float addrspace(1)* %out, i32 2
305   %out.gep.3 = getelementptr float, float addrspace(1)* %out, i32 3
306   %in.gep.1 = getelementptr float, float addrspace(1)* %in, i32 1
307   %in.gep.2 = getelementptr float, float addrspace(1)* %in, i32 2
308   %in.gep.3 = getelementptr float, float addrspace(1)* %in, i32 3
310   %x = load float, float addrspace(1)* %in
311   %y = load float, float addrspace(1)* %in.gep.1
312   %z = load float, float addrspace(1)* %in.gep.2
313   %w = load float, float addrspace(1)* %in.gep.3
315   store float %x, float addrspace(1)* %out
316   store float %y, float addrspace(1)* %out.gep.1
317   store float %z, float addrspace(1)* %out.gep.2
318   store float %w, float addrspace(1)* %out.gep.3
319   ret void
322 ; GCN-LABEL: {{^}}merge_global_store_4_adjacent_loads_i32_nonzero_base:
323 ; GCN: buffer_load_dwordx4 [[LOAD:v\[[0-9]+:[0-9]+\]]], off, s{{\[[0-9]+:[0-9]+\]}}, 0 offset:44
324 ; GCN: buffer_store_dwordx4 [[LOAD]], off, s{{\[[0-9]+:[0-9]+\]}}, 0 offset:28
325 define amdgpu_kernel void @merge_global_store_4_adjacent_loads_i32_nonzero_base(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
326   %in.gep.0 = getelementptr i32, i32 addrspace(1)* %in, i32 11
327   %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 12
328   %in.gep.2 = getelementptr i32, i32 addrspace(1)* %in, i32 13
329   %in.gep.3 = getelementptr i32, i32 addrspace(1)* %in, i32 14
330   %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i32 7
331   %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 8
332   %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 9
333   %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 10
335   %x = load i32, i32 addrspace(1)* %in.gep.0
336   %y = load i32, i32 addrspace(1)* %in.gep.1
337   %z = load i32, i32 addrspace(1)* %in.gep.2
338   %w = load i32, i32 addrspace(1)* %in.gep.3
340   store i32 %x, i32 addrspace(1)* %out.gep.0
341   store i32 %y, i32 addrspace(1)* %out.gep.1
342   store i32 %z, i32 addrspace(1)* %out.gep.2
343   store i32 %w, i32 addrspace(1)* %out.gep.3
344   ret void
347 ; GCN-LABEL: {{^}}merge_global_store_4_adjacent_loads_inverse_i32:
348 ; GCN: buffer_load_dwordx4 [[LOAD:v\[[0-9]+:[0-9]+\]]]
349 ; GCN: s_barrier
350 ; GCN: buffer_store_dwordx4 [[LOAD]]
351 define amdgpu_kernel void @merge_global_store_4_adjacent_loads_inverse_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
352   %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
353   %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
354   %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 3
355   %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
356   %in.gep.2 = getelementptr i32, i32 addrspace(1)* %in, i32 2
357   %in.gep.3 = getelementptr i32, i32 addrspace(1)* %in, i32 3
359   %x = load i32, i32 addrspace(1)* %in
360   %y = load i32, i32 addrspace(1)* %in.gep.1
361   %z = load i32, i32 addrspace(1)* %in.gep.2
362   %w = load i32, i32 addrspace(1)* %in.gep.3
364   ; Make sure the barrier doesn't stop this
365   tail call void @llvm.amdgcn.s.barrier() #1
367   store i32 %w, i32 addrspace(1)* %out.gep.3
368   store i32 %z, i32 addrspace(1)* %out.gep.2
369   store i32 %y, i32 addrspace(1)* %out.gep.1
370   store i32 %x, i32 addrspace(1)* %out
372   ret void
375 ; TODO: Re-packing of loaded register required. Maybe an IR pass
376 ; should catch this?
378 ; GCN-LABEL: {{^}}merge_global_store_4_adjacent_loads_shuffle_i32:
379 ; GCN: buffer_load_dwordx4 v
380 ; GCN: s_barrier
381 ; GCN: buffer_store_dwordx4 v
382 define amdgpu_kernel void @merge_global_store_4_adjacent_loads_shuffle_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
383   %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
384   %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
385   %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 3
386   %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
387   %in.gep.2 = getelementptr i32, i32 addrspace(1)* %in, i32 2
388   %in.gep.3 = getelementptr i32, i32 addrspace(1)* %in, i32 3
390   %x = load i32, i32 addrspace(1)* %in
391   %y = load i32, i32 addrspace(1)* %in.gep.1
392   %z = load i32, i32 addrspace(1)* %in.gep.2
393   %w = load i32, i32 addrspace(1)* %in.gep.3
395   ; Make sure the barrier doesn't stop this
396   tail call void @llvm.amdgcn.s.barrier() #1
398   store i32 %w, i32 addrspace(1)* %out
399   store i32 %z, i32 addrspace(1)* %out.gep.1
400   store i32 %y, i32 addrspace(1)* %out.gep.2
401   store i32 %x, i32 addrspace(1)* %out.gep.3
403   ret void
406 ; GCN-LABEL: {{^}}merge_global_store_4_adjacent_loads_i8:
407 ; GCN: buffer_load_dword [[LOAD:v[0-9]+]]
408 ; GCN: buffer_store_dword [[LOAD]]
409 ; GCN: s_endpgm
410 define amdgpu_kernel void @merge_global_store_4_adjacent_loads_i8(i8 addrspace(1)* %out, i8 addrspace(1)* %in) #0 {
411   %out.gep.1 = getelementptr i8, i8 addrspace(1)* %out, i8 1
412   %out.gep.2 = getelementptr i8, i8 addrspace(1)* %out, i8 2
413   %out.gep.3 = getelementptr i8, i8 addrspace(1)* %out, i8 3
414   %in.gep.1 = getelementptr i8, i8 addrspace(1)* %in, i8 1
415   %in.gep.2 = getelementptr i8, i8 addrspace(1)* %in, i8 2
416   %in.gep.3 = getelementptr i8, i8 addrspace(1)* %in, i8 3
418   %x = load i8, i8 addrspace(1)* %in, align 4
419   %y = load i8, i8 addrspace(1)* %in.gep.1
420   %z = load i8, i8 addrspace(1)* %in.gep.2
421   %w = load i8, i8 addrspace(1)* %in.gep.3
423   store i8 %x, i8 addrspace(1)* %out, align 4
424   store i8 %y, i8 addrspace(1)* %out.gep.1
425   store i8 %z, i8 addrspace(1)* %out.gep.2
426   store i8 %w, i8 addrspace(1)* %out.gep.3
427   ret void
430 ; GCN-LABEL: {{^}}merge_global_store_4_adjacent_loads_i8_natural_align:
431 ; GCN: buffer_load_ubyte
432 ; GCN: buffer_load_ubyte
433 ; GCN: buffer_load_ubyte
434 ; GCN: buffer_load_ubyte
435 ; GCN: buffer_store_byte
436 ; GCN: buffer_store_byte
437 ; GCN: buffer_store_byte
438 ; GCN: buffer_store_byte
439 ; GCN: s_endpgm
440 define amdgpu_kernel void @merge_global_store_4_adjacent_loads_i8_natural_align(i8 addrspace(1)* %out, i8 addrspace(1)* %in) #0 {
441   %out.gep.1 = getelementptr i8, i8 addrspace(1)* %out, i8 1
442   %out.gep.2 = getelementptr i8, i8 addrspace(1)* %out, i8 2
443   %out.gep.3 = getelementptr i8, i8 addrspace(1)* %out, i8 3
444   %in.gep.1 = getelementptr i8, i8 addrspace(1)* %in, i8 1
445   %in.gep.2 = getelementptr i8, i8 addrspace(1)* %in, i8 2
446   %in.gep.3 = getelementptr i8, i8 addrspace(1)* %in, i8 3
448   %x = load i8, i8 addrspace(1)* %in
449   %y = load i8, i8 addrspace(1)* %in.gep.1
450   %z = load i8, i8 addrspace(1)* %in.gep.2
451   %w = load i8, i8 addrspace(1)* %in.gep.3
453   store i8 %x, i8 addrspace(1)* %out
454   store i8 %y, i8 addrspace(1)* %out.gep.1
455   store i8 %z, i8 addrspace(1)* %out.gep.2
456   store i8 %w, i8 addrspace(1)* %out.gep.3
457   ret void
460 ; GCN-LABEL: {{^}}merge_global_store_4_vector_elts_loads_v4i32:
461 ; GCN: buffer_load_dwordx4 [[LOAD:v\[[0-9]+:[0-9]+\]]]
462 ; GCN: buffer_store_dwordx4 [[LOAD]]
463 ; GCN: s_endpgm
464 define amdgpu_kernel void @merge_global_store_4_vector_elts_loads_v4i32(i32 addrspace(1)* %out, <4 x i32> addrspace(1)* %in) #0 {
465   %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
466   %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
467   %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 3
468   %vec = load <4 x i32>, <4 x i32> addrspace(1)* %in
470   %x = extractelement <4 x i32> %vec, i32 0
471   %y = extractelement <4 x i32> %vec, i32 1
472   %z = extractelement <4 x i32> %vec, i32 2
473   %w = extractelement <4 x i32> %vec, i32 3
475   store i32 %x, i32 addrspace(1)* %out
476   store i32 %y, i32 addrspace(1)* %out.gep.1
477   store i32 %z, i32 addrspace(1)* %out.gep.2
478   store i32 %w, i32 addrspace(1)* %out.gep.3
479   ret void
482 ; GCN-LABEL: {{^}}merge_local_store_2_constants_i8:
483 ; GCN: ds_write_b16
484 ; GCN: s_endpgm
485 define amdgpu_kernel void @merge_local_store_2_constants_i8(i8 addrspace(3)* %out) #0 {
486   %out.gep.1 = getelementptr i8, i8 addrspace(3)* %out, i32 1
488   store i8 123, i8 addrspace(3)* %out.gep.1
489   store i8 456, i8 addrspace(3)* %out, align 2
490   ret void
493 ; GCN-LABEL: {{^}}merge_local_store_2_constants_i32:
494 ; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0x1c8
495 ; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0x7b
496 ; GCN: ds_write2_b32 v{{[0-9]+}}, v[[LO]], v[[HI]] offset1:1{{$}}
497 define amdgpu_kernel void @merge_local_store_2_constants_i32(i32 addrspace(3)* %out) #0 {
498   %out.gep.1 = getelementptr i32, i32 addrspace(3)* %out, i32 1
500   store i32 123, i32 addrspace(3)* %out.gep.1
501   store i32 456, i32 addrspace(3)* %out
502   ret void
505 ; GCN-LABEL: {{^}}merge_local_store_4_constants_i32:
506 ; GCN-DAG: v_mov_b32_e32 [[K2:v[0-9]+]], 0x1c8
507 ; GCN-DAG: v_mov_b32_e32 [[K3:v[0-9]+]], 0x14d
508 ; GCN-DAG: ds_write2_b32 v{{[0-9]+}}, [[K2]], [[K3]] offset0:2 offset1:3
510 ; GCN-DAG: v_mov_b32_e32 [[K0:v[0-9]+]], 0x4d2
511 ; GCN-DAG: v_mov_b32_e32 [[K1:v[0-9]+]], 0x7b
512 ; GCN-DAG: ds_write2_b32 v{{[0-9]+}}, [[K0]], [[K1]] offset1:1
514 ; GCN: s_endpgm
515 define amdgpu_kernel void @merge_local_store_4_constants_i32(i32 addrspace(3)* %out) #0 {
516   %out.gep.1 = getelementptr i32, i32 addrspace(3)* %out, i32 1
517   %out.gep.2 = getelementptr i32, i32 addrspace(3)* %out, i32 2
518   %out.gep.3 = getelementptr i32, i32 addrspace(3)* %out, i32 3
520   store i32 123, i32 addrspace(3)* %out.gep.1
521   store i32 456, i32 addrspace(3)* %out.gep.2
522   store i32 333, i32 addrspace(3)* %out.gep.3
523   store i32 1234, i32 addrspace(3)* %out
524   ret void
527 ; GCN-LABEL: {{^}}merge_global_store_5_constants_i32:
528 ; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 9{{$}}
529 ; GCN-DAG: v_mov_b32_e32 v[[HI4:[0-9]+]], -12{{$}}
530 ; GCN: buffer_store_dwordx4 v{{\[}}[[LO]]:[[HI4]]{{\]}}
531 ; GCN: v_mov_b32_e32 v[[HI:[0-9]+]], 11{{$}}
532 ; GCN: buffer_store_dword v[[HI]]
533 define amdgpu_kernel void @merge_global_store_5_constants_i32(i32 addrspace(1)* %out) {
534   store i32 9, i32 addrspace(1)* %out, align 4
535   %idx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 1
536   store i32 12, i32 addrspace(1)* %idx1, align 4
537   %idx2 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 2
538   store i32 16, i32 addrspace(1)* %idx2, align 4
539   %idx3 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 3
540   store i32 -12, i32 addrspace(1)* %idx3, align 4
541   %idx4 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 4
542   store i32 11, i32 addrspace(1)* %idx4, align 4
543   ret void
546 ; GCN-LABEL: {{^}}merge_global_store_6_constants_i32:
547 ; GCN: buffer_store_dwordx4
548 ; GCN: buffer_store_dwordx2
549 define amdgpu_kernel void @merge_global_store_6_constants_i32(i32 addrspace(1)* %out) {
550   store i32 13, i32 addrspace(1)* %out, align 4
551   %idx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 1
552   store i32 15, i32 addrspace(1)* %idx1, align 4
553   %idx2 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 2
554   store i32 62, i32 addrspace(1)* %idx2, align 4
555   %idx3 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 3
556   store i32 63, i32 addrspace(1)* %idx3, align 4
557   %idx4 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 4
558   store i32 11, i32 addrspace(1)* %idx4, align 4
559   %idx5 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 5
560   store i32 123, i32 addrspace(1)* %idx5, align 4
561   ret void
564 ; GCN-LABEL: {{^}}merge_global_store_7_constants_i32:
565 ; GCN: buffer_store_dwordx4
566 ; GCN: buffer_store_dwordx2
567 ; GCN: buffer_store_dword v
568 define amdgpu_kernel void @merge_global_store_7_constants_i32(i32 addrspace(1)* %out) {
569   store i32 34, i32 addrspace(1)* %out, align 4
570   %idx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 1
571   store i32 999, i32 addrspace(1)* %idx1, align 4
572   %idx2 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 2
573   store i32 65, i32 addrspace(1)* %idx2, align 4
574   %idx3 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 3
575   store i32 33, i32 addrspace(1)* %idx3, align 4
576   %idx4 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 4
577   store i32 98, i32 addrspace(1)* %idx4, align 4
578   %idx5 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 5
579   store i32 91, i32 addrspace(1)* %idx5, align 4
580   %idx6 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 6
581   store i32 212, i32 addrspace(1)* %idx6, align 4
582   ret void
585 ; GCN-LABEL: {{^}}merge_global_store_8_constants_i32:
586 ; GCN: buffer_store_dwordx4
587 ; GCN: buffer_store_dwordx4
588 ; GCN: s_endpgm
589 define amdgpu_kernel void @merge_global_store_8_constants_i32(i32 addrspace(1)* %out) {
590   store i32 34, i32 addrspace(1)* %out, align 4
591   %idx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 1
592   store i32 999, i32 addrspace(1)* %idx1, align 4
593   %idx2 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 2
594   store i32 65, i32 addrspace(1)* %idx2, align 4
595   %idx3 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 3
596   store i32 33, i32 addrspace(1)* %idx3, align 4
597   %idx4 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 4
598   store i32 98, i32 addrspace(1)* %idx4, align 4
599   %idx5 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 5
600   store i32 91, i32 addrspace(1)* %idx5, align 4
601   %idx6 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 6
602   store i32 212, i32 addrspace(1)* %idx6, align 4
603   %idx7 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 7
604   store i32 999, i32 addrspace(1)* %idx7, align 4
605   ret void
608 ; This requires handling of scalar_to_vector for v2i64 to avoid
609 ; scratch usage.
610 ; FIXME: Should do single load and store
612 ; GCN-LABEL: {{^}}copy_v3i32_align4:
613 ; GCN-NOT: SCRATCH_RSRC_DWORD
614 ; GCN-DAG: buffer_load_dword v{{[0-9]+}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0 offset:8
615 ; GCN-DAG: buffer_load_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0{{$}}
616 ; GCN-NOT: offen
617 ; GCN: s_waitcnt vmcnt
618 ; GCN-NOT: offen
619 ; GCN-DAG: buffer_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0{{$}}
620 ; GCN-DAG: buffer_store_dword v{{[0-9]+}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0 offset:8
622 ; GCN: ScratchSize: 0{{$}}
623 define amdgpu_kernel void @copy_v3i32_align4(<3 x i32> addrspace(1)* noalias %out, <3 x i32> addrspace(1)* noalias %in) #0 {
624   %vec = load <3 x i32>, <3 x i32> addrspace(1)* %in, align 4
625   store <3 x i32> %vec, <3 x i32> addrspace(1)* %out
626   ret void
629 ; GCN-LABEL: {{^}}copy_v3i64_align4:
630 ; GCN-NOT: SCRATCH_RSRC_DWORD
631 ; GCN-DAG: buffer_load_dwordx4 v{{\[[0-9]+:[0-9]+\]}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0{{$}}
632 ; GCN-DAG: buffer_load_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0 offset:16{{$}}
633 ; GCN-NOT: offen
634 ; GCN: s_waitcnt vmcnt
635 ; GCN-NOT: offen
636 ; GCN-DAG: buffer_store_dwordx4 v{{\[[0-9]+:[0-9]+\]}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0{{$}}
637 ; GCN-DAG: buffer_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0 offset:16{{$}}
638 ; GCN: ScratchSize: 0{{$}}
639 define amdgpu_kernel void @copy_v3i64_align4(<3 x i64> addrspace(1)* noalias %out, <3 x i64> addrspace(1)* noalias %in) #0 {
640   %vec = load <3 x i64>, <3 x i64> addrspace(1)* %in, align 4
641   store <3 x i64> %vec, <3 x i64> addrspace(1)* %out
642   ret void
645 ; GCN-LABEL: {{^}}copy_v3f32_align4:
646 ; GCN-NOT: SCRATCH_RSRC_DWORD
647 ; GCN-DAG: buffer_load_dword v{{[0-9]+}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0 offset:8
648 ; GCN-DAG: buffer_load_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0{{$}}
649 ; GCN-NOT: offen
650 ; GCN: s_waitcnt vmcnt
651 ; GCN-NOT: offen
652 ; GCN-DAG: buffer_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0{{$}}
653 ; GCN-DAG: buffer_store_dword v{{[0-9]+}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0 offset:8
654 ; GCN: ScratchSize: 0{{$}}
655 define amdgpu_kernel void @copy_v3f32_align4(<3 x float> addrspace(1)* noalias %out, <3 x float> addrspace(1)* noalias %in) #0 {
656   %vec = load <3 x float>, <3 x float> addrspace(1)* %in, align 4
657   %fadd = fadd <3 x float> %vec, <float 1.0, float 2.0, float 4.0>
658   store <3 x float> %fadd, <3 x float> addrspace(1)* %out
659   ret void
662 ; GCN-LABEL: {{^}}copy_v3f64_align4:
663 ; GCN-NOT: SCRATCH_RSRC_DWORD
664 ; GCN-DAG: buffer_load_dwordx4 v{{\[[0-9]+:[0-9]+\]}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0{{$}}
665 ; GCN-DAG: buffer_load_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0 offset:16{{$}}
666 ; GCN-NOT: offen
667 ; GCN: s_waitcnt vmcnt
668 ; GCN-NOT: offen
669 ; GCN-DAG: buffer_store_dwordx4 v{{\[[0-9]+:[0-9]+\]}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0{{$}}
670 ; GCN-DAG: buffer_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, off, s{{\[[0-9]+:[0-9]+\]}}, 0 offset:16{{$}}
671 ; GCN: ScratchSize: 0{{$}}
672 define amdgpu_kernel void @copy_v3f64_align4(<3 x double> addrspace(1)* noalias %out, <3 x double> addrspace(1)* noalias %in) #0 {
673   %vec = load <3 x double>, <3 x double> addrspace(1)* %in, align 4
674   %fadd = fadd <3 x double> %vec, <double 1.0, double 2.0, double 4.0>
675   store <3 x double> %fadd, <3 x double> addrspace(1)* %out
676   ret void
679 declare void @llvm.amdgcn.s.barrier() #1
681 attributes #0 = { nounwind }
682 attributes #1 = { convergent nounwind }