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
create_mubuf(Temp desc=Temp (0,s8),unsigned vtx_binding=0)29 static void create_mubuf(Temp desc=Temp(0, s8), unsigned vtx_binding=0)
30 {
31 Operand desc_op(desc);
32 desc_op.setFixed(PhysReg(0));
33 bld.mubuf(aco_opcode::buffer_load_dword, Definition(PhysReg(256), v1), desc_op,
34 Operand(PhysReg(256), v1), Operand::zero(), 0, false)
35 .instr->mubuf()
36 .vtx_binding = vtx_binding;
37 }
38
create_mubuf_store()39 static void 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
create_mtbuf(Temp desc=Temp (0,s8),unsigned vtx_binding=0)45 static void create_mtbuf(Temp desc=Temp(0, s8), unsigned vtx_binding=0)
46 {
47 Operand desc_op(desc);
48 desc_op.setFixed(PhysReg(0));
49 bld.mtbuf(aco_opcode::tbuffer_load_format_x, Definition(PhysReg(256), v1), desc_op,
50 Operand(PhysReg(256), v1), Operand::zero(), V_008F0C_BUF_DATA_FORMAT_32,
51 V_008F0C_BUF_NUM_FORMAT_FLOAT, 0, false)
52 .instr->mtbuf()
53 .vtx_binding = vtx_binding;
54 }
55
create_flat()56 static void create_flat()
57 {
58 bld.flat(aco_opcode::flat_load_dword, Definition(PhysReg(256), v1),
59 Operand(PhysReg(256), v2), Operand(s2));
60 }
61
create_global()62 static void create_global()
63 {
64 bld.global(aco_opcode::global_load_dword, Definition(PhysReg(256), v1),
65 Operand(PhysReg(256), v2), Operand(s2));
66 }
67
create_mimg(bool nsa,Temp desc=Temp (0,s8))68 static void create_mimg(bool nsa, Temp desc=Temp(0, s8))
69 {
70 aco_ptr<MIMG_instruction> mimg{create_instruction<MIMG_instruction>(
71 aco_opcode::image_sample, Format::MIMG, 5, 1)};
72 mimg->definitions[0] = Definition(PhysReg(256), v1);
73 mimg->operands[0] = Operand(desc);
74 mimg->operands[0].setFixed(PhysReg(0));
75 mimg->operands[1] = Operand(PhysReg(0), s4);
76 mimg->operands[2] = Operand(v1);
77 for (unsigned i = 0; i < 2; i++)
78 mimg->operands[3 + i] = Operand(PhysReg(256 + (nsa ? i * 2 : i)), v1);
79 mimg->dmask = 0x1;
80 mimg->dim = ac_image_2d;
81
82 bld.insert(std::move(mimg));
83 }
84
create_smem()85 static void create_smem()
86 {
87 bld.smem(aco_opcode::s_load_dword, Definition(PhysReg(0), s1), Operand(PhysReg(0), s2),
88 Operand::zero());
89 }
90
create_smem_buffer(Temp desc=Temp (0,s4))91 static void create_smem_buffer(Temp desc=Temp(0, s4))
92 {
93 Operand desc_op(desc);
94 desc_op.setFixed(PhysReg(0));
95 bld.smem(aco_opcode::s_buffer_load_dword, Definition(PhysReg(0), s1), desc_op, Operand::zero());
96 }
97
98 BEGIN_TEST(form_hard_clauses.type_restrictions)
99 if (!setup_cs(NULL, GFX10))
100 return;
101
102 //>> p_unit_test 0
103 //! s_clause imm:1
104 //; search_re('image_sample')
105 //; search_re('image_sample')
106 bld.pseudo(aco_opcode::p_unit_test, Operand::zero());
107 create_mimg(false);
108 create_mimg(false);
109
110 //>> p_unit_test 1
111 //! s_clause imm:1
112 //; search_re('buffer_load_dword')
113 //; search_re('buffer_load_dword')
114 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(1u));
115 create_mubuf();
116 create_mubuf();
117
118 //>> p_unit_test 2
119 //! s_clause imm:1
120 //; search_re('global_load_dword')
121 //; search_re('global_load_dword')
122 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(2u));
123 create_global();
124 create_global();
125
126 //>> p_unit_test 3
127 //! s_clause imm:1
128 //; search_re('flat_load_dword')
129 //; search_re('flat_load_dword')
130 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(3u));
131 create_flat();
132 create_flat();
133
134 //>> p_unit_test 4
135 //! s_clause imm:1
136 //; search_re('s_load_dword')
137 //; search_re('s_load_dword')
138 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(4u));
139 create_smem();
140 create_smem();
141
142 //>> p_unit_test 5
143 //; search_re('buffer_load_dword')
144 //; search_re('flat_load_dword')
145 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(5u));
146 create_mubuf();
147 create_flat();
148
149 //>> p_unit_test 6
150 //; search_re('buffer_load_dword')
151 //; search_re('s_load_dword')
152 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(6u));
153 create_mubuf();
154 create_smem();
155
156 //>> p_unit_test 7
157 //; search_re('flat_load_dword')
158 //; search_re('s_load_dword')
159 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(7u));
160 create_flat();
161 create_smem();
162
163 finish_form_hard_clause_test();
164 END_TEST
165
166 BEGIN_TEST(form_hard_clauses.size)
167 if (!setup_cs(NULL, GFX10))
168 return;
169
170 //>> p_unit_test 0
171 //; search_re('s_load_dword')
172 bld.pseudo(aco_opcode::p_unit_test, Operand::zero());
173 create_smem();
174
175 //>> p_unit_test 1
176 //! s_clause imm:63
177 //; for i in range(64):
178 //; search_re('s_load_dword')
179 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(1u));
180 for (unsigned i = 0; i < 64; i++)
181 create_smem();
182
183 //>> p_unit_test 2
184 //! s_clause imm:63
185 //; for i in range(65):
186 //; search_re('s_load_dword')
187 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(2u));
188 for (unsigned i = 0; i < 65; i++)
189 create_smem();
190
191 //>> p_unit_test 3
192 //! s_clause imm:63
193 //; for i in range(64):
194 //; search_re('s_load_dword')
195 //! s_clause imm:1
196 //; search_re('s_load_dword')
197 //; search_re('s_load_dword')
198 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(3u));
199 for (unsigned i = 0; i < 66; i++)
200 create_smem();
201
202 finish_form_hard_clause_test();
203 END_TEST
204
205 BEGIN_TEST(form_hard_clauses.nsa)
206 for (unsigned i = GFX10; i <= GFX10_3; i++) {
207 if (!setup_cs(NULL, (chip_class)i))
208 continue;
209
210 //>> p_unit_test 0
211 //! s_clause imm:1
212 //; search_re('image_sample .* %0:v\[0\], %0:v\[1\]')
213 //; search_re('image_sample .* %0:v\[0\], %0:v\[1\]')
214 bld.pseudo(aco_opcode::p_unit_test, Operand::zero());
215 create_mimg(false);
216 create_mimg(false);
217
218 //>> p_unit_test 1
219 //~gfx10_3! s_clause imm:1
220 //; search_re('image_sample .* %0:v\[0\], %0:v\[1\]')
221 //; search_re('image_sample .* %0:v\[0\], %0:v\[2\]')
222 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(1u));
223 create_mimg(false);
224 create_mimg(true);
225
226 //>> p_unit_test 2
227 //~gfx10_3! s_clause imm:1
228 //; search_re('image_sample .* %0:v\[0\], %0:v\[2\]')
229 //; search_re('image_sample .* %0:v\[0\], %0:v\[2\]')
230 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(2u));
231 create_mimg(true);
232 create_mimg(true);
233
234 finish_form_hard_clause_test();
235 }
236 END_TEST
237
238 BEGIN_TEST(form_hard_clauses.heuristic)
239 if (!setup_cs(NULL, GFX10))
240 return;
241
242 Temp img_desc0 = bld.tmp(s8);
243 Temp img_desc1 = bld.tmp(s8);
244 Temp buf_desc0 = bld.tmp(s4);
245 Temp buf_desc1 = bld.tmp(s4);
246
247 /* Don't form clause with different descriptors */
248 //>> p_unit_test 0
249 //! s_clause imm:1
250 //; search_re('image_sample')
251 //; search_re('image_sample')
252 bld.pseudo(aco_opcode::p_unit_test, Operand::zero());
253 create_mimg(false, img_desc0);
254 create_mimg(false, img_desc0);
255
256 //>> p_unit_test 1
257 //; search_re('image_sample')
258 //; search_re('image_sample')
259 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(1u));
260 create_mimg(false, img_desc0);
261 create_mimg(false, img_desc1);
262
263 //>> p_unit_test 2
264 //! s_clause imm:1
265 //; search_re('buffer_load_dword')
266 //; search_re('buffer_load_dword')
267 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(2u));
268 create_mubuf(buf_desc0);
269 create_mubuf(buf_desc0);
270
271 //>> p_unit_test 3
272 //; search_re('buffer_load_dword')
273 //; search_re('buffer_load_dword')
274 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(3u));
275 create_mubuf(buf_desc0);
276 create_mubuf(buf_desc1);
277
278 //>> p_unit_test 4
279 //! s_clause imm:1
280 //; search_re('s_buffer_load_dword')
281 //; search_re('s_buffer_load_dword')
282 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(4u));
283 create_smem_buffer(buf_desc0);
284 create_smem_buffer(buf_desc0);
285
286 //>> p_unit_test 5
287 //; search_re('s_buffer_load_dword')
288 //; search_re('s_buffer_load_dword')
289 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(5u));
290 create_smem_buffer(buf_desc0);
291 create_smem_buffer(buf_desc1);
292
293 //>> p_unit_test 6
294 //; search_re('s_buffer_load_dword')
295 //; search_re('s_load_dword')
296 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(6u));
297 create_smem_buffer(buf_desc0);
298 create_smem();
299
300 /* Only form clause between MUBUF and MTBUF if they load from the same binding. Ignore descriptor
301 * if they're te same binding.
302 */
303 //>> p_unit_test 7
304 //; search_re('buffer_load_dword')
305 //; search_re('tbuffer_load_format_x')
306 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(7u));
307 create_mubuf(buf_desc0);
308 create_mtbuf(buf_desc0);
309
310 //>> p_unit_test 8
311 //! s_clause imm:1
312 //; search_re('buffer_load_dword')
313 //; search_re('tbuffer_load_format_x')
314 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(8u));
315 create_mubuf(buf_desc0, 1);
316 create_mtbuf(buf_desc0, 1);
317
318 //>> p_unit_test 9
319 //! s_clause imm:1
320 //; search_re('buffer_load_dword')
321 //; search_re('tbuffer_load_format_x')
322 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(9u));
323 create_mubuf(buf_desc0, 1);
324 create_mtbuf(buf_desc1, 1);
325
326 finish_form_hard_clause_test();
327 END_TEST
328
329 BEGIN_TEST(form_hard_clauses.stores)
330 if (!setup_cs(NULL, GFX10))
331 return;
332
333 //>> p_unit_test 0
334 //; search_re('buffer_store_dword')
335 //; search_re('buffer_store_dword')
336 bld.pseudo(aco_opcode::p_unit_test, Operand::zero());
337 create_mubuf_store();
338 create_mubuf_store();
339
340 //>> p_unit_test 1
341 //! s_clause imm:1
342 //; search_re('buffer_load_dword')
343 //; search_re('buffer_load_dword')
344 //; search_re('buffer_store_dword')
345 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(1u));
346 create_mubuf();
347 create_mubuf();
348 create_mubuf_store();
349
350 //>> p_unit_test 2
351 //; search_re('buffer_store_dword')
352 //! s_clause imm:1
353 //; search_re('buffer_load_dword')
354 //; search_re('buffer_load_dword')
355 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(2u));
356 create_mubuf_store();
357 create_mubuf();
358 create_mubuf();
359
360 /* Unclear whether this is the best behaviour */
361 //>> p_unit_test 3
362 //; search_re('buffer_load_dword')
363 //; search_re('buffer_store_dword')
364 //; search_re('buffer_load_dword')
365 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(3u));
366 create_mubuf();
367 create_mubuf_store();
368 create_mubuf();
369
370 /* Unimportant pass limitations */
371 //>> p_unit_test 4
372 //; search_re('buffer_store_dword')
373 //! s_clause imm:62
374 //; for i in range(63):
375 //; search_re('buffer_load_dword')
376 //; search_re('buffer_load_dword')
377 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(4u));
378 create_mubuf_store();
379 for (unsigned i = 0; i < 64; i++)
380 create_mubuf();
381
382 //>> p_unit_test 5
383 //! s_clause imm:63
384 //; for i in range(64):
385 //; search_re('buffer_load_dword')
386 //; search_re('buffer_store_dword')
387 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(5u));
388 for (unsigned i = 0; i < 64; i++)
389 create_mubuf();
390 create_mubuf_store();
391
392 finish_form_hard_clause_test();
393 END_TEST
394