1;RUN: llc < %s -march=amdgcn -mcpu=verde -verify-machineinstrs | FileCheck %s -check-prefix=CHECK -check-prefix=SICI
2;RUN: llc < %s -march=amdgcn -mcpu=tonga -verify-machineinstrs | FileCheck %s -check-prefix=CHECK -check-prefix=VI
3
4;CHECK-LABEL: {{^}}buffer_load:
5;CHECK: buffer_load_dwordx4 v[0:3], off, s[0:3], 0
6;CHECK: buffer_load_dwordx4 v[4:7], off, s[0:3], 0 glc
7;CHECK: buffer_load_dwordx4 v[8:11], off, s[0:3], 0 slc
8define amdgpu_ps {<4 x float>, <4 x float>, <4 x float>} @buffer_load(<4 x i32> inreg) {
9main_body:
10  %data = call <4 x float> @llvm.amdgcn.buffer.load.v4f32(<4 x i32> %0, i32 0, i32 0, i1 0, i1 0)
11  %data_glc = call <4 x float> @llvm.amdgcn.buffer.load.v4f32(<4 x i32> %0, i32 0, i32 0, i1 1, i1 0)
12  %data_slc = call <4 x float> @llvm.amdgcn.buffer.load.v4f32(<4 x i32> %0, i32 0, i32 0, i1 0, i1 1)
13  %r0 = insertvalue {<4 x float>, <4 x float>, <4 x float>} undef, <4 x float> %data, 0
14  %r1 = insertvalue {<4 x float>, <4 x float>, <4 x float>} %r0, <4 x float> %data_glc, 1
15  %r2 = insertvalue {<4 x float>, <4 x float>, <4 x float>} %r1, <4 x float> %data_slc, 2
16  ret {<4 x float>, <4 x float>, <4 x float>} %r2
17}
18
19;CHECK-LABEL: {{^}}buffer_load_immoffs:
20;CHECK: buffer_load_dwordx4 v[0:3], off, s[0:3], 0 offset:40
21define amdgpu_ps <4 x float> @buffer_load_immoffs(<4 x i32> inreg) {
22main_body:
23  %data = call <4 x float> @llvm.amdgcn.buffer.load.v4f32(<4 x i32> %0, i32 0, i32 40, i1 0, i1 0)
24  ret <4 x float> %data
25}
26
27;CHECK-LABEL: {{^}}buffer_load_immoffs_large:
28;SICI: buffer_load_dwordx4 v[0:3], {{v[0-9]+}}, s[0:3], 0 offen
29;VI: s_movk_i32 [[OFFSET:s[0-9]+]], 0x1ffc
30;VI: buffer_load_dwordx4 v[0:3], off, s[0:3], [[OFFSET]] offset:4
31define amdgpu_ps <4 x float> @buffer_load_immoffs_large(<4 x i32> inreg) {
32main_body:
33  %data = call <4 x float> @llvm.amdgcn.buffer.load.v4f32(<4 x i32> %0, i32 0, i32 8192, i1 0, i1 0)
34  ret <4 x float> %data
35}
36
37;CHECK-LABEL: {{^}}buffer_load_idx:
38;CHECK: buffer_load_dwordx4 v[0:3], v0, s[0:3], 0 idxen
39define amdgpu_ps <4 x float> @buffer_load_idx(<4 x i32> inreg, i32) {
40main_body:
41  %data = call <4 x float> @llvm.amdgcn.buffer.load.v4f32(<4 x i32> %0, i32 %1, i32 0, i1 0, i1 0)
42  ret <4 x float> %data
43}
44
45;CHECK-LABEL: {{^}}buffer_load_ofs:
46;CHECK: buffer_load_dwordx4 v[0:3], v0, s[0:3], 0 offen
47define amdgpu_ps <4 x float> @buffer_load_ofs(<4 x i32> inreg, i32) {
48main_body:
49  %data = call <4 x float> @llvm.amdgcn.buffer.load.v4f32(<4 x i32> %0, i32 0, i32 %1, i1 0, i1 0)
50  ret <4 x float> %data
51}
52
53;CHECK-LABEL: {{^}}buffer_load_ofs_imm:
54;CHECK: buffer_load_dwordx4 v[0:3], v0, s[0:3], 0 offen offset:60
55define amdgpu_ps <4 x float> @buffer_load_ofs_imm(<4 x i32> inreg, i32) {
56main_body:
57  %ofs = add i32 %1, 60
58  %data = call <4 x float> @llvm.amdgcn.buffer.load.v4f32(<4 x i32> %0, i32 0, i32 %ofs, i1 0, i1 0)
59  ret <4 x float> %data
60}
61
62;CHECK-LABEL: {{^}}buffer_load_both:
63;CHECK: buffer_load_dwordx4 v[0:3], v[0:1], s[0:3], 0 idxen offen
64define amdgpu_ps <4 x float> @buffer_load_both(<4 x i32> inreg, i32, i32) {
65main_body:
66  %data = call <4 x float> @llvm.amdgcn.buffer.load.v4f32(<4 x i32> %0, i32 %1, i32 %2, i1 0, i1 0)
67  ret <4 x float> %data
68}
69
70;CHECK-LABEL: {{^}}buffer_load_both_reversed:
71;CHECK: v_mov_b32_e32 v2, v0
72;CHECK: buffer_load_dwordx4 v[0:3], v[1:2], s[0:3], 0 idxen offen
73define amdgpu_ps <4 x float> @buffer_load_both_reversed(<4 x i32> inreg, i32, i32) {
74main_body:
75  %data = call <4 x float> @llvm.amdgcn.buffer.load.v4f32(<4 x i32> %0, i32 %2, i32 %1, i1 0, i1 0)
76  ret <4 x float> %data
77}
78
79;CHECK-LABEL: {{^}}buffer_load_x1:
80;CHECK: buffer_load_dword v0, v[0:1], s[0:3], 0 idxen offen
81define amdgpu_ps float @buffer_load_x1(<4 x i32> inreg %rsrc, i32 %idx, i32 %ofs) {
82main_body:
83  %data = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 %idx, i32 %ofs, i1 0, i1 0)
84  ret float %data
85}
86
87;CHECK-LABEL: {{^}}buffer_load_x2:
88;CHECK: buffer_load_dwordx2 v[0:1], v[0:1], s[0:3], 0 idxen offen
89define amdgpu_ps <2 x float> @buffer_load_x2(<4 x i32> inreg %rsrc, i32 %idx, i32 %ofs) {
90main_body:
91  %data = call <2 x float> @llvm.amdgcn.buffer.load.v2f32(<4 x i32> %rsrc, i32 %idx, i32 %ofs, i1 0, i1 0)
92  ret <2 x float> %data
93}
94
95;CHECK-LABEL: {{^}}buffer_load_negative_offset:
96;CHECK: v_add_{{[iu]}}32_e32 [[VOFS:v[0-9]+]], vcc, -16, v0
97;CHECK: buffer_load_dwordx4 v[0:3], [[VOFS]], s[0:3], 0 offen
98define amdgpu_ps <4 x float> @buffer_load_negative_offset(<4 x i32> inreg, i32 %ofs) {
99main_body:
100  %ofs.1 = add i32 %ofs, -16
101  %data = call <4 x float> @llvm.amdgcn.buffer.load.v4f32(<4 x i32> %0, i32 0, i32 %ofs.1, i1 0, i1 0)
102  ret <4 x float> %data
103}
104
105; SI won't merge ds memory operations, because of the signed offset bug, so
106; we only have check lines for VI.
107; CHECK-LABEL: buffer_load_mmo:
108; VI: v_mov_b32_e32 [[ZERO:v[0-9]+]], 0
109; VI: ds_write2_b32 v{{[0-9]+}}, [[ZERO]], [[ZERO]] offset1:4
110define amdgpu_ps float @buffer_load_mmo(<4 x i32> inreg %rsrc, float addrspace(3)* %lds) {
111entry:
112  store float 0.0, float addrspace(3)* %lds
113  %val = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 0, i1 0, i1 0)
114  %tmp2 = getelementptr float, float addrspace(3)* %lds, i32 4
115  store float 0.0, float addrspace(3)* %tmp2
116  ret float %val
117}
118
119;CHECK-LABEL: {{^}}buffer_load_x1_offen_merged:
120;CHECK-NEXT: %bb.
121;CHECK-NEXT: buffer_load_dwordx4 v[{{[0-9]}}:{{[0-9]}}], v0, s[0:3], 0 offen offset:4
122;CHECK-NEXT: buffer_load_dwordx2 v[{{[0-9]}}:{{[0-9]}}], v0, s[0:3], 0 offen offset:28
123define amdgpu_ps void @buffer_load_x1_offen_merged(<4 x i32> inreg %rsrc, i32 %a) {
124main_body:
125  %a1 = add i32 %a, 4
126  %a2 = add i32 %a, 8
127  %a3 = add i32 %a, 12
128  %a4 = add i32 %a, 16
129  %a5 = add i32 %a, 28
130  %a6 = add i32 %a, 32
131  %r1 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 %a1, i1 0, i1 0)
132  %r2 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 %a2, i1 0, i1 0)
133  %r3 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 %a3, i1 0, i1 0)
134  %r4 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 %a4, i1 0, i1 0)
135  %r5 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 %a5, i1 0, i1 0)
136  %r6 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 %a6, i1 0, i1 0)
137  call void @llvm.amdgcn.exp.f32(i32 0, i32 15, float %r1, float %r2, float %r3, float %r4, i1 true, i1 true)
138  call void @llvm.amdgcn.exp.f32(i32 0, i32 15, float %r5, float %r6, float undef, float undef, i1 true, i1 true)
139  ret void
140}
141
142;CHECK-LABEL: {{^}}buffer_load_x1_offen_merged_glc_slc:
143;CHECK-NEXT: %bb.
144;CHECK-NEXT: buffer_load_dwordx2 v[{{[0-9]}}:{{[0-9]}}], v0, s[0:3], 0 offen offset:4{{$}}
145;CHECK-NEXT: buffer_load_dwordx2 v[{{[0-9]}}:{{[0-9]}}], v0, s[0:3], 0 offen offset:12 glc{{$}}
146;CHECK-NEXT: buffer_load_dwordx2 v[{{[0-9]}}:{{[0-9]}}], v0, s[0:3], 0 offen offset:28 glc slc{{$}}
147define amdgpu_ps void @buffer_load_x1_offen_merged_glc_slc(<4 x i32> inreg %rsrc, i32 %a) {
148main_body:
149  %a1 = add i32 %a, 4
150  %a2 = add i32 %a, 8
151  %a3 = add i32 %a, 12
152  %a4 = add i32 %a, 16
153  %a5 = add i32 %a, 28
154  %a6 = add i32 %a, 32
155  %r1 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 %a1, i1 0, i1 0)
156  %r2 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 %a2, i1 0, i1 0)
157  %r3 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 %a3, i1 1, i1 0)
158  %r4 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 %a4, i1 1, i1 0)
159  %r5 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 %a5, i1 1, i1 1)
160  %r6 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 %a6, i1 1, i1 1)
161  call void @llvm.amdgcn.exp.f32(i32 0, i32 15, float %r1, float %r2, float %r3, float %r4, i1 true, i1 true)
162  call void @llvm.amdgcn.exp.f32(i32 0, i32 15, float %r5, float %r6, float undef, float undef, i1 true, i1 true)
163  ret void
164}
165
166;CHECK-LABEL: {{^}}buffer_load_x2_offen_merged:
167;CHECK-NEXT: %bb.
168;CHECK-NEXT: buffer_load_dwordx4 v[{{[0-9]}}:{{[0-9]}}], v0, s[0:3], 0 offen offset:4
169define amdgpu_ps void @buffer_load_x2_offen_merged(<4 x i32> inreg %rsrc, i32 %a) {
170main_body:
171  %a1 = add i32 %a, 4
172  %a2 = add i32 %a, 12
173  %vr1 = call <2 x float> @llvm.amdgcn.buffer.load.v2f32(<4 x i32> %rsrc, i32 0, i32 %a1, i1 0, i1 0)
174  %vr2 = call <2 x float> @llvm.amdgcn.buffer.load.v2f32(<4 x i32> %rsrc, i32 0, i32 %a2, i1 0, i1 0)
175  %r1 = extractelement <2 x float> %vr1, i32 0
176  %r2 = extractelement <2 x float> %vr1, i32 1
177  %r3 = extractelement <2 x float> %vr2, i32 0
178  %r4 = extractelement <2 x float> %vr2, i32 1
179  call void @llvm.amdgcn.exp.f32(i32 0, i32 15, float %r1, float %r2, float %r3, float %r4, i1 true, i1 true)
180  ret void
181}
182
183;CHECK-LABEL: {{^}}buffer_load_x3_offen_merged:
184;CHECK-NEXT: %bb.
185;VI-NEXT: buffer_load_dwordx3 v[{{[0-9]}}:{{[0-9]}}], v0, s[0:3], 0 offen offset:4
186define amdgpu_ps void @buffer_load_x3_offen_merged(<4 x i32> inreg %rsrc, i32 %a) {
187main_body:
188  %a1 = add i32 %a, 4
189  %a2 = add i32 %a, 12
190  %vr1 = call <2 x float> @llvm.amdgcn.buffer.load.v2f32(<4 x i32> %rsrc, i32 0, i32 %a1, i1 0, i1 0)
191  %r3 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 %a2, i1 0, i1 0)
192  %r1 = extractelement <2 x float> %vr1, i32 0
193  %r2 = extractelement <2 x float> %vr1, i32 1
194  call void @llvm.amdgcn.exp.f32(i32 0, i32 15, float %r1, float %r2, float %r3, float undef, i1 true, i1 true)
195  ret void
196}
197
198;CHECK-LABEL: {{^}}buffer_load_x1_offset_merged:
199;CHECK-NEXT: %bb.
200;CHECK-NEXT: buffer_load_dwordx4 v[{{[0-9]}}:{{[0-9]}}], off, s[0:3], 0 offset:4
201;CHECK-NEXT: buffer_load_dwordx2 v[{{[0-9]}}:{{[0-9]}}], off, s[0:3], 0 offset:28
202define amdgpu_ps void @buffer_load_x1_offset_merged(<4 x i32> inreg %rsrc) {
203main_body:
204  %r1 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 4, i1 0, i1 0)
205  %r2 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 8, i1 0, i1 0)
206  %r3 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 12, i1 0, i1 0)
207  %r4 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 16, i1 0, i1 0)
208  %r5 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 28, i1 0, i1 0)
209  %r6 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 32, i1 0, i1 0)
210  call void @llvm.amdgcn.exp.f32(i32 0, i32 15, float %r1, float %r2, float %r3, float %r4, i1 true, i1 true)
211  call void @llvm.amdgcn.exp.f32(i32 0, i32 15, float %r5, float %r6, float undef, float undef, i1 true, i1 true)
212  ret void
213}
214
215;CHECK-LABEL: {{^}}buffer_load_x2_offset_merged:
216;CHECK-NEXT: %bb.
217;CHECK-NEXT: buffer_load_dwordx4 v[{{[0-9]}}:{{[0-9]}}], off, s[0:3], 0 offset:4
218define amdgpu_ps void @buffer_load_x2_offset_merged(<4 x i32> inreg %rsrc) {
219main_body:
220  %vr1 = call <2 x float> @llvm.amdgcn.buffer.load.v2f32(<4 x i32> %rsrc, i32 0, i32 4, i1 0, i1 0)
221  %vr2 = call <2 x float> @llvm.amdgcn.buffer.load.v2f32(<4 x i32> %rsrc, i32 0, i32 12, i1 0, i1 0)
222  %r1 = extractelement <2 x float> %vr1, i32 0
223  %r2 = extractelement <2 x float> %vr1, i32 1
224  %r3 = extractelement <2 x float> %vr2, i32 0
225  %r4 = extractelement <2 x float> %vr2, i32 1
226  call void @llvm.amdgcn.exp.f32(i32 0, i32 15, float %r1, float %r2, float %r3, float %r4, i1 true, i1 true)
227  ret void
228}
229
230;CHECK-LABEL: {{^}}buffer_load_x3_offset_merged:
231;CHECK-NEXT: %bb.
232;VI-NEXT: buffer_load_dwordx3 v[{{[0-9]}}:{{[0-9]}}], off, s[0:3], 0 offset:4
233define amdgpu_ps void @buffer_load_x3_offset_merged(<4 x i32> inreg %rsrc) {
234main_body:
235  %vr1 = call <2 x float> @llvm.amdgcn.buffer.load.v2f32(<4 x i32> %rsrc, i32 0, i32 4, i1 0, i1 0)
236  %r3 = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 0, i32 12, i1 0, i1 0)
237  %r1 = extractelement <2 x float> %vr1, i32 0
238  %r2 = extractelement <2 x float> %vr1, i32 1
239  call void @llvm.amdgcn.exp.f32(i32 0, i32 15, float %r1, float %r2, float %r3, float undef, i1 true, i1 true)
240  ret void
241}
242
243;CHECK-LABEL: {{^}}buffer_load_ubyte:
244;CHECK-NEXT: %bb.
245;CHECK-NEXT: buffer_load_ubyte v{{[0-9]}}, off, s[0:3], 0 offset:8
246;CHECK-NEXT: s_waitcnt vmcnt(0)
247;CHECK-NEXT: v_cvt_f32_ubyte0_e32 v0, v0
248;CHECK-NEXT: ; return to shader part epilog
249define amdgpu_ps float @buffer_load_ubyte(<4 x i32> inreg %rsrc) {
250main_body:
251  %tmp = call i8 @llvm.amdgcn.buffer.load.i8(<4 x i32> %rsrc, i32 0, i32 8, i1 0, i1 0)
252  %val = uitofp i8 %tmp to float
253  ret float %val
254}
255
256;CHECK-LABEL: {{^}}buffer_load_ushort:
257;CHECK-NEXT: %bb.
258;CHECK-NEXT: buffer_load_ushort v{{[0-9]}}, off, s[0:3], 0 offset:16
259;CHECK-NEXT: s_waitcnt vmcnt(0)
260;CHECK-NEXT: v_cvt_f32_u32_e32 v0, v0
261;CHECK-NEXT: ; return to shader part epilog
262define amdgpu_ps float @buffer_load_ushort(<4 x i32> inreg %rsrc) {
263main_body:
264  %tmp = call i16 @llvm.amdgcn.buffer.load.i16(<4 x i32> %rsrc, i32 0, i32 16, i1 0, i1 0)
265  %tmp2 = zext i16 %tmp to i32
266  %val = uitofp i32 %tmp2 to float
267  ret float %val
268}
269
270;CHECK-LABEL: {{^}}buffer_load_sbyte:
271;CHECK-NEXT: %bb.
272;CHECK-NEXT: buffer_load_sbyte v{{[0-9]}}, off, s[0:3], 0 offset:8
273;CHECK-NEXT: s_waitcnt vmcnt(0)
274;CHECK-NEXT: v_cvt_f32_i32_e32 v0, v0
275;CHECK-NEXT: ; return to shader part epilog
276define amdgpu_ps float @buffer_load_sbyte(<4 x i32> inreg %rsrc) {
277main_body:
278  %tmp = call i8 @llvm.amdgcn.buffer.load.i8(<4 x i32> %rsrc, i32 0, i32 8, i1 0, i1 0)
279  %tmp2 = sext i8 %tmp to i32
280  %val = sitofp i32 %tmp2 to float
281  ret float %val
282}
283
284;CHECK-LABEL: {{^}}buffer_load_sshort:
285;CHECK-NEXT: %bb.
286;CHECK-NEXT: buffer_load_sshort v{{[0-9]}}, off, s[0:3], 0 offset:16
287;CHECK-NEXT: s_waitcnt vmcnt(0)
288;CHECK-NEXT: v_cvt_f32_i32_e32 v0, v0
289;CHECK-NEXT: ; return to shader part epilog
290define amdgpu_ps float @buffer_load_sshort(<4 x i32> inreg %rsrc) {
291main_body:
292  %tmp = call i16 @llvm.amdgcn.buffer.load.i16(<4 x i32> %rsrc, i32 0, i32 16, i1 0, i1 0)
293  %tmp2 = sext i16 %tmp to i32
294  %val = sitofp i32 %tmp2 to float
295  ret float %val
296}
297
298;CHECK-LABEL: {{^}}buffer_load_ubyte_bitcast:
299;CHECK-NEXT: %bb.
300;CHECK-NEXT: buffer_load_ubyte v{{[0-9]}}, off, s[0:3], 0 offset:8
301;CHECK-NEXT: ; return to shader part epilog
302define amdgpu_ps float @buffer_load_ubyte_bitcast(<4 x i32> inreg %rsrc) {
303main_body:
304  %tmp = call i8 @llvm.amdgcn.buffer.load.i8(<4 x i32> %rsrc, i32 0, i32 8, i1 0, i1 0)
305  %tmp2 = zext i8 %tmp to i32
306  %val = bitcast i32 %tmp2 to float
307  ret float %val
308}
309
310;CHECK-LABEL: {{^}}buffer_load_ushort_bitcast:
311;CHECK-NEXT: %bb.
312;CHECK-NEXT: buffer_load_ushort v{{[0-9]}}, off, s[0:3], 0 offset:8
313;CHECK-NEXT: ; return to shader part epilog
314define amdgpu_ps float @buffer_load_ushort_bitcast(<4 x i32> inreg %rsrc) {
315main_body:
316  %tmp = call i16 @llvm.amdgcn.buffer.load.i16(<4 x i32> %rsrc, i32 0, i32 8, i1 0, i1 0)
317  %tmp2 = zext i16 %tmp to i32
318  %val = bitcast i32 %tmp2 to float
319  ret float %val
320}
321
322;CHECK-LABEL: {{^}}buffer_load_sbyte_bitcast:
323;CHECK-NEXT: %bb.
324;CHECK-NEXT: buffer_load_sbyte v{{[0-9]}}, off, s[0:3], 0 offset:8
325;CHECK-NEXT: ; return to shader part epilog
326define amdgpu_ps float @buffer_load_sbyte_bitcast(<4 x i32> inreg %rsrc) {
327main_body:
328  %tmp = call i8 @llvm.amdgcn.buffer.load.i8(<4 x i32> %rsrc, i32 0, i32 8, i1 0, i1 0)
329  %tmp2 = sext i8 %tmp to i32
330  %val = bitcast i32 %tmp2 to float
331  ret float %val
332}
333
334;CHECK-LABEL: {{^}}buffer_load_sshort_bitcast:
335;CHECK-NEXT: %bb.
336;CHECK-NEXT: buffer_load_sshort v{{[0-9]}}, off, s[0:3], 0 offset:8
337;CHECK-NEXT: ; return to shader part epilog
338define amdgpu_ps float @buffer_load_sshort_bitcast(<4 x i32> inreg %rsrc) {
339main_body:
340  %tmp = call i16 @llvm.amdgcn.buffer.load.i16(<4 x i32> %rsrc, i32 0, i32 8, i1 0, i1 0)
341  %tmp2 = sext i16 %tmp to i32
342  %val = bitcast i32 %tmp2 to float
343  ret float %val
344}
345
346;CHECK-LABEL: {{^}}buffer_load_ubyte_mul_bitcast:
347;CHECK-NEXT: %bb.
348;CHECK-NEXT: buffer_load_ubyte v{{[0-9]}}, off, s[0:3], 0 offset:8
349;CHECK-NEXT: s_waitcnt vmcnt(0)
350;CHECK-NEXT: v_mul_u32_u24_e32 v{{[0-9]}}, 0xff, v{{[0-9]}}
351;CHECK-NEXT: ; return to shader part epilog
352define amdgpu_ps float @buffer_load_ubyte_mul_bitcast(<4 x i32> inreg %rsrc) {
353main_body:
354  %tmp = call i8 @llvm.amdgcn.buffer.load.i8(<4 x i32> %rsrc, i32 0, i32 8, i1 0, i1 0)
355  %tmp2 = zext i8 %tmp to i32
356  %tmp3 = mul i32 %tmp2, 255
357  %val = bitcast i32 %tmp3 to float
358  ret float %val
359}
360
361;CHECK-LABEL: {{^}}buffer_load_ushort_mul_bitcast:
362;CHECK-NEXT: %bb.
363;CHECK-NEXT: buffer_load_ushort v{{[0-9]}}, off, s[0:3], 0 offset:8
364;CHECK-NEXT: s_waitcnt vmcnt(0)
365;CHECK-NEXT: v_mul_u32_u24_e32 v{{[0-9]}}, 0xff, v{{[0-9]}}
366;CHECK-NEXT: ; return to shader part epilog
367define amdgpu_ps float @buffer_load_ushort_mul_bitcast(<4 x i32> inreg %rsrc) {
368main_body:
369  %tmp = call i16 @llvm.amdgcn.buffer.load.i16(<4 x i32> %rsrc, i32 0, i32 8, i1 0, i1 0)
370  %tmp2 = zext i16 %tmp to i32
371  %tmp3 = mul i32 %tmp2, 255
372  %val = bitcast i32 %tmp3 to float
373  ret float %val
374}
375
376;CHECK-LABEL: {{^}}buffer_load_sbyte_mul_bitcast:
377;CHECK-NEXT: %bb.
378;CHECK-NEXT: buffer_load_sbyte v{{[0-9]}}, off, s[0:3], 0 offset:8
379;CHECK-NEXT: s_waitcnt vmcnt(0)
380;CHECK-NEXT: v_mul_i32_i24_e32 v{{[0-9]}}, 0xff, v{{[0-9]}}
381;CHECK-NEXT: ; return to shader part epilog
382define amdgpu_ps float @buffer_load_sbyte_mul_bitcast(<4 x i32> inreg %rsrc) {
383main_body:
384  %tmp = call i8 @llvm.amdgcn.buffer.load.i8(<4 x i32> %rsrc, i32 0, i32 8, i1 0, i1 0)
385  %tmp2 = sext i8 %tmp to i32
386  %tmp3 = mul i32 %tmp2, 255
387  %val = bitcast i32 %tmp3 to float
388  ret float %val
389}
390
391;CHECK-LABEL: {{^}}buffer_load_sshort_mul_bitcast:
392;CHECK-NEXT: %bb.
393;CHECK-NEXT: buffer_load_sshort v{{[0-9]}}, off, s[0:3], 0 offset:8
394;CHECK-NEXT: s_waitcnt vmcnt(0)
395;CHECK-NEXT: v_mul_i32_i24_e32 v{{[0-9]}}, 0xff, v{{[0-9]}}
396;CHECK-NEXT: ; return to shader part epilog
397define amdgpu_ps float @buffer_load_sshort_mul_bitcast(<4 x i32> inreg %rsrc) {
398main_body:
399  %tmp = call i16 @llvm.amdgcn.buffer.load.i16(<4 x i32> %rsrc, i32 0, i32 8, i1 0, i1 0)
400  %tmp2 = sext i16 %tmp to i32
401  %tmp3 = mul i32 %tmp2, 255
402  %val = bitcast i32 %tmp3 to float
403  ret float %val
404}
405
406;CHECK-LABEL: {{^}}buffer_load_sbyte_type_check:
407;CHECK-NEXT: %bb.
408;CHECK-NEXT: buffer_load_ubyte v{{[0-9]}}, off, s[0:3], 0 offset:8
409;CHECK-NEXT: s_waitcnt vmcnt(0)
410;CHECK-NEXT: v_bfe_i32 v{{[0-9]}}, v{{[0-9]}}, 0, 5
411;CHECK-NEXT: ; return to shader part epilog
412define amdgpu_ps float @buffer_load_sbyte_type_check(<4 x i32> inreg %rsrc) {
413main_body:
414  %tmp = call i8 @llvm.amdgcn.buffer.load.i8(<4 x i32> %rsrc, i32 0, i32 8, i1 0, i1 0)
415  %tmp2 = zext i8 %tmp to i32
416  %tmp3 = shl i32 %tmp2, 27
417  %tmp4 = ashr i32 %tmp3, 27
418  %val = bitcast i32 %tmp4 to float
419  ret float %val
420}
421
422; Make sure a frame index folding doessn't crash on a MUBUF not used
423; for stack access.
424
425; CHECK-LABEL: {{^}}no_fold_fi_imm_soffset:
426; CHECK: v_mov_b32_e32 [[FI:v[0-9]+]], 4{{$}}
427; CHECK-NEXT: buffer_load_dword v0, [[FI]], s{{\[[0-9]+:[0-9]+\]}}, 0 idxen
428define amdgpu_ps float @no_fold_fi_imm_soffset(<4 x i32> inreg %rsrc) {
429  %alloca = alloca i32, addrspace(5)
430  %alloca.cast = ptrtoint i32 addrspace(5)* %alloca to i32
431
432  %ret.val = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 %alloca.cast, i32 0, i1 false, i1 false)
433  ret float %ret.val
434}
435
436; CHECK-LABEL: {{^}}no_fold_fi_reg_soffset:
437; CHECK-DAG: v_mov_b32_e32 v[[FI:[0-9]+]], 4{{$}}
438; CHECK-DAG: v_mov_b32_e32 v[[HI:[0-9]+]], s
439; CHECK: buffer_load_dword v0, v{{\[}}[[FI]]:[[HI]]
440define amdgpu_ps float @no_fold_fi_reg_soffset(<4 x i32> inreg %rsrc, i32 inreg %soffset) {
441  %alloca = alloca i32, addrspace(5)
442  %alloca.cast = ptrtoint i32 addrspace(5)* %alloca to i32
443
444  %ret.val = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> %rsrc, i32 %alloca.cast, i32 %soffset, i1 false, i1 false)
445  ret float %ret.val
446}
447
448declare float @llvm.amdgcn.buffer.load.f32(<4 x i32>, i32, i32, i1, i1) #0
449declare <2 x float> @llvm.amdgcn.buffer.load.v2f32(<4 x i32>, i32, i32, i1, i1) #0
450declare <4 x float> @llvm.amdgcn.buffer.load.v4f32(<4 x i32>, i32, i32, i1, i1) #0
451declare i8 @llvm.amdgcn.buffer.load.i8(<4 x i32>, i32, i32, i1, i1) #0
452declare i16 @llvm.amdgcn.buffer.load.i16(<4 x i32>, i32, i32, i1, i1) #0
453declare void @llvm.amdgcn.exp.f32(i32, i32, float, float, float, float, i1, i1) #0
454
455attributes #0 = { nounwind readonly }
456