From 298d400e5c2bcb3278a0e46387068867e03460f1 Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Tue, 23 Feb 2021 09:54:04 +0000 Subject: [PATCH] aco/tests: add test for NSAToVMEMBug MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Rhys Perry Reviewed-by: Timur Kristóf Part-of: --- src/amd/compiler/aco_builder_h.py | 2 +- src/amd/compiler/tests/helpers.cpp | 7 ++ src/amd/compiler/tests/helpers.h | 1 + src/amd/compiler/tests/meson.build | 1 + src/amd/compiler/tests/test_insert_nops.cpp | 115 ++++++++++++++++++++++++++++ 5 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 src/amd/compiler/tests/test_insert_nops.cpp diff --git a/src/amd/compiler/aco_builder_h.py b/src/amd/compiler/aco_builder_h.py index 502ffc7..563fc4e 100644 --- a/src/amd/compiler/aco_builder_h.py +++ b/src/amd/compiler/aco_builder_h.py @@ -524,7 +524,7 @@ formats = [("pseudo", [Format.PSEUDO], 'Pseudo_instruction', list(itertools.prod ("ds", [Format.DS], 'DS_instruction', [(1, 1), (1, 2), (0, 3), (0, 4)]), ("mubuf", [Format.MUBUF], 'MUBUF_instruction', [(0, 4), (1, 3)]), ("mtbuf", [Format.MTBUF], 'MTBUF_instruction', [(0, 4), (1, 3)]), - ("mimg", [Format.MIMG], 'MIMG_instruction', [(0, 3), (1, 3)]), + ("mimg", [Format.MIMG], 'MIMG_instruction', itertools.product([0, 1], [3, 4, 5, 6, 7])), ("exp", [Format.EXP], 'Export_instruction', [(0, 4)]), ("branch", [Format.PSEUDO_BRANCH], 'Pseudo_branch_instruction', itertools.product([1], [0, 1])), ("barrier", [Format.PSEUDO_BARRIER], 'Pseudo_barrier_instruction', [(0, 0)]), diff --git a/src/amd/compiler/tests/helpers.cpp b/src/amd/compiler/tests/helpers.cpp index f094724..0a83ee6 100644 --- a/src/amd/compiler/tests/helpers.cpp +++ b/src/amd/compiler/tests/helpers.cpp @@ -190,6 +190,13 @@ void finish_to_hw_instr_test() aco_print_program(program.get(), output); } +void finish_insert_nops_test() +{ + finish_program(program.get()); + aco::insert_NOPs(program.get()); + aco_print_program(program.get(), output); +} + void finish_assembler_test() { finish_program(program.get()); diff --git a/src/amd/compiler/tests/helpers.h b/src/amd/compiler/tests/helpers.h index 30ff8ca..bd87f84 100644 --- a/src/amd/compiler/tests/helpers.h +++ b/src/amd/compiler/tests/helpers.h @@ -81,6 +81,7 @@ void finish_validator_test(); void finish_opt_test(); void finish_ra_test(aco::ra_test_policy); void finish_to_hw_instr_test(); +void finish_insert_nops_test(); void finish_assembler_test(); void writeout(unsigned i, aco::Temp tmp=aco::Temp(0, aco::s1)); diff --git a/src/amd/compiler/tests/meson.build b/src/amd/compiler/tests/meson.build index 712a32c..0537f01 100644 --- a/src/amd/compiler/tests/meson.build +++ b/src/amd/compiler/tests/meson.build @@ -24,6 +24,7 @@ aco_tests_files = files( 'main.cpp', 'test_assembler.cpp', 'test_builder.cpp', + 'test_insert_nops.cpp', 'test_isel.cpp', 'test_optimizer.cpp', 'test_regalloc.cpp', diff --git a/src/amd/compiler/tests/test_insert_nops.cpp b/src/amd/compiler/tests/test_insert_nops.cpp new file mode 100644 index 0000000..f0d2a58 --- /dev/null +++ b/src/amd/compiler/tests/test_insert_nops.cpp @@ -0,0 +1,115 @@ +/* + * Copyright © 2020 Valve Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ +#include "helpers.h" + +using namespace aco; + +void create_mubuf(unsigned offset) +{ + bld.mubuf(aco_opcode::buffer_load_dword, Definition(PhysReg(256), v1), + Operand(PhysReg(0), s4), Operand(PhysReg(256), v1), + Operand(0u), offset, true); +} + +void create_mimg(bool nsa, unsigned addrs, unsigned instr_dwords) +{ + aco_ptr mimg{create_instruction( + aco_opcode::image_sample, Format::MIMG, 3 + addrs, 1)}; + mimg->definitions[0] = Definition(PhysReg(256), v1); + mimg->operands[0] = Operand(PhysReg(0), s8); + mimg->operands[1] = Operand(PhysReg(0), s4); + mimg->operands[2] = Operand(v1); + for (unsigned i = 0; i < addrs; i++) + mimg->operands[3 + i] = Operand(PhysReg(256 + (nsa ? i * 2 : i)), v1); + mimg->dmask = 0x1; + mimg->dim = ac_image_2d; + + assert(get_mimg_nsa_dwords(mimg.get()) + 2 == instr_dwords); + + bld.insert(std::move(mimg)); +} + +BEGIN_TEST(insert_nops.nsa_to_vmem_bug) + if (!setup_cs(NULL, GFX10)) + return; + + /* no nop needed because offset&6==0 */ + //>> p_unit_test 0 + //! v1: %0:v[0] = image_sample %0:s[0-7], %0:s[0-3], v1: undef, %0:v[0], %0:v[2], %0:v[4], %0:v[6], %0:v[8], %0:v[10] 2d storage: semantics: scope:invocation + //! v1: %0:v[0] = buffer_load_dword %0:s[0-3], %0:v[0], 0 offset:8 offen storage: semantics: scope:invocation + bld.pseudo(aco_opcode::p_unit_test, Operand(0u)); + create_mimg(true, 6, 4); + create_mubuf(8); + + /* nop needed */ + //! p_unit_test 1 + //! v1: %0:v[0] = image_sample %0:s[0-7], %0:s[0-3], v1: undef, %0:v[0], %0:v[2], %0:v[4], %0:v[6], %0:v[8], %0:v[10] 2d storage: semantics: scope:invocation + //! s_nop + //! v1: %0:v[0] = buffer_load_dword %0:s[0-3], %0:v[0], 0 offset:4 offen storage: semantics: scope:invocation + bld.pseudo(aco_opcode::p_unit_test, Operand(1u)); + create_mimg(true, 6, 4); + create_mubuf(4); + + /* no nop needed because the MIMG is not NSA */ + //! p_unit_test 2 + //! v1: %0:v[0] = image_sample %0:s[0-7], %0:s[0-3], v1: undef, %0:v[0], %0:v[1], %0:v[2], %0:v[3], %0:v[4], %0:v[5] 2d storage: semantics: scope:invocation + //! v1: %0:v[0] = buffer_load_dword %0:s[0-3], %0:v[0], 0 offset:4 offen storage: semantics: scope:invocation + bld.pseudo(aco_opcode::p_unit_test, Operand(2u)); + create_mimg(false, 6, 2); + create_mubuf(4); + + /* no nop needed because there's already an instruction in-between */ + //! p_unit_test 3 + //! v1: %0:v[0] = image_sample %0:s[0-7], %0:s[0-3], v1: undef, %0:v[0], %0:v[2], %0:v[4], %0:v[6], %0:v[8], %0:v[10] 2d storage: semantics: scope:invocation + //! v_nop + //! v1: %0:v[0] = buffer_load_dword %0:s[0-3], %0:v[0], 0 offset:4 offen storage: semantics: scope:invocation + bld.pseudo(aco_opcode::p_unit_test, Operand(3u)); + create_mimg(true, 6, 4); + bld.vop1(aco_opcode::v_nop); + create_mubuf(4); + + /* no nop needed because the NSA instruction is under 4 dwords */ + //! p_unit_test 4 + //! v1: %0:v[0] = image_sample %0:s[0-7], %0:s[0-3], v1: undef, %0:v[0], %0:v[2] 2d storage: semantics: scope:invocation + //! v1: %0:v[0] = buffer_load_dword %0:s[0-3], %0:v[0], 0 offset:4 offen storage: semantics: scope:invocation + bld.pseudo(aco_opcode::p_unit_test, Operand(4u)); + create_mimg(true, 2, 3); + create_mubuf(4); + + /* NSA instruction and MUBUF/MTBUF in a different block */ + //! p_unit_test 5 + //! v1: %0:v[0] = image_sample %0:s[0-7], %0:s[0-3], v1: undef, %0:v[0], %0:v[2], %0:v[4], %0:v[6], %0:v[8], %0:v[10] 2d storage: semantics: scope:invocation + //! BB1 + //! /* logical preds: / linear preds: BB0, / kind: uniform, */ + //! s_nop + //! v1: %0:v[0] = buffer_load_dword %0:s[0-3], %0:v[0], 0 offset:4 offen storage: semantics: scope:invocation + bld.pseudo(aco_opcode::p_unit_test, Operand(5u)); + create_mimg(true, 6, 4); + bld.reset(program->create_and_insert_block()); + create_mubuf(4); + program->blocks[0].linear_succs.push_back(1); + program->blocks[1].linear_preds.push_back(0); + + finish_insert_nops_test(); +END_TEST -- 2.7.4