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 27using namespace aco; 28 29static 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 39static 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 45static 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 56static 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 62static 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 68static 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 85static 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 91static 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 98BEGIN_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(); 164END_TEST 165 166BEGIN_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(); 203END_TEST 204 205BEGIN_TEST(form_hard_clauses.nsa) 206 for (unsigned i = GFX10; i <= GFX10_3; i++) { 207 if (!setup_cs(NULL, (amd_gfx_level)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 } 236END_TEST 237 238BEGIN_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(); 327END_TEST 328 329BEGIN_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(); 393END_TEST 394