1 ; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=GCN %s
2 ; RUN: llc -march=amdgcn -mcpu=bonaire -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=GCN %s
4 ; Run with devices with different unaligned load restrictions.
6 ; TODO: Vector element tests
7 ; TODO: Non-zero base offset for load and store combinations
8 ; TODO: Same base addrspacecasted
11 ; GCN-LABEL: {{^}}merge_global_store_2_constants_i8:
12 ; GCN: buffer_store_byte
13 ; GCN: buffer_store_byte
15 define 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
23 ; GCN-LABEL: {{^}}merge_global_store_2_constants_i8_natural_align:
24 ; GCN: buffer_store_byte
25 ; GCN: buffer_store_byte
27 define 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
35 ; GCN-LABEL: {{^}}merge_global_store_2_constants_i16:
36 ; GCN: buffer_store_dword v
37 define 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
45 ; GCN-LABEL: {{^}}merge_global_store_2_constants_0_i16:
46 ; GCN: buffer_store_dword v
47 define 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
55 ; GCN-LABEL: {{^}}merge_global_store_2_constants_i16_natural_align:
56 ; GCN: buffer_store_short
57 ; GCN: buffer_store_short
59 define 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
67 ; GCN-LABEL: {{^}}merge_global_store_2_constants_i32:
68 ; SI-DAG: s_movk_i32 [[SLO:s[0-9]+]], 0x1c8
69 ; SI-DAG: s_movk_i32 [[SHI:s[0-9]+]], 0x7b
70 ; SI-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], [[SLO]]
71 ; SI-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], [[SHI]]
72 ; GCN: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]{{\]}}
73 define void @merge_global_store_2_constants_i32(i32 addrspace(1)* %out) #0 {
74 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
76 store i32 123, i32 addrspace(1)* %out.gep.1
77 store i32 456, i32 addrspace(1)* %out
81 ; GCN-LABEL: {{^}}merge_global_store_2_constants_i32_f32:
82 ; GCN: buffer_store_dwordx2
83 define void @merge_global_store_2_constants_i32_f32(i32 addrspace(1)* %out) #0 {
84 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
85 %out.gep.1.bc = bitcast i32 addrspace(1)* %out.gep.1 to float addrspace(1)*
86 store float 1.0, float addrspace(1)* %out.gep.1.bc
87 store i32 456, i32 addrspace(1)* %out
91 ; GCN-LABEL: {{^}}merge_global_store_2_constants_f32_i32:
92 ; SI-DAG: s_mov_b32 [[SLO:s[0-9]+]], 4.0
93 ; SI-DAG: s_movk_i32 [[SHI:s[0-9]+]], 0x7b{{$}}
94 ; SI-DAG: v_mov_b32_e32 v[[VLO:[0-9]+]], [[SLO]]
95 ; SI-DAG: v_mov_b32_e32 v[[VHI:[0-9]+]], [[SHI]]
96 ; GCN: buffer_store_dwordx2 v{{\[}}[[VLO]]:[[VHI]]{{\]}}
97 define void @merge_global_store_2_constants_f32_i32(float addrspace(1)* %out) #0 {
98 %out.gep.1 = getelementptr float, float addrspace(1)* %out, i32 1
99 %out.gep.1.bc = bitcast float addrspace(1)* %out.gep.1 to i32 addrspace(1)*
100 store i32 123, i32 addrspace(1)* %out.gep.1.bc
101 store float 4.0, float addrspace(1)* %out
105 ; GCN-LABEL: {{^}}merge_global_store_4_constants_i32:
106 ; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], 0x14d{{$}}
107 ; GCN-DAG: v_mov_b32_e32 v{{[0-9]+}}, 0x1c8{{$}}
108 ; GCN-DAG: v_mov_b32_e32 v{{[0-9]+}}, 0x7b{{$}}
109 ; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 0x4d2{{$}}
110 ; GCN: buffer_store_dwordx4 v{{\[}}[[LO]]:[[HI]]{{\]}}
111 define void @merge_global_store_4_constants_i32(i32 addrspace(1)* %out) #0 {
112 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
113 %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
114 %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 3
116 store i32 123, i32 addrspace(1)* %out.gep.1
117 store i32 456, i32 addrspace(1)* %out.gep.2
118 store i32 333, i32 addrspace(1)* %out.gep.3
119 store i32 1234, i32 addrspace(1)* %out
123 ; GCN-LABEL: {{^}}merge_global_store_4_constants_f32_order:
124 ; XGCN: buffer_store_dwordx4
125 ; GCN: buffer_store_dword v
126 ; GCN: buffer_store_dword v
127 ; GCN: buffer_store_dwordx2 v
128 define void @merge_global_store_4_constants_f32_order(float addrspace(1)* %out) #0 {
129 %out.gep.1 = getelementptr float, float addrspace(1)* %out, i32 1
130 %out.gep.2 = getelementptr float, float addrspace(1)* %out, i32 2
131 %out.gep.3 = getelementptr float, float addrspace(1)* %out, i32 3
133 store float 8.0, float addrspace(1)* %out
134 store float 1.0, float addrspace(1)* %out.gep.1
135 store float 2.0, float addrspace(1)* %out.gep.2
136 store float 4.0, float addrspace(1)* %out.gep.3
140 ; First store is out of order. Because of order of combines, the
141 ; consecutive store fails because only some of the stores have been
142 ; replaced with integer constant stores, and then won't merge because
143 ; the types are different.
145 ; GCN-LABEL: {{^}}merge_global_store_4_constants_f32:
146 ; XGCN: buffer_store_dwordx4
147 ; GCN: buffer_store_dword v
148 ; GCN: buffer_store_dword v
149 ; GCN: buffer_store_dword v
150 ; GCN: buffer_store_dword v
151 define void @merge_global_store_4_constants_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 store float 1.0, float addrspace(1)* %out.gep.1
157 store float 2.0, float addrspace(1)* %out.gep.2
158 store float 4.0, float addrspace(1)* %out.gep.3
159 store float 8.0, float addrspace(1)* %out
163 ; GCN-LABEL: {{^}}merge_global_store_3_constants_i32:
164 ; SI-DAG: buffer_store_dwordx2
165 ; SI-DAG: buffer_store_dword
166 ; SI-NOT: buffer_store_dword
168 define void @merge_global_store_3_constants_i32(i32 addrspace(1)* %out) #0 {
169 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
170 %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
172 store i32 123, i32 addrspace(1)* %out.gep.1
173 store i32 456, i32 addrspace(1)* %out.gep.2
174 store i32 1234, i32 addrspace(1)* %out
178 ; GCN-LABEL: {{^}}merge_global_store_2_constants_i64:
179 ; XGCN: buffer_store_dwordx4
180 ; GCN: buffer_store_dwordx2
181 ; GCN: buffer_store_dwordx2
182 define void @merge_global_store_2_constants_i64(i64 addrspace(1)* %out) #0 {
183 %out.gep.1 = getelementptr i64, i64 addrspace(1)* %out, i64 1
185 store i64 123, i64 addrspace(1)* %out.gep.1
186 store i64 456, i64 addrspace(1)* %out
190 ; GCN-LABEL: {{^}}merge_global_store_4_constants_i64:
191 ; XGCN: buffer_store_dwordx4
192 ; XGCN: buffer_store_dwordx4
194 ; GCN: buffer_store_dwordx2
195 ; GCN: buffer_store_dwordx2
196 ; GCN: buffer_store_dwordx2
197 ; GCN: buffer_store_dwordx2
198 define void @merge_global_store_4_constants_i64(i64 addrspace(1)* %out) #0 {
199 %out.gep.1 = getelementptr i64, i64 addrspace(1)* %out, i64 1
200 %out.gep.2 = getelementptr i64, i64 addrspace(1)* %out, i64 2
201 %out.gep.3 = getelementptr i64, i64 addrspace(1)* %out, i64 3
203 store i64 123, i64 addrspace(1)* %out.gep.1
204 store i64 456, i64 addrspace(1)* %out.gep.2
205 store i64 333, i64 addrspace(1)* %out.gep.3
206 store i64 1234, i64 addrspace(1)* %out
210 ; GCN-LABEL: {{^}}merge_global_store_2_adjacent_loads_i32:
211 ; GCN: buffer_load_dwordx2 [[LOAD:v\[[0-9]+:[0-9]+\]]]
212 ; GCN: buffer_store_dwordx2 [[LOAD]]
213 define void @merge_global_store_2_adjacent_loads_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
214 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
215 %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
217 %lo = load i32, i32 addrspace(1)* %in
218 %hi = load i32, i32 addrspace(1)* %in.gep.1
220 store i32 %lo, i32 addrspace(1)* %out
221 store i32 %hi, i32 addrspace(1)* %out.gep.1
225 ; GCN-LABEL: {{^}}merge_global_store_2_adjacent_loads_i32_nonzero_base:
226 ; GCN: buffer_load_dwordx2 [[LOAD:v\[[0-9]+:[0-9]+\]]], s{{\[[0-9]+:[0-9]+\]}}, 0 offset:8
227 ; GCN: buffer_store_dwordx2 [[LOAD]], s{{\[[0-9]+:[0-9]+\]}}, 0 offset:8
228 define void @merge_global_store_2_adjacent_loads_i32_nonzero_base(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
229 %in.gep.0 = getelementptr i32, i32 addrspace(1)* %in, i32 2
230 %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 3
232 %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i32 2
233 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 3
234 %lo = load i32, i32 addrspace(1)* %in.gep.0
235 %hi = load i32, i32 addrspace(1)* %in.gep.1
237 store i32 %lo, i32 addrspace(1)* %out.gep.0
238 store i32 %hi, i32 addrspace(1)* %out.gep.1
242 ; GCN-LABEL: {{^}}merge_global_store_2_adjacent_loads_shuffle_i32:
243 ; GCN: buffer_load_dword v
244 ; GCN: buffer_load_dword v
245 ; GCN: buffer_store_dword v
246 ; GCN: buffer_store_dword v
247 define void @merge_global_store_2_adjacent_loads_shuffle_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
248 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
249 %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
251 %lo = load i32, i32 addrspace(1)* %in
252 %hi = load i32, i32 addrspace(1)* %in.gep.1
254 store i32 %hi, i32 addrspace(1)* %out
255 store i32 %lo, i32 addrspace(1)* %out.gep.1
259 ; GCN-LABEL: {{^}}merge_global_store_4_adjacent_loads_i32:
260 ; GCN: buffer_load_dwordx4 [[LOAD:v\[[0-9]+:[0-9]+\]]]
261 ; GCN: buffer_store_dwordx4 [[LOAD]]
262 define void @merge_global_store_4_adjacent_loads_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
263 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
264 %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
265 %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 3
266 %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
267 %in.gep.2 = getelementptr i32, i32 addrspace(1)* %in, i32 2
268 %in.gep.3 = getelementptr i32, i32 addrspace(1)* %in, i32 3
270 %x = load i32, i32 addrspace(1)* %in
271 %y = load i32, i32 addrspace(1)* %in.gep.1
272 %z = load i32, i32 addrspace(1)* %in.gep.2
273 %w = load i32, i32 addrspace(1)* %in.gep.3
275 store i32 %x, i32 addrspace(1)* %out
276 store i32 %y, i32 addrspace(1)* %out.gep.1
277 store i32 %z, i32 addrspace(1)* %out.gep.2
278 store i32 %w, i32 addrspace(1)* %out.gep.3
282 ; GCN-LABEL: {{^}}merge_global_store_3_adjacent_loads_i32:
283 ; SI-DAG: buffer_load_dwordx2
284 ; SI-DAG: buffer_load_dword v
286 ; SI-DAG: buffer_store_dword v
287 ; SI-DAG: buffer_store_dwordx2 v
289 define void @merge_global_store_3_adjacent_loads_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
290 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
291 %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
292 %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
293 %in.gep.2 = getelementptr i32, i32 addrspace(1)* %in, i32 2
295 %x = load i32, i32 addrspace(1)* %in
296 %y = load i32, i32 addrspace(1)* %in.gep.1
297 %z = load i32, i32 addrspace(1)* %in.gep.2
299 store i32 %x, i32 addrspace(1)* %out
300 store i32 %y, i32 addrspace(1)* %out.gep.1
301 store i32 %z, i32 addrspace(1)* %out.gep.2
305 ; GCN-LABEL: {{^}}merge_global_store_4_adjacent_loads_f32:
306 ; GCN: buffer_load_dwordx4 [[LOAD:v\[[0-9]+:[0-9]+\]]]
307 ; GCN: buffer_store_dwordx4 [[LOAD]]
308 define void @merge_global_store_4_adjacent_loads_f32(float addrspace(1)* %out, float addrspace(1)* %in) #0 {
309 %out.gep.1 = getelementptr float, float addrspace(1)* %out, i32 1
310 %out.gep.2 = getelementptr float, float addrspace(1)* %out, i32 2
311 %out.gep.3 = getelementptr float, float addrspace(1)* %out, i32 3
312 %in.gep.1 = getelementptr float, float addrspace(1)* %in, i32 1
313 %in.gep.2 = getelementptr float, float addrspace(1)* %in, i32 2
314 %in.gep.3 = getelementptr float, float addrspace(1)* %in, i32 3
316 %x = load float, float addrspace(1)* %in
317 %y = load float, float addrspace(1)* %in.gep.1
318 %z = load float, float addrspace(1)* %in.gep.2
319 %w = load float, float addrspace(1)* %in.gep.3
321 store float %x, float addrspace(1)* %out
322 store float %y, float addrspace(1)* %out.gep.1
323 store float %z, float addrspace(1)* %out.gep.2
324 store float %w, float addrspace(1)* %out.gep.3
328 ; GCN-LABEL: {{^}}merge_global_store_4_adjacent_loads_i32_nonzero_base:
329 ; GCN: buffer_load_dwordx4 [[LOAD:v\[[0-9]+:[0-9]+\]]], s{{\[[0-9]+:[0-9]+\]}}, 0 offset:44
330 ; GCN: buffer_store_dwordx4 [[LOAD]], s{{\[[0-9]+:[0-9]+\]}}, 0 offset:28
331 define void @merge_global_store_4_adjacent_loads_i32_nonzero_base(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
332 %in.gep.0 = getelementptr i32, i32 addrspace(1)* %in, i32 11
333 %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 12
334 %in.gep.2 = getelementptr i32, i32 addrspace(1)* %in, i32 13
335 %in.gep.3 = getelementptr i32, i32 addrspace(1)* %in, i32 14
336 %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i32 7
337 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 8
338 %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 9
339 %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 10
341 %x = load i32, i32 addrspace(1)* %in.gep.0
342 %y = load i32, i32 addrspace(1)* %in.gep.1
343 %z = load i32, i32 addrspace(1)* %in.gep.2
344 %w = load i32, i32 addrspace(1)* %in.gep.3
346 store i32 %x, i32 addrspace(1)* %out.gep.0
347 store i32 %y, i32 addrspace(1)* %out.gep.1
348 store i32 %z, i32 addrspace(1)* %out.gep.2
349 store i32 %w, i32 addrspace(1)* %out.gep.3
353 ; GCN-LABEL: {{^}}merge_global_store_4_adjacent_loads_inverse_i32:
354 ; GCN: buffer_load_dwordx4 [[LOAD:v\[[0-9]+:[0-9]+\]]]
356 ; GCN: buffer_store_dwordx4 [[LOAD]]
357 define void @merge_global_store_4_adjacent_loads_inverse_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
358 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
359 %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
360 %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 3
361 %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
362 %in.gep.2 = getelementptr i32, i32 addrspace(1)* %in, i32 2
363 %in.gep.3 = getelementptr i32, i32 addrspace(1)* %in, i32 3
365 %x = load i32, i32 addrspace(1)* %in
366 %y = load i32, i32 addrspace(1)* %in.gep.1
367 %z = load i32, i32 addrspace(1)* %in.gep.2
368 %w = load i32, i32 addrspace(1)* %in.gep.3
370 ; Make sure the barrier doesn't stop this
371 tail call void @llvm.AMDGPU.barrier.local() #1
373 store i32 %w, i32 addrspace(1)* %out.gep.3
374 store i32 %z, i32 addrspace(1)* %out.gep.2
375 store i32 %y, i32 addrspace(1)* %out.gep.1
376 store i32 %x, i32 addrspace(1)* %out
381 ; TODO: Re-packing of loaded register required. Maybe an IR pass
384 ; GCN-LABEL: {{^}}merge_global_store_4_adjacent_loads_shuffle_i32:
385 ; GCN: buffer_load_dword v
386 ; GCN: buffer_load_dword v
387 ; GCN: buffer_load_dword v
388 ; GCN: buffer_load_dword v
390 ; GCN: buffer_store_dword v
391 ; GCN: buffer_store_dword v
392 ; GCN: buffer_store_dword v
393 ; GCN: buffer_store_dword v
394 define void @merge_global_store_4_adjacent_loads_shuffle_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
395 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
396 %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
397 %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 3
398 %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
399 %in.gep.2 = getelementptr i32, i32 addrspace(1)* %in, i32 2
400 %in.gep.3 = getelementptr i32, i32 addrspace(1)* %in, i32 3
402 %x = load i32, i32 addrspace(1)* %in
403 %y = load i32, i32 addrspace(1)* %in.gep.1
404 %z = load i32, i32 addrspace(1)* %in.gep.2
405 %w = load i32, i32 addrspace(1)* %in.gep.3
407 ; Make sure the barrier doesn't stop this
408 tail call void @llvm.AMDGPU.barrier.local() #1
410 store i32 %w, i32 addrspace(1)* %out
411 store i32 %z, i32 addrspace(1)* %out.gep.1
412 store i32 %y, i32 addrspace(1)* %out.gep.2
413 store i32 %x, i32 addrspace(1)* %out.gep.3
418 ; GCN-LABEL: {{^}}merge_global_store_4_adjacent_loads_i8:
419 ; GCN: buffer_load_dword [[LOAD:v[0-9]+]]
420 ; GCN: buffer_store_dword [[LOAD]]
422 define void @merge_global_store_4_adjacent_loads_i8(i8 addrspace(1)* %out, i8 addrspace(1)* %in) #0 {
423 %out.gep.1 = getelementptr i8, i8 addrspace(1)* %out, i8 1
424 %out.gep.2 = getelementptr i8, i8 addrspace(1)* %out, i8 2
425 %out.gep.3 = getelementptr i8, i8 addrspace(1)* %out, i8 3
426 %in.gep.1 = getelementptr i8, i8 addrspace(1)* %in, i8 1
427 %in.gep.2 = getelementptr i8, i8 addrspace(1)* %in, i8 2
428 %in.gep.3 = getelementptr i8, i8 addrspace(1)* %in, i8 3
430 %x = load i8, i8 addrspace(1)* %in, align 4
431 %y = load i8, i8 addrspace(1)* %in.gep.1
432 %z = load i8, i8 addrspace(1)* %in.gep.2
433 %w = load i8, i8 addrspace(1)* %in.gep.3
435 store i8 %x, i8 addrspace(1)* %out, align 4
436 store i8 %y, i8 addrspace(1)* %out.gep.1
437 store i8 %z, i8 addrspace(1)* %out.gep.2
438 store i8 %w, i8 addrspace(1)* %out.gep.3
442 ; GCN-LABEL: {{^}}merge_global_store_4_adjacent_loads_i8_natural_align:
443 ; GCN: buffer_load_ubyte
444 ; GCN: buffer_load_ubyte
445 ; GCN: buffer_load_ubyte
446 ; GCN: buffer_load_ubyte
447 ; GCN: buffer_store_byte
448 ; GCN: buffer_store_byte
449 ; GCN: buffer_store_byte
450 ; GCN: buffer_store_byte
452 define void @merge_global_store_4_adjacent_loads_i8_natural_align(i8 addrspace(1)* %out, i8 addrspace(1)* %in) #0 {
453 %out.gep.1 = getelementptr i8, i8 addrspace(1)* %out, i8 1
454 %out.gep.2 = getelementptr i8, i8 addrspace(1)* %out, i8 2
455 %out.gep.3 = getelementptr i8, i8 addrspace(1)* %out, i8 3
456 %in.gep.1 = getelementptr i8, i8 addrspace(1)* %in, i8 1
457 %in.gep.2 = getelementptr i8, i8 addrspace(1)* %in, i8 2
458 %in.gep.3 = getelementptr i8, i8 addrspace(1)* %in, i8 3
460 %x = load i8, i8 addrspace(1)* %in
461 %y = load i8, i8 addrspace(1)* %in.gep.1
462 %z = load i8, i8 addrspace(1)* %in.gep.2
463 %w = load i8, i8 addrspace(1)* %in.gep.3
465 store i8 %x, i8 addrspace(1)* %out
466 store i8 %y, i8 addrspace(1)* %out.gep.1
467 store i8 %z, i8 addrspace(1)* %out.gep.2
468 store i8 %w, i8 addrspace(1)* %out.gep.3
472 ; This works once AA is enabled on the subtarget
473 ; GCN-LABEL: {{^}}merge_global_store_4_vector_elts_loads_v4i32:
474 ; GCN: buffer_load_dwordx4 [[LOAD:v\[[0-9]+:[0-9]+\]]]
475 ; XGCN: buffer_store_dwordx4 [[LOAD]]
476 ; GCN: buffer_store_dword v
477 ; GCN: buffer_store_dword v
478 ; GCN: buffer_store_dword v
479 ; GCN: buffer_store_dword v
480 define void @merge_global_store_4_vector_elts_loads_v4i32(i32 addrspace(1)* %out, <4 x i32> addrspace(1)* %in) #0 {
481 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
482 %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
483 %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 3
484 %vec = load <4 x i32>, <4 x i32> addrspace(1)* %in
486 %x = extractelement <4 x i32> %vec, i32 0
487 %y = extractelement <4 x i32> %vec, i32 1
488 %z = extractelement <4 x i32> %vec, i32 2
489 %w = extractelement <4 x i32> %vec, i32 3
491 store i32 %x, i32 addrspace(1)* %out
492 store i32 %y, i32 addrspace(1)* %out.gep.1
493 store i32 %z, i32 addrspace(1)* %out.gep.2
494 store i32 %w, i32 addrspace(1)* %out.gep.3
498 ; GCN-LABEL: {{^}}merge_local_store_2_constants_i8:
502 define void @merge_local_store_2_constants_i8(i8 addrspace(3)* %out) #0 {
503 %out.gep.1 = getelementptr i8, i8 addrspace(3)* %out, i32 1
505 store i8 123, i8 addrspace(3)* %out.gep.1
506 store i8 456, i8 addrspace(3)* %out, align 2
510 ; GCN-LABEL: {{^}}merge_local_store_2_constants_i32:
511 ; GCN-DAG: s_movk_i32 [[SLO:s[0-9]+]], 0x1c8
512 ; GCN-DAG: s_movk_i32 [[SHI:s[0-9]+]], 0x7b
513 ; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], [[SLO]]
514 ; GCN-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], [[SHI]]
515 ; GCN: ds_write2_b32 v{{[0-9]+}}, v[[LO]], v[[HI]] offset1:1{{$}}
516 define void @merge_local_store_2_constants_i32(i32 addrspace(3)* %out) #0 {
517 %out.gep.1 = getelementptr i32, i32 addrspace(3)* %out, i32 1
519 store i32 123, i32 addrspace(3)* %out.gep.1
520 store i32 456, i32 addrspace(3)* %out
524 ; GCN-LABEL: {{^}}merge_local_store_4_constants_i32:
529 define void @merge_local_store_4_constants_i32(i32 addrspace(3)* %out) #0 {
530 %out.gep.1 = getelementptr i32, i32 addrspace(3)* %out, i32 1
531 %out.gep.2 = getelementptr i32, i32 addrspace(3)* %out, i32 2
532 %out.gep.3 = getelementptr i32, i32 addrspace(3)* %out, i32 3
534 store i32 123, i32 addrspace(3)* %out.gep.1
535 store i32 456, i32 addrspace(3)* %out.gep.2
536 store i32 333, i32 addrspace(3)* %out.gep.3
537 store i32 1234, i32 addrspace(3)* %out
541 ; GCN-LABEL: {{^}}merge_global_store_5_constants_i32:
542 ; GCN-DAG: v_mov_b32_e32 v[[LO:[0-9]+]], 9{{$}}
543 ; GCN-DAG: v_mov_b32_e32 v[[HI4:[0-9]+]], -12{{$}}
544 ; GCN: buffer_store_dwordx4 v{{\[}}[[LO]]:[[HI4]]{{\]}}
545 ; GCN: v_mov_b32_e32 v[[HI:[0-9]+]], 11{{$}}
546 ; GCN: buffer_store_dword v[[HI]]
547 define void @merge_global_store_5_constants_i32(i32 addrspace(1)* %out) {
548 store i32 9, i32 addrspace(1)* %out, align 4
549 %idx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 1
550 store i32 12, i32 addrspace(1)* %idx1, align 4
551 %idx2 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 2
552 store i32 16, i32 addrspace(1)* %idx2, align 4
553 %idx3 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 3
554 store i32 -12, i32 addrspace(1)* %idx3, align 4
555 %idx4 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 4
556 store i32 11, i32 addrspace(1)* %idx4, align 4
560 ; GCN-LABEL: {{^}}merge_global_store_6_constants_i32:
561 ; GCN: buffer_store_dwordx4
562 ; GCN: buffer_store_dwordx2
563 define void @merge_global_store_6_constants_i32(i32 addrspace(1)* %out) {
564 store i32 13, i32 addrspace(1)* %out, align 4
565 %idx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 1
566 store i32 15, i32 addrspace(1)* %idx1, align 4
567 %idx2 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 2
568 store i32 62, i32 addrspace(1)* %idx2, align 4
569 %idx3 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 3
570 store i32 63, i32 addrspace(1)* %idx3, align 4
571 %idx4 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 4
572 store i32 11, i32 addrspace(1)* %idx4, align 4
573 %idx5 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 5
574 store i32 123, i32 addrspace(1)* %idx5, align 4
578 ; GCN-LABEL: {{^}}merge_global_store_7_constants_i32:
579 ; GCN: buffer_store_dwordx4
580 ; GCN: buffer_store_dwordx2
581 ; GCN: buffer_store_dword v
582 define void @merge_global_store_7_constants_i32(i32 addrspace(1)* %out) {
583 store i32 34, i32 addrspace(1)* %out, align 4
584 %idx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 1
585 store i32 999, i32 addrspace(1)* %idx1, align 4
586 %idx2 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 2
587 store i32 65, i32 addrspace(1)* %idx2, align 4
588 %idx3 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 3
589 store i32 33, i32 addrspace(1)* %idx3, align 4
590 %idx4 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 4
591 store i32 98, i32 addrspace(1)* %idx4, align 4
592 %idx5 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 5
593 store i32 91, i32 addrspace(1)* %idx5, align 4
594 %idx6 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 6
595 store i32 212, i32 addrspace(1)* %idx6, align 4
599 ; GCN-LABEL: {{^}}merge_global_store_8_constants_i32:
600 ; XGCN: buffer_store_dwordx4
601 ; XGCN: buffer_store_dwordx4
603 ; GCN: buffer_store_dword v
604 ; GCN: buffer_store_dword v
605 ; GCN: buffer_store_dword v
606 ; GCN: buffer_store_dword v
607 ; GCN: buffer_store_dword v
608 ; GCN: buffer_store_dword v
609 ; GCN: buffer_store_dword v
610 ; GCN: buffer_store_dword v
611 define void @merge_global_store_8_constants_i32(i32 addrspace(1)* %out) {
612 store i32 34, i32 addrspace(1)* %out, align 4
613 %idx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 1
614 store i32 999, i32 addrspace(1)* %idx1, align 4
615 %idx2 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 2
616 store i32 65, i32 addrspace(1)* %idx2, align 4
617 %idx3 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 3
618 store i32 33, i32 addrspace(1)* %idx3, align 4
619 %idx4 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 4
620 store i32 98, i32 addrspace(1)* %idx4, align 4
621 %idx5 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 5
622 store i32 91, i32 addrspace(1)* %idx5, align 4
623 %idx6 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 6
624 store i32 212, i32 addrspace(1)* %idx6, align 4
625 %idx7 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 7
626 store i32 999, i32 addrspace(1)* %idx7, align 4
630 declare void @llvm.AMDGPU.barrier.local() #1
632 attributes #0 = { nounwind }
633 attributes #1 = { noduplicate nounwind }