1; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=GCN-NOHSA -check-prefix=FUNC %s
2; RUN: llc -mtriple=amdgcn--amdhsa -mcpu=kaveri -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=GCN-HSA -check-prefix=FUNC %s
3; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=GCN-NOHSA -check-prefix=FUNC %s
4; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
5
6; FUNC-LABEL: {{^}}local_unaligned_load_store_i16:
7; GCN: ds_read_u8
8; GCN: ds_read_u8
9; GCN: ds_write_b8
10; GCN: ds_write_b8
11; GCN: s_endpgm
12define void @local_unaligned_load_store_i16(i16 addrspace(3)* %p, i16 addrspace(3)* %r) #0 {
13  %v = load i16, i16 addrspace(3)* %p, align 1
14  store i16 %v, i16 addrspace(3)* %r, align 1
15  ret void
16}
17
18; FUNC-LABEL: {{^}}unaligned_load_store_i16_global:
19; GCN-NOHSA: buffer_load_ubyte
20; GCN-NOHSA: buffer_load_ubyte
21; GCN-NOHSA: buffer_store_byte
22; GCN-NOHSA: buffer_store_byte
23
24; GCN-HSA: flat_load_ubyte
25; GCN-HSA: flat_load_ubyte
26; GCN-HSA: flat_store_byte
27; GCN-HSA: flat_store_byte
28define void @unaligned_load_store_i16_global(i16 addrspace(1)* %p, i16 addrspace(1)* %r) #0 {
29  %v = load i16, i16 addrspace(1)* %p, align 1
30  store i16 %v, i16 addrspace(1)* %r, align 1
31  ret void
32}
33
34; FUNC-LABEL: {{^}}local_unaligned_load_store_i32:
35; GCN: ds_read_u8
36; GCN: ds_read_u8
37; GCN: ds_read_u8
38; GCN: ds_read_u8
39; GCN: ds_write_b8
40; GCN: ds_write_b8
41; GCN: ds_write_b8
42; GCN: ds_write_b8
43; GCN: s_endpgm
44define void @local_unaligned_load_store_i32(i32 addrspace(3)* %p, i32 addrspace(3)* %r) #0 {
45  %v = load i32, i32 addrspace(3)* %p, align 1
46  store i32 %v, i32 addrspace(3)* %r, align 1
47  ret void
48}
49
50; FUNC-LABEL: {{^}}global_unaligned_load_store_i32:
51; GCN-NOHSA: buffer_load_ubyte
52; GCN-NOHSA: buffer_load_ubyte
53; GCN-NOHSA: buffer_load_ubyte
54; GCN-NOHSA: buffer_load_ubyte
55; GCN-NOHSA: buffer_store_byte
56; GCN-NOHSA: buffer_store_byte
57; GCN-NOHSA: buffer_store_byte
58; GCN-NOHSA: buffer_store_byte
59
60; GCN-HSA: flat_load_ubyte
61; GCN-HSA: flat_load_ubyte
62; GCN-HSA: flat_load_ubyte
63; GCN-HSA: flat_load_ubyte
64; GCN-HSA: flat_store_byte
65; GCN-HSA: flat_store_byte
66; GCN-HSA: flat_store_byte
67; GCN-HSA: flat_store_byte
68define void @global_unaligned_load_store_i32(i32 addrspace(1)* %p, i32 addrspace(1)* %r) #0 {
69  %v = load i32, i32 addrspace(1)* %p, align 1
70  store i32 %v, i32 addrspace(1)* %r, align 1
71  ret void
72}
73
74; FUNC-LABEL: {{^}}global_align2_load_store_i32:
75; GCN-NOHSA: buffer_load_ushort
76; GCN-NOHSA: buffer_load_ushort
77; GCN-NOHSA: buffer_store_short
78; GCN-NOHSA: buffer_store_short
79
80; GCN-HSA: flat_load_ushort
81; GCN-HSA: flat_load_ushort
82; GCN-HSA: flat_store_short
83; GCN-HSA: flat_store_short
84define void @global_align2_load_store_i32(i32 addrspace(1)* %p, i32 addrspace(1)* %r) #0 {
85  %v = load i32, i32 addrspace(1)* %p, align 2
86  store i32 %v, i32 addrspace(1)* %r, align 2
87  ret void
88}
89
90; FUNC-LABEL: {{^}}local_align2_load_store_i32:
91; GCN: ds_read_u16
92; GCN: ds_read_u16
93; GCN: ds_write_b16
94; GCN: ds_write_b16
95define void @local_align2_load_store_i32(i32 addrspace(3)* %p, i32 addrspace(3)* %r) #0 {
96  %v = load i32, i32 addrspace(3)* %p, align 2
97  store i32 %v, i32 addrspace(3)* %r, align 2
98  ret void
99}
100
101; FIXME: Unnecessary packing and unpacking of bytes.
102; FUNC-LABEL: {{^}}local_unaligned_load_store_i64:
103; GCN: ds_read_u8
104; GCN: ds_read_u8
105; GCN: ds_read_u8
106; GCN: ds_read_u8
107; GCN: ds_read_u8
108; GCN: ds_read_u8
109; GCN: ds_read_u8
110; GCN: ds_read_u8
111
112; XGCN-NOT: v_or_b32
113; XGCN-NOT: v_lshl
114; GCN: ds_write_b8
115; XGCN-NOT: v_or_b32
116; XGCN-NOT: v_lshl
117
118; GCN: ds_write_b8
119; XGCN-NOT: v_or_b32
120; XGCN-NOT: v_lshl
121
122; GCN: ds_write_b8
123; XGCN-NOT: v_or_b32
124; XGCN-NOT: v_lshl
125
126; GCN: ds_write_b8
127; XGCN-NOT: v_or_b32
128; XGCN-NOT: v_lshl
129
130; GCN: ds_write_b8
131; XGCN-NOT: v_or_b32
132; XGCN-NOT: v_lshl
133
134; GCN: ds_write_b8
135; XGCN-NOT: v_or_b32
136; XGCN-NOT: v_lshl
137
138; GCN: ds_write_b8
139; XGCN-NOT: v_or_b32
140; XGCN-NOT: v_lshl
141; GCN: ds_write_b8
142; GCN: s_endpgm
143define void @local_unaligned_load_store_i64(i64 addrspace(3)* %p, i64 addrspace(3)* %r) {
144  %v = load i64, i64 addrspace(3)* %p, align 1
145  store i64 %v, i64 addrspace(3)* %r, align 1
146  ret void
147}
148
149; FUNC-LABEL: {{^}}local_unaligned_load_store_v2i32:
150; GCN: ds_read_u8
151; GCN: ds_read_u8
152; GCN: ds_read_u8
153; GCN: ds_read_u8
154; GCN: ds_read_u8
155; GCN: ds_read_u8
156; GCN: ds_read_u8
157; GCN: ds_read_u8
158
159; XGCN-NOT: v_or_b32
160; XGCN-NOT: v_lshl
161; GCN: ds_write_b8
162; XGCN-NOT: v_or_b32
163; XGCN-NOT: v_lshl
164
165; GCN: ds_write_b8
166; XGCN-NOT: v_or_b32
167; XGCN-NOT: v_lshl
168
169; GCN: ds_write_b8
170; XGCN-NOT: v_or_b32
171; XGCN-NOT: v_lshl
172
173; GCN: ds_write_b8
174; XGCN-NOT: v_or_b32
175; XGCN-NOT: v_lshl
176
177; GCN: ds_write_b8
178; XGCN-NOT: v_or_b32
179; XGCN-NOT: v_lshl
180
181; GCN: ds_write_b8
182; XGCN-NOT: v_or_b32
183; XGCN-NOT: v_lshl
184
185; GCN: ds_write_b8
186; XGCN-NOT: v_or_b32
187; XGCN-NOT: v_lshl
188; GCN: ds_write_b8
189; GCN: s_endpgm
190define void @local_unaligned_load_store_v2i32(<2 x i32> addrspace(3)* %p, <2 x i32> addrspace(3)* %r) {
191  %v = load <2 x i32>, <2 x i32> addrspace(3)* %p, align 1
192  store <2 x i32> %v, <2 x i32> addrspace(3)* %r, align 1
193  ret void
194}
195
196; FUNC-LABEL: {{^}}unaligned_load_store_i64_global:
197; GCN-NOHSA: buffer_load_ubyte
198; GCN-NOHSA: buffer_load_ubyte
199; GCN-NOHSA: buffer_load_ubyte
200; GCN-NOHSA: buffer_load_ubyte
201; GCN-NOHSA: buffer_load_ubyte
202; GCN-NOHSA: buffer_load_ubyte
203; GCN-NOHSA: buffer_load_ubyte
204; GCN-NOHSA: buffer_load_ubyte
205
206; GCN-HSA: flat_load_ubyte
207; GCN-HSA: flat_load_ubyte
208; GCN-HSA: flat_load_ubyte
209; GCN-HSA: flat_load_ubyte
210; GCN-HSA: flat_load_ubyte
211; GCN-HSA: flat_load_ubyte
212; GCN-HSA: flat_load_ubyte
213; GCN-HSA: flat_load_ubyte
214
215; XGCN-NOT: v_or_
216; XGCN-NOT: v_lshl
217
218; GCN-NOHSA: buffer_store_byte
219; GCN-NOHSA: buffer_store_byte
220; GCN-NOHSA: buffer_store_byte
221; GCN-NOHSA: buffer_store_byte
222; GCN-NOHSA: buffer_store_byte
223; GCN-NOHSA: buffer_store_byte
224; GCN-NOHSA: buffer_store_byte
225; GCN-NOHSA: buffer_store_byte
226
227; GCN-HSA: flat_store_byte
228; GCN-HSA: flat_store_byte
229; GCN-HSA: flat_store_byte
230; GCN-HSA: flat_store_byte
231; GCN-HSA: flat_store_byte
232; GCN-HSA: flat_store_byte
233; GCN-HSA: flat_store_byte
234; GCN-HSA: flat_store_byte
235define void @unaligned_load_store_i64_global(i64 addrspace(1)* %p, i64 addrspace(1)* %r) #0 {
236  %v = load i64, i64 addrspace(1)* %p, align 1
237  store i64 %v, i64 addrspace(1)* %r, align 1
238  ret void
239}
240
241; FUNC-LABEL: {{^}}local_unaligned_load_store_v4i32:
242; GCN: ds_read_u8
243; GCN: ds_read_u8
244; GCN: ds_read_u8
245; GCN: ds_read_u8
246
247; GCN: ds_read_u8
248; GCN: ds_read_u8
249; GCN: ds_read_u8
250; GCN: ds_read_u8
251
252; GCN: ds_read_u8
253; GCN: ds_read_u8
254; GCN: ds_read_u8
255; GCN: ds_read_u8
256
257; GCN: ds_read_u8
258; GCN: ds_read_u8
259; GCN: ds_read_u8
260; GCN: ds_read_u8
261
262; GCN: ds_write_b8
263; GCN: ds_write_b8
264; GCN: ds_write_b8
265; GCN: ds_write_b8
266
267; GCN: ds_write_b8
268; GCN: ds_write_b8
269; GCN: ds_write_b8
270; GCN: ds_write_b8
271
272; GCN: ds_write_b8
273; GCN: ds_write_b8
274; GCN: ds_write_b8
275; GCN: ds_write_b8
276
277; GCN: ds_write_b8
278; GCN: ds_write_b8
279; GCN: ds_write_b8
280; GCN: ds_write_b8
281; GCN: s_endpgm
282define void @local_unaligned_load_store_v4i32(<4 x i32> addrspace(3)* %p, <4 x i32> addrspace(3)* %r) #0 {
283  %v = load <4 x i32>, <4 x i32> addrspace(3)* %p, align 1
284  store <4 x i32> %v, <4 x i32> addrspace(3)* %r, align 1
285  ret void
286}
287
288; FUNC-LABEL: {{^}}global_unaligned_load_store_v4i32:
289; GCN-NOHSA: buffer_load_ubyte
290; GCN-NOHSA: buffer_load_ubyte
291; GCN-NOHSA: buffer_load_ubyte
292; GCN-NOHSA: buffer_load_ubyte
293; GCN-NOHSA: buffer_load_ubyte
294; GCN-NOHSA: buffer_load_ubyte
295; GCN-NOHSA: buffer_load_ubyte
296; GCN-NOHSA: buffer_load_ubyte
297; GCN-NOHSA: buffer_load_ubyte
298; GCN-NOHSA: buffer_load_ubyte
299; GCN-NOHSA: buffer_load_ubyte
300; GCN-NOHSA: buffer_load_ubyte
301; GCN-NOHSA: buffer_load_ubyte
302; GCN-NOHSA: buffer_load_ubyte
303; GCN-NOHSA: buffer_load_ubyte
304; GCN-NOHSA: buffer_load_ubyte
305
306; GCN-NOHSA: buffer_store_byte
307; GCN-NOHSA: buffer_store_byte
308; GCN-NOHSA: buffer_store_byte
309; GCN-NOHSA: buffer_store_byte
310; GCN-NOHSA: buffer_store_byte
311; GCN-NOHSA: buffer_store_byte
312; GCN-NOHSA: buffer_store_byte
313; GCN-NOHSA: buffer_store_byte
314; GCN-NOHSA: buffer_store_byte
315; GCN-NOHSA: buffer_store_byte
316; GCN-NOHSA: buffer_store_byte
317; GCN-NOHSA: buffer_store_byte
318; GCN-NOHSA: buffer_store_byte
319; GCN-NOHSA: buffer_store_byte
320; GCN-NOHSA: buffer_store_byte
321; GCN-NOHSA: buffer_store_byte
322
323
324; GCN-HSA: flat_load_ubyte
325; GCN-HSA: flat_load_ubyte
326; GCN-HSA: flat_load_ubyte
327; GCN-HSA: flat_load_ubyte
328; GCN-HSA: flat_load_ubyte
329; GCN-HSA: flat_load_ubyte
330; GCN-HSA: flat_load_ubyte
331; GCN-HSA: flat_load_ubyte
332; GCN-HSA: flat_load_ubyte
333; GCN-HSA: flat_load_ubyte
334; GCN-HSA: flat_load_ubyte
335; GCN-HSA: flat_load_ubyte
336; GCN-HSA: flat_load_ubyte
337; GCN-HSA: flat_load_ubyte
338; GCN-HSA: flat_load_ubyte
339; GCN-HSA: flat_load_ubyte
340
341; GCN-HSA: flat_store_byte
342; GCN-HSA: flat_store_byte
343; GCN-HSA: flat_store_byte
344; GCN-HSA: flat_store_byte
345; GCN-HSA: flat_store_byte
346; GCN-HSA: flat_store_byte
347; GCN-HSA: flat_store_byte
348; GCN-HSA: flat_store_byte
349; GCN-HSA: flat_store_byte
350; GCN-HSA: flat_store_byte
351; GCN-HSA: flat_store_byte
352; GCN-HSA: flat_store_byte
353; GCN-HSA: flat_store_byte
354; GCN-HSA: flat_store_byte
355; GCN-HSA: flat_store_byte
356; GCN-HSA: flat_store_byte
357define void @global_unaligned_load_store_v4i32(<4 x i32> addrspace(1)* %p, <4 x i32> addrspace(1)* %r) #0 {
358  %v = load <4 x i32>, <4 x i32> addrspace(1)* %p, align 1
359  store <4 x i32> %v, <4 x i32> addrspace(1)* %r, align 1
360  ret void
361}
362
363; FUNC-LABEL: {{^}}local_load_i64_align_4:
364; GCN: ds_read2_b32
365define void @local_load_i64_align_4(i64 addrspace(1)* nocapture %out, i64 addrspace(3)* %in) #0 {
366  %val = load i64, i64 addrspace(3)* %in, align 4
367  store i64 %val, i64 addrspace(1)* %out, align 8
368  ret void
369}
370
371; FUNC-LABEL: {{^}}local_load_i64_align_4_with_offset
372; GCN: ds_read2_b32 v[{{[0-9]+}}:{{[0-9]+}}], v{{[0-9]}} offset0:8 offset1:9
373define void @local_load_i64_align_4_with_offset(i64 addrspace(1)* nocapture %out, i64 addrspace(3)* %in) #0 {
374  %ptr = getelementptr i64, i64 addrspace(3)* %in, i32 4
375  %val = load i64, i64 addrspace(3)* %ptr, align 4
376  store i64 %val, i64 addrspace(1)* %out, align 8
377  ret void
378}
379
380; FUNC-LABEL: {{^}}local_load_i64_align_4_with_split_offset:
381; The tests for the case where the lo offset is 8-bits, but the hi offset is 9-bits
382; GCN: ds_read2_b32 v[{{[0-9]+}}:{{[0-9]+}}], v{{[0-9]}} offset1:1
383; GCN: s_endpgm
384define void @local_load_i64_align_4_with_split_offset(i64 addrspace(1)* nocapture %out, i64 addrspace(3)* %in) #0 {
385  %ptr = bitcast i64 addrspace(3)* %in to i32 addrspace(3)*
386  %ptr255 = getelementptr i32, i32 addrspace(3)* %ptr, i32 255
387  %ptri64 = bitcast i32 addrspace(3)* %ptr255 to i64 addrspace(3)*
388  %val = load i64, i64 addrspace(3)* %ptri64, align 4
389  store i64 %val, i64 addrspace(1)* %out, align 8
390  ret void
391}
392
393; FUNC-LABEL: {{^}}local_load_i64_align_1:
394; GCN: ds_read_u8
395; GCN: ds_read_u8
396; GCN: ds_read_u8
397; GCN: ds_read_u8
398; GCN: ds_read_u8
399; GCN: ds_read_u8
400; GCN: ds_read_u8
401; GCN: ds_read_u8
402; GCN: store_dwordx2
403define void @local_load_i64_align_1(i64 addrspace(1)* nocapture %out, i64 addrspace(3)* %in) #0 {
404  %val = load i64, i64 addrspace(3)* %in, align 1
405  store i64 %val, i64 addrspace(1)* %out, align 8
406  ret void
407}
408
409; FUNC-LABEL: {{^}}local_store_i64_align_4:
410; GCN: ds_write2_b32
411define void @local_store_i64_align_4(i64 addrspace(3)* %out, i64 %val) #0 {
412  store i64 %val, i64 addrspace(3)* %out, align 4
413  ret void
414}
415
416; FUNC-LABEL: {{^}}local_store_i64_align_4_with_offset
417; GCN: ds_write2_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset0:8 offset1:9
418; GCN: s_endpgm
419define void @local_store_i64_align_4_with_offset(i64 addrspace(3)* %out) #0 {
420  %ptr = getelementptr i64, i64 addrspace(3)* %out, i32 4
421  store i64 0, i64 addrspace(3)* %ptr, align 4
422  ret void
423}
424
425; FUNC-LABEL: {{^}}local_store_i64_align_4_with_split_offset:
426; The tests for the case where the lo offset is 8-bits, but the hi offset is 9-bits
427; GCN: ds_write2_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset1:1
428; GCN: s_endpgm
429define void @local_store_i64_align_4_with_split_offset(i64 addrspace(3)* %out) #0 {
430  %ptr = bitcast i64 addrspace(3)* %out to i32 addrspace(3)*
431  %ptr255 = getelementptr i32, i32 addrspace(3)* %ptr, i32 255
432  %ptri64 = bitcast i32 addrspace(3)* %ptr255 to i64 addrspace(3)*
433  store i64 0, i64 addrspace(3)* %out, align 4
434  ret void
435}
436
437; FUNC-LABEL: {{^}}constant_load_unaligned_i16:
438; GCN-NOHSA: buffer_load_ushort
439; GCN-HSA: flat_load_ushort
440
441; EG: VTX_READ_16 T{{[0-9]+\.X, T[0-9]+\.X}}
442define void @constant_load_unaligned_i16(i32 addrspace(1)* %out, i16 addrspace(2)* %in) {
443entry:
444  %tmp0 = getelementptr i16, i16 addrspace(2)* %in, i32 1
445  %tmp1 = load i16, i16 addrspace(2)* %tmp0
446  %tmp2 = zext i16 %tmp1 to i32
447  store i32 %tmp2, i32 addrspace(1)* %out
448  ret void
449}
450
451; FUNC-LABEL: {{^}}constant_load_unaligned_i32:
452; GCN-NOHSA: buffer_load_ubyte
453; GCN-NOHSA: buffer_load_ubyte
454; GCN-NOHSA: buffer_load_ubyte
455; GCN-NOHSA: buffer_load_ubyte
456
457; GCN-HSA: flat_load_ubyte
458; GCN-HSA: flat_load_ubyte
459; GCN-HSA: flat_load_ubyte
460; GCN-HSA: flat_load_ubyte
461define void @constant_load_unaligned_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in) {
462entry:
463  %tmp0 = load i32, i32 addrspace(2)* %in, align 1
464  store i32 %tmp0, i32 addrspace(1)* %out
465  ret void
466}
467
468; FUNC-LABEL: {{^}}constant_load_unaligned_f32:
469; GCN-NOHSA: buffer_load_ubyte
470; GCN-NOHSA: buffer_load_ubyte
471; GCN-NOHSA: buffer_load_ubyte
472; GCN-NOHSA: buffer_load_ubyte
473
474; GCN-HSA: flat_load_ubyte
475; GCN-HSA: flat_load_ubyte
476; GCN-HSA: flat_load_ubyte
477; GCN-HSA: flat_load_ubyte
478define void @constant_load_unaligned_f32(float addrspace(1)* %out, float addrspace(2)* %in) {
479  %tmp1 = load float, float addrspace(2)* %in, align 1
480  store float %tmp1, float addrspace(1)* %out
481  ret void
482}
483
484attributes #0 = { nounwind }
485