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