aco/tests: Add post-RA SCC no-compare tests cases with control flow.

- scc_nocmp_across_cf: passes
- scc_nocmp_across_cf_partially_overwritten: fails (fixed later)

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18488>
This commit is contained in:
Timur Kristóf
2022-09-21 09:13:54 +02:00
committed by Marge Bot
parent d4b3f81d94
commit 5e80edfa78
@@ -156,6 +156,7 @@ BEGIN_TEST(optimizer_postRA.scc_nocmp_opt)
PhysReg reg_s3{3};
PhysReg reg_s4{4};
PhysReg reg_s6{6};
PhysReg reg_s8{8};
Temp in_0 = inputs[0];
Temp in_1 = inputs[1];
@@ -276,6 +277,25 @@ BEGIN_TEST(optimizer_postRA.scc_nocmp_opt)
//; del d, e, f, g, h, x
{
/* SCC is overwritten in between, optimize by pulling down */
//! s1: %h:s[3], s1: %x:scc = s_add_u32 %a:s[0], 1
//! s2: %d:s[8-9], s1: %e:scc = s_and_b64 %b:s[4-5], 0x40018
//! s2: %f:vcc = p_cbranch_z %g:scc
//! p_unit_test 5, %f:vcc, %h:s[3]
auto salu = bld.sop2(aco_opcode::s_and_b64, bld.def(s2, reg_s8), bld.def(s1, scc), op_in_1,
Operand::c32(0x40018u));
auto ovrw = bld.sop2(aco_opcode::s_add_u32, bld.def(s1, reg_s3), bld.def(s1, scc), op_in_0,
Operand::c32(1u));
auto scmp = bld.sopc(aco_opcode::s_cmp_lg_u32, bld.def(s1, scc), Operand(salu, reg_s8),
Operand::zero());
auto br = bld.branch(aco_opcode::p_cbranch_z, bld.def(s2, vcc), bld.scc(scmp));
writeout(5, Operand(br, vcc), Operand(ovrw, reg_s3));
}
//; del d, e, f, g, h, x
{
//! s1: %d:s[2], s1: %e:scc = s_bfe_u32 %a:s[0], 0x40018
//! s1: %f:s[4] = s_cselect_b32 %z:s[6], %a:s[0], %e:scc
@@ -518,6 +538,7 @@ BEGIN_TEST(optimizer_postRA.dpp_across_cf_overwritten)
Operand a(inputs[0], PhysReg(256)); /* source for DPP */
Operand b(inputs[1], PhysReg(257)); /* source for fadd */
Operand c(inputs[2], PhysReg(258)); /* buffer store address */
Operand d(inputs[3], PhysReg(259)); /* buffer store value */
Operand e(inputs[4], PhysReg(0)); /* condition */
Operand f(inputs[5], PhysReg(2)); /* buffer store address (scalar) */
@@ -580,3 +601,161 @@ BEGIN_TEST(optimizer_postRA.dpp_across_cf_overwritten)
finish_optimizer_postRA_test();
END_TEST
BEGIN_TEST(optimizer_postRA.scc_nocmp_across_cf)
//>> s2: %a:s[2-3], v1: %c:v[2], v1: %d:v[3], s2: %e:s[0-1] = p_startpgm
if (!setup_cs("s2 v1 v1 s2", GFX10_3))
return;
aco_ptr<Instruction>& startpgm = bld.instructions->at(0);
startpgm->definitions[0].setFixed(PhysReg(2));
startpgm->definitions[1].setFixed(PhysReg(258));
startpgm->definitions[2].setFixed(PhysReg(259));
startpgm->definitions[3].setFixed(PhysReg(0));
Operand a(inputs[0], PhysReg(2)); /* source for s_and */
Operand c(inputs[1], PhysReg(258)); /* buffer store address */
Operand d(inputs[2], PhysReg(259)); /* buffer store value */
Operand e(inputs[3], PhysReg(0)); /* condition */
PhysReg reg_s8(8); /* temporary register */
auto tmp_salu = bld.sop2(aco_opcode::s_and_b64, bld.def(s2, reg_s8), bld.def(s1, scc), a,
Operand::c32(0x40018u));
//! s2: %saved_exec:s[84-85], s1: %0:scc, s2: %0:exec = s_and_saveexec_b64 %e:s[0-1], %0:exec
//! s2: %0:vcc = p_cbranch_nz BB1, BB2
emit_divergent_if_else(program.get(), bld, e, [&]() -> void {
/* --- logical then --- */
//! BB1
//! /* logical preds: BB0, / linear preds: BB0, / kind: */
//! p_logical_start
//! buffer_store_dword %c:v[2], 0, %d:v[3], 0 offen storage: semantics: scope:invocation
bld.mubuf(aco_opcode::buffer_store_dword, c, Operand::zero(), d, Operand::zero(), 0, true);
//! p_logical_end
//! s2: %0:vcc = p_branch BB3
/* --- linear then --- */
//! BB2
//! /* logical preds: / linear preds: BB0, / kind: */
//! s2: %0:vcc = p_branch BB3
/* --- invert --- */
//! BB3
//! /* logical preds: / linear preds: BB1, BB2, / kind: invert, */
//! s2: %0:exec, s1: %0:scc = s_andn2_b64 %saved_exec:s[84-85], %0:exec
//! s2: %0:vcc = p_cbranch_nz BB4, BB5
}, [&]() -> void {
/* --- logical else --- */
//! BB4
//! /* logical preds: BB0, / linear preds: BB3, / kind: */
//! p_logical_start
//! p_logical_end
//! s2: %0:vcc = p_branch BB6
/* --- linear else --- */
//! BB5
//! /* logical preds: / linear preds: BB3, / kind: */
//! s2: %0:vcc = p_branch BB6
});
/* --- merge block --- */
//! BB6
//! /* logical preds: BB1, BB4, / linear preds: BB4, BB5, / kind: uniform, merge, */
//! s2: %0:exec = p_parallelcopy %saved_exec:s[84-85]
//! s2: %tmp_salu:s[8-9], s1: %br_scc:scc = s_and_b64 %a:s[2-3], 0x40018
//! s2: %br_vcc:vcc = p_cbranch_z %br_scc:scc
//! p_unit_test 5, %br_vcc:vcc
auto scmp = bld.sopc(aco_opcode::s_cmp_lg_u32, bld.def(s1, scc), Operand(tmp_salu, reg_s8),
Operand::zero());
auto br = bld.branch(aco_opcode::p_cbranch_z, bld.def(s2, vcc), bld.scc(scmp));
writeout(5, Operand(br, vcc));
finish_optimizer_postRA_test();
END_TEST
BEGIN_TEST(optimizer_postRA.scc_nocmp_across_cf_partially_overwritten)
//>> s2: %a:s[2-3], v1: %c:v[2], v1: %d:v[3], s2: %e:s[0-1], s1: %f:s[4] = p_startpgm
if (!setup_cs("s2 v1 v1 s2 s1", GFX10_3))
return;
aco_ptr<Instruction>& startpgm = bld.instructions->at(0);
startpgm->definitions[0].setFixed(PhysReg(2));
startpgm->definitions[1].setFixed(PhysReg(258));
startpgm->definitions[2].setFixed(PhysReg(259));
startpgm->definitions[3].setFixed(PhysReg(0));
startpgm->definitions[4].setFixed(PhysReg(4));
Operand a(inputs[0], PhysReg(2)); /* source for s_and */
Operand c(inputs[1], PhysReg(258)); /* buffer store address */
Operand d(inputs[2], PhysReg(259)); /* buffer store value */
Operand e(inputs[3], PhysReg(0)); /* condition */
Operand f(inputs[4], PhysReg(4)); /* overwrite value */
PhysReg reg_s3(3); /* temporary register */
PhysReg reg_s8(8); /* temporary register */
//! s2: %tmp_salu:s[8-9], s1: %tmp_salu_scc:scc = s_and_b64 %a:s[2-3], 0x40018
auto tmp_salu = bld.sop2(aco_opcode::s_and_b64, bld.def(s2, reg_s8), bld.def(s1, scc), a,
Operand::c32(0x40018u));
//! s2: %saved_exec:s[84-85], s1: %0:scc, s2: %0:exec = s_and_saveexec_b64 %e:s[0-1], %0:exec
//! s2: %0:vcc = p_cbranch_nz BB1, BB2
emit_divergent_if_else(program.get(), bld, e, [&]() -> void {
/* --- logical then --- */
//! BB1
//! /* logical preds: BB0, / linear preds: BB0, / kind: */
//! p_logical_start
//! s1: %ovrwr:s[3] = p_parallelcopy %f:s[4]
Temp s_addr = bld.pseudo(aco_opcode::p_parallelcopy, bld.def(s1, reg_s3), f);
//! buffer_store_dword %c:v[2], %ovrwr:s[3], %d:v[3], 0 offen storage: semantics: scope:invocation
bld.mubuf(aco_opcode::buffer_store_dword, c, Operand(s_addr, reg_s3), d, Operand::zero(), 0, true);
//! p_logical_end
//! s2: %0:vcc = p_branch BB3
/* --- linear then --- */
//! BB2
//! /* logical preds: / linear preds: BB0, / kind: */
//! s2: %0:vcc = p_branch BB3
/* --- invert --- */
//! BB3
//! /* logical preds: / linear preds: BB1, BB2, / kind: invert, */
//! s2: %0:exec, s1: %0:scc = s_andn2_b64 %saved_exec:s[84-85], %0:exec
//! s2: %0:vcc = p_cbranch_nz BB4, BB5
}, [&]() -> void {
/* --- logical else --- */
//! BB4
//! /* logical preds: BB0, / linear preds: BB3, / kind: */
//! p_logical_start
//! p_logical_end
//! s2: %0:vcc = p_branch BB6
/* --- linear else --- */
//! BB5
//! /* logical preds: / linear preds: BB3, / kind: */
//! s2: %0:vcc = p_branch BB6
});
/* --- merge block --- */
//! BB6
//! /* logical preds: BB1, BB4, / linear preds: BB4, BB5, / kind: uniform, merge, */
//! s2: %0:exec = p_parallelcopy %saved_exec:s[84-85]
//! s1: %br_scc:scc = s_cmp_lg_u32 %tmp_salu:s[8-9], 0
//! s2: %br_vcc:vcc = p_cbranch_z %br_scc:scc
//! p_unit_test 5, %br_vcc:vcc
auto scmp = bld.sopc(aco_opcode::s_cmp_lg_u32, bld.def(s1, scc), Operand(tmp_salu, reg_s8),
Operand::zero());
auto br = bld.branch(aco_opcode::p_cbranch_z, bld.def(s2, vcc), bld.scc(scmp));
writeout(5, Operand(br, vcc));
finish_optimizer_postRA_test();
END_TEST