1 /*
2 * Copyright © 2020 Valve Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24 #include "helpers.h"
25 #include "sid.h"
26
27 using namespace aco;
28
29 static void
create_mubuf(Temp desc=Temp (0,s8))30 create_mubuf(Temp desc = Temp(0, s8))
31 {
32 Operand desc_op(desc);
33 desc_op.setFixed(PhysReg(0));
34 bld.mubuf(aco_opcode::buffer_load_dword, Definition(PhysReg(256), v1), desc_op,
35 Operand(PhysReg(256), v1), Operand::zero(), 0, false);
36 }
37
38 static void
create_mubuf_store()39 create_mubuf_store()
40 {
41 bld.mubuf(aco_opcode::buffer_store_dword, Operand(PhysReg(0), s4), Operand(PhysReg(256), v1),
42 Operand(PhysReg(256), v1), Operand::zero(), 0, false);
43 }
44
45 static void
create_mtbuf(Temp desc=Temp (0,s8))46 create_mtbuf(Temp desc = Temp(0, s8))
47 {
48 Operand desc_op(desc);
49 desc_op.setFixed(PhysReg(0));
50 bld.mtbuf(aco_opcode::tbuffer_load_format_x, Definition(PhysReg(256), v1), desc_op,
51 Operand(PhysReg(256), v1), Operand::zero(), V_008F0C_BUF_DATA_FORMAT_32,
52 V_008F0C_BUF_NUM_FORMAT_FLOAT, 0, false);
53 }
54
55 static void
create_flat()56 create_flat()
57 {
58 bld.flat(aco_opcode::flat_load_dword, Definition(PhysReg(256), v1), Operand(PhysReg(256), v2),
59 Operand(s2));
60 }
61
62 static void
create_global()63 create_global()
64 {
65 bld.global(aco_opcode::global_load_dword, Definition(PhysReg(256), v1),
66 Operand(PhysReg(256), v2), Operand(s2));
67 }
68
69 static void
create_mimg(bool nsa,Temp desc=Temp (0,s8))70 create_mimg(bool nsa, Temp desc = Temp(0, s8))
71 {
72 aco_ptr<MIMG_instruction> mimg{
73 create_instruction<MIMG_instruction>(aco_opcode::image_sample, Format::MIMG, 5, 1)};
74 mimg->definitions[0] = Definition(PhysReg(256), v1);
75 mimg->operands[0] = Operand(desc);
76 mimg->operands[0].setFixed(PhysReg(0));
77 mimg->operands[1] = Operand(PhysReg(0), s4);
78 mimg->operands[2] = Operand(v1);
79 for (unsigned i = 0; i < 2; i++)
80 mimg->operands[3 + i] = Operand(PhysReg(256 + (nsa ? i * 2 : i)), v1);
81 mimg->dmask = 0x1;
82 mimg->dim = ac_image_2d;
83
84 bld.insert(std::move(mimg));
85 }
86
87 static void
create_smem()88 create_smem()
89 {
90 bld.smem(aco_opcode::s_load_dword, Definition(PhysReg(0), s1), Operand(PhysReg(0), s2),
91 Operand::zero());
92 }
93
94 static void
create_smem_buffer(Temp desc=Temp (0,s4))95 create_smem_buffer(Temp desc = Temp(0, s4))
96 {
97 Operand desc_op(desc);
98 desc_op.setFixed(PhysReg(0));
99 bld.smem(aco_opcode::s_buffer_load_dword, Definition(PhysReg(0), s1), desc_op, Operand::zero());
100 }
101
102 BEGIN_TEST(form_hard_clauses.type_restrictions)
103 if (!setup_cs(NULL, GFX10))
104 return;
105
106 //>> p_unit_test 0
107 //! s_clause imm:1
108 //; search_re('image_sample')
109 //; search_re('image_sample')
110 bld.pseudo(aco_opcode::p_unit_test, Operand::zero());
111 create_mimg(false);
112 create_mimg(false);
113
114 //>> p_unit_test 1
115 //! s_clause imm:1
116 //; search_re('buffer_load_dword')
117 //; search_re('buffer_load_dword')
118 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(1u));
119 create_mubuf();
120 create_mubuf();
121
122 //>> p_unit_test 2
123 //! s_clause imm:1
124 //; search_re('global_load_dword')
125 //; search_re('global_load_dword')
126 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(2u));
127 create_global();
128 create_global();
129
130 //>> p_unit_test 3
131 //! s_clause imm:1
132 //; search_re('flat_load_dword')
133 //; search_re('flat_load_dword')
134 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(3u));
135 create_flat();
136 create_flat();
137
138 //>> p_unit_test 4
139 //! s_clause imm:1
140 //; search_re('s_load_dword')
141 //; search_re('s_load_dword')
142 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(4u));
143 create_smem();
144 create_smem();
145
146 //>> p_unit_test 5
147 //; search_re('buffer_load_dword')
148 //; search_re('flat_load_dword')
149 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(5u));
150 create_mubuf();
151 create_flat();
152
153 //>> p_unit_test 6
154 //; search_re('buffer_load_dword')
155 //; search_re('s_load_dword')
156 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(6u));
157 create_mubuf();
158 create_smem();
159
160 //>> p_unit_test 7
161 //; search_re('flat_load_dword')
162 //; search_re('s_load_dword')
163 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(7u));
164 create_flat();
165 create_smem();
166
167 finish_form_hard_clause_test();
168 END_TEST
169
170 BEGIN_TEST(form_hard_clauses.size)
171 if (!setup_cs(NULL, GFX10))
172 return;
173
174 //>> p_unit_test 0
175 //; search_re('s_load_dword')
176 bld.pseudo(aco_opcode::p_unit_test, Operand::zero());
177 create_smem();
178
179 //>> p_unit_test 1
180 //! s_clause imm:62
181 //; for i in range(63):
182 //; search_re('s_load_dword')
183 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(1u));
184 for (unsigned i = 0; i < 63; i++)
185 create_smem();
186
187 //>> p_unit_test 2
188 //! s_clause imm:62
189 //; for i in range(64):
190 //; search_re('s_load_dword')
191 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(2u));
192 for (unsigned i = 0; i < 64; i++)
193 create_smem();
194
195 //>> p_unit_test 3
196 //! s_clause imm:62
197 //; for i in range(63):
198 //; search_re('s_load_dword')
199 //! s_clause imm:1
200 //; search_re('s_load_dword')
201 //; search_re('s_load_dword')
202 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(3u));
203 for (unsigned i = 0; i < 65; i++)
204 create_smem();
205
206 finish_form_hard_clause_test();
207 END_TEST
208
209 BEGIN_TEST(form_hard_clauses.nsa)
210 for (unsigned i = GFX10; i <= GFX10_3; i++) {
211 if (!setup_cs(NULL, (amd_gfx_level)i))
212 continue;
213
214 //>> p_unit_test 0
215 //! s_clause imm:1
216 //; search_re(r'image_sample .* %0:v\[0\], %0:v\[1\]')
217 //; search_re(r'image_sample .* %0:v\[0\], %0:v\[1\]')
218 bld.pseudo(aco_opcode::p_unit_test, Operand::zero());
219 create_mimg(false);
220 create_mimg(false);
221
222 //>> p_unit_test 1
223 //~gfx10_3! s_clause imm:1
224 //; search_re(r'image_sample .* %0:v\[0\], %0:v\[1\]')
225 //; search_re(r'image_sample .* %0:v\[0\], %0:v\[2\]')
226 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(1u));
227 create_mimg(false);
228 create_mimg(true);
229
230 //>> p_unit_test 2
231 //~gfx10_3! s_clause imm:1
232 //; search_re(r'image_sample .* %0:v\[0\], %0:v\[2\]')
233 //; search_re(r'image_sample .* %0:v\[0\], %0:v\[2\]')
234 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(2u));
235 create_mimg(true);
236 create_mimg(true);
237
238 finish_form_hard_clause_test();
239 }
240 END_TEST
241
242 BEGIN_TEST(form_hard_clauses.heuristic)
243 if (!setup_cs(NULL, GFX10))
244 return;
245
246 Temp img_desc0 = bld.tmp(s8);
247 Temp img_desc1 = bld.tmp(s8);
248 Temp buf_desc0 = bld.tmp(s4);
249 Temp buf_desc1 = bld.tmp(s4);
250
251 /* Don't form clause with different descriptors */
252 //>> p_unit_test 0
253 //! s_clause imm:1
254 //; search_re('image_sample')
255 //; search_re('image_sample')
256 bld.pseudo(aco_opcode::p_unit_test, Operand::zero());
257 create_mimg(false, img_desc0);
258 create_mimg(false, img_desc0);
259
260 //>> p_unit_test 1
261 //; search_re('image_sample')
262 //; search_re('image_sample')
263 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(1u));
264 create_mimg(false, img_desc0);
265 create_mimg(false, img_desc1);
266
267 //>> p_unit_test 2
268 //! s_clause imm:1
269 //; search_re('buffer_load_dword')
270 //; search_re('buffer_load_dword')
271 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(2u));
272 create_mubuf(buf_desc0);
273 create_mubuf(buf_desc0);
274
275 //>> p_unit_test 3
276 //; search_re('buffer_load_dword')
277 //; search_re('buffer_load_dword')
278 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(3u));
279 create_mubuf(buf_desc0);
280 create_mubuf(buf_desc1);
281
282 //>> p_unit_test 4
283 //! s_clause imm:1
284 //; search_re('s_buffer_load_dword')
285 //; search_re('s_buffer_load_dword')
286 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(4u));
287 create_smem_buffer(buf_desc0);
288 create_smem_buffer(buf_desc0);
289
290 //>> p_unit_test 5
291 //; search_re('s_buffer_load_dword')
292 //; search_re('s_buffer_load_dword')
293 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(5u));
294 create_smem_buffer(buf_desc0);
295 create_smem_buffer(buf_desc1);
296
297 //>> p_unit_test 6
298 //; search_re('s_buffer_load_dword')
299 //; search_re('s_load_dword')
300 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(6u));
301 create_smem_buffer(buf_desc0);
302 create_smem();
303
304 /* Only form clause between MUBUF and MTBUF if they load from the same binding. Ignore descriptor
305 * if they're te same binding.
306 */
307 //>> p_unit_test 7
308 //; search_re('buffer_load_dword')
309 //; search_re('tbuffer_load_format_x')
310 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(7u));
311 create_mubuf(buf_desc0);
312 create_mtbuf(buf_desc0);
313
314 finish_form_hard_clause_test();
315 END_TEST
316
317 BEGIN_TEST(form_hard_clauses.stores)
318 for (amd_gfx_level gfx : {GFX10, GFX11}) {
319 if (!setup_cs(NULL, gfx))
320 continue;
321
322 //>> p_unit_test 0
323 //~gfx11! s_clause imm:1
324 //; search_re('buffer_store_dword')
325 //; search_re('buffer_store_dword')
326 bld.pseudo(aco_opcode::p_unit_test, Operand::zero());
327 create_mubuf_store();
328 create_mubuf_store();
329
330 //>> p_unit_test 1
331 //! s_clause imm:1
332 //; search_re('buffer_load_dword')
333 //; search_re('buffer_load_dword')
334 //; search_re('buffer_store_dword')
335 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(1u));
336 create_mubuf();
337 create_mubuf();
338 create_mubuf_store();
339
340 //>> p_unit_test 2
341 //; search_re('buffer_store_dword')
342 //! s_clause imm:1
343 //; search_re('buffer_load_dword')
344 //; search_re('buffer_load_dword')
345 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(2u));
346 create_mubuf_store();
347 create_mubuf();
348 create_mubuf();
349
350 /* Unclear whether this is the best behaviour */
351 //>> p_unit_test 3
352 //; search_re('buffer_load_dword')
353 //; search_re('buffer_store_dword')
354 //; search_re('buffer_load_dword')
355 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(3u));
356 create_mubuf();
357 create_mubuf_store();
358 create_mubuf();
359
360 finish_form_hard_clause_test();
361 }
362 END_TEST
363