• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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