From aa0ede751d13c15edde8692783a26ae587996789 Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Thu, 10 Oct 2024 14:27:40 +0100 Subject: [PATCH] aco/tests: add tests for empty exec masks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rhys Perry Reviewed-by: Daniel Schürmann Part-of: --- src/amd/compiler/tests/test_isel.cpp | 588 +++++++++++++++++++++++++++ 1 file changed, 588 insertions(+) diff --git a/src/amd/compiler/tests/test_isel.cpp b/src/amd/compiler/tests/test_isel.cpp index a1a6c528d04..78bdeb47743 100644 --- a/src/amd/compiler/tests/test_isel.cpp +++ b/src/amd/compiler/tests/test_isel.cpp @@ -1153,3 +1153,591 @@ BEGIN_TEST(isel.cf.divergent_if_undef.both) finish_isel_test(); END_TEST + +/* + * if (uniform) { + * terminate_if + * } + */ +BEGIN_TEST(isel.cf.empty_exec.uniform_if) + if (!setup_nir_cs(GFX11)) + return; + + //>> BB0 + //>> s2: %_ = p_unit_test 0 + //>> s2: %_ = p_cbranch_z %_:scc + nir_push_if(nb, nir_unit_test_uniform_amd(nb, 1, 1, .base = 0)); + { + //>> BB1 + //>> s2: %_ = p_unit_test 1 + //>> p_discard_if %_ + //>> p_unit_test 2, %_ + nir_terminate_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 1)); + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 2); + } + nir_pop_if(nb, NULL); + //>> BB3 + //! /* logical preds: BB1, BB2, / linear preds: BB1, BB2, / kind: uniform, top-level, */ + + //>> p_unit_test 3, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 3); + + finish_isel_test(); +END_TEST + +/* + * if (divergent) { + * terminate_if + * //potentially empty + * if (divergent) { + * terminate_if + * //potentially empty + * } else { + * terminate_if + * //potentially empty + * } + * //potentially empty + * } + */ +BEGIN_TEST(isel.cf.empty_exec.divergent_if) + if (!setup_nir_cs(GFX11)) + return; + + //>> BB0 + //>> s2: %_ = p_unit_test 0 + //>> s2: %_ = p_cbranch_z %_ + nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 0)); + { + //>> BB1 + //>> s2: %_ = p_unit_test 1 + //>> p_discard_if %_ + //>> s2: %_ = p_cbranch_z %0:exec rarely_taken + nir_terminate_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 1)); + + //>> p_unit_test 2, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 2); + + //>> s2: %_ = p_unit_test 3 + //>> s2: %_ = p_cbranch_z %_ + nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 3)); + { + //>> p_unit_test 4, %_ + //>> s2: %_ = p_unit_test 5 + //>> p_discard_if %_ + //>> s2: %_ = p_cbranch_z %0:exec rarely_taken + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 4); + nir_terminate_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 5)); + + //>> p_unit_test 6, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 6); + } + nir_push_else(nb, NULL); + { + //>> p_unit_test 7, %_ + //>> s2: %_ = p_unit_test 8 + //>> p_discard_if %_ + //>> s2: %_ = p_cbranch_z %0:exec rarely_taken + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 7); + nir_terminate_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 8)); + + //>> p_unit_test 9, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 9); + } + nir_pop_if(nb, NULL); + //>> BB14 + //! /* logical preds: BB6, BB12, / linear preds: BB12, BB13, / kind: uniform, merge, */ + //>> BB15 + //>> /* logical preds: / linear preds: BB1, / kind: uniform, */ + //>> BB16 + //! /* logical preds: BB14, / linear preds: BB14, BB15, / kind: uniform, */ + //>> s2: %35 = p_cbranch_z %0:exec rarely_taken + + //>> p_unit_test 10, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 10); + } + nir_pop_if(nb, NULL); + + //>> BB24 + //! /* logical preds: BB19, BB22, / linear preds: BB22, BB23, / kind: uniform, top-level, merge, */ + //! p_logical_start + //! p_unit_test 11, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 11); + + finish_isel_test(); +END_TEST + +/* + * loop { + * terminate_if + * //potentially empty + * } + */ +BEGIN_TEST(isel.cf.empty_exec.loop_terminate) + if (!setup_nir_cs(GFX11)) + return; + + nir_push_loop(nb); + { + nir_break_if(nb, nir_imm_false(nb)); + + //>> BB4 + //>> p_unit_test 0, %_ + //>> s2: %_ = p_unit_test 1 + //>> p_discard_if %_ + //>> s2: %_ = p_cbranch_z %0:exec rarely_taken + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 0); + nir_terminate_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 1)); + + //>> BB5 + //>> p_unit_test 2, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 2); + + //>> BB7 + //! /* logical preds: BB5, / linear preds: BB5, BB6, / kind: uniform, continue_or_break, */ + } + nir_pop_loop(nb, NULL); + + //>> BB10 + //! /* logical preds: BB2, / linear preds: BB2, BB8, / kind: uniform, top-level, loop-exit, */ + //! p_logical_start + //! p_unit_test 3, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 3); + + finish_isel_test(); +END_TEST + +/* + * loop { + * if (divergent) { + * if (divergent) { + * break + * } + * //potentially empty + * } + * } + */ +BEGIN_TEST(isel.cf.empty_exec.loop_break) + if (!setup_nir_cs(GFX11)) + return; + + nir_push_loop(nb); + { + //>> BB1 + //>> p_unit_test 0, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 0); + + //>> s2: %_ = p_unit_test 1 + nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 1)); + { + //>> BB2 + //>> s2: %_ = p_unit_test 2 + //>> BB3 + //! /* logical preds: BB2, / linear preds: BB2, / kind: break, */ + nir_break_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 2)); + //>> BB10 + //! /* logical preds: BB8, / linear preds: BB8, BB9, / kind: uniform, merge, */ + + //>> s2: %_ = p_cbranch_z %0:exec rarely_taken + //>> BB11 + //>> p_unit_test 3, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 3); + } + nir_pop_if(nb, NULL); + //>> BB18 + //! /* logical preds: BB13, BB16, / linear preds: BB16, BB17, / kind: uniform, continue, merge, */ + //! p_logical_start + + //! p_unit_test 4, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 4); + } + nir_pop_loop(nb, NULL); + //>> BB19 + //! /* logical preds: BB3, / linear preds: BB4, / kind: uniform, top-level, loop-exit, */ + //! p_logical_start + + //! p_unit_test 5, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 5); + + finish_isel_test(); +END_TEST + +/* + * loop { + * if (divergent) { + * if (divergent) { + * continue + * } + * //potentially empty + * } + * } + */ +BEGIN_TEST(isel.cf.empty_exec.loop_continue) + if (!setup_nir_cs(GFX11)) + return; + + nir_push_loop(nb); + { + nir_break_if(nb, nir_imm_false(nb)); + + //>> BB4 + //>> p_unit_test 0, %_ + //>> s2: %_ = p_unit_test 1 + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 0); + nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 1)); + { + //>> BB5 + //>> s2: %_ = p_unit_test 2 + nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 2)); + { + //>> BB6 + //>> /* logical preds: BB5, / linear preds: BB5, / kind: continue, */ + nir_jump(nb, nir_jump_continue); + } + nir_pop_if(nb, NULL); + //>> BB13 + //! /* logical preds: BB11, / linear preds: BB11, BB12, / kind: uniform, merge, */ + + //>> s2: %23 = p_cbranch_z %0:exec rarely_taken + //>> BB14 + //>> p_unit_test 3, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 3); + } + nir_pop_if(nb, NULL); + //>> BB21 + //! /* logical preds: BB16, BB19, / linear preds: BB19, BB20, / kind: uniform, continue, merge, */ + //! p_logical_start + + //! p_unit_test 4, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 4); + } + nir_pop_loop(nb, NULL); + //>> BB22 + //! /* logical preds: BB2, / linear preds: BB2, / kind: uniform, top-level, loop-exit, */ + //! p_logical_start + + //! p_unit_test 5, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 5); + + finish_isel_test(); +END_TEST + +/* + * loop { + * if (divergent) { + * continue + * } + * if (divergent) { + * break + * } + * //potentially empty + * } + */ +BEGIN_TEST(isel.cf.empty_exec.loop_continue_then_break) + if (!setup_nir_cs(GFX11)) + return; + + nir_push_loop(nb); + { + //>> BB1 + //! /* logical preds: BB0, BB2, BB20, / linear preds: BB0, BB3, BB20, / kind: loop-header, branch, */ + //>> p_unit_test 0, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 0); + + //>> s2: %_ = p_unit_test 1 + nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 1)); + { + //>> BB2 + //! /* logical preds: BB1, / linear preds: BB1, / kind: continue, */ + nir_jump(nb, nir_jump_continue); + } + nir_pop_if(nb, NULL); + + //>> BB9 + //! /* logical preds: BB7, / linear preds: BB7, BB8, / kind: branch, merge, */ + //>> p_unit_test 2, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 2); + + //>> s2: %_ = p_unit_test 3 + //>> BB10 + //! /* logical preds: BB9, / linear preds: BB9, / kind: break, */ + nir_break_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 3)); + //>> BB17 + //! /* logical preds: BB15, / linear preds: BB15, BB16, / kind: uniform, merge, */ + //>> s2: %_ = p_cbranch_z %0:exec rarely_taken + + //>> BB18 + //! /* logical preds: BB17, / linear preds: BB17, / kind: uniform, */ + //>> p_unit_test 4, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 4); + + //>> BB20 + //! /* logical preds: BB18, / linear preds: BB18, BB19, / kind: uniform, continue, */ + } + nir_pop_loop(nb, NULL); + //>> BB21 + //! /* logical preds: BB10, / linear preds: BB11, / kind: uniform, top-level, loop-exit, */ + //! p_logical_start + + //! p_unit_test 5, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 5); + + finish_isel_test(); +END_TEST + +/* + * if (divergent) { + * terminate_if + * //potentially empty + * if (uniform) { + * } + * //potentially empty + * } + */ +BEGIN_TEST(isel.cf.empty_exec.terminate_then_uniform_if) + if (!setup_nir_cs(GFX11)) + return; + + //>> BB0 + //>> s2: %_ = p_unit_test 0 + //>> s2: %_ = p_cbranch_z %_ + nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 0)); + { + //>> BB1 + //>> s2: %_ = p_unit_test 1 + //>> s2: %_ = p_unit_test 2 + //>> p_discard_if %_ + nir_def* cond = nir_unit_test_uniform_amd(nb, 1, 1, .base = 1); + nir_terminate_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 2)); + //>> s2: %_ = p_cbranch_z %0:exec rarely_taken + + //>> s2: %_ = p_cbranch_z %_:scc + nir_push_if(nb, cond); + { + //>> p_unit_test 3, %2 + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 3); + } + nir_pop_if(nb, NULL); + + //>> p_unit_test 4, %1 + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 4); + + //>> BB6 + //! /* logical preds: / linear preds: BB1, / kind: uniform, */ + } + nir_pop_if(nb, NULL); + + finish_isel_test(); +END_TEST + +/* + * if (divergent) { + * terminate_if + * if (divergent) { + * } + * //potentially empty + * } + */ +BEGIN_TEST(isel.cf.empty_exec.terminate_then_divergent_if) + if (!setup_nir_cs(GFX11)) + return; + + //>> BB0 + //>> s2: %_ = p_unit_test 0 + //>> s2: %_ = p_cbranch_z %_ + nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 0)); + { + //>> BB1 + //>> s2: %_ = p_unit_test 1 + //>> s2: %_ = p_unit_test 2 + //>> p_discard_if %_ + nir_def* cond = nir_unit_test_divergent_amd(nb, 1, 1, .base = 1); + nir_terminate_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 2)); + //>> s2: %_ = p_cbranch_z %0:exec rarely_taken + + //>> s2: %_ = p_cbranch_z %_ + nir_push_if(nb, cond); + { + //>> BB3 + //! /* logical preds: BB2, / linear preds: BB2, / kind: uniform, */ + //! p_logical_start + //! p_unit_test 3, %_ + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 3); + } + nir_pop_if(nb, NULL); + + //>> p_unit_test 4, %1 + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 4); + + //>> BB9 + //! /* logical preds: / linear preds: BB1, / kind: uniform, */ + } + nir_pop_if(nb, NULL); + + finish_isel_test(); +END_TEST + +/* + * if (divergent) { + * terminate_if + * //potentially empty + * loop { + * } + * //potentially empty + * } + */ +BEGIN_TEST(isel.cf.empty_exec.terminate_then_loop) + if (!setup_nir_cs(GFX11)) + return; + + //>> BB0 + //>> s2: %_ = p_unit_test 0 + //>> s2: %_ = p_cbranch_z %_ + nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 0)); + { + //>> BB1 + //>> s2: %_ = p_unit_test 1 + //>> p_discard_if %_ + nir_terminate_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 1)); + //>> s2: %_ = p_cbranch_z %0:exec rarely_taken + + //>> BB2 + //! /* logical preds: BB1, / linear preds: BB1, / kind: uniform, loop-preheader, */ + nir_push_loop(nb); + { + nir_break_if(nb, nir_imm_false(nb)); + + //>> BB6 + //! /* logical preds: BB5, / linear preds: BB5, / kind: uniform, continue, */ + //>> p_unit_test 2, %1 + nir_unit_test_amd(nb, nir_undef(nb, 1, 32), .base = 2); + } + nir_pop_loop(nb, NULL); + //>> BB7 + //! /* logical preds: BB4, / linear preds: BB4, / kind: uniform, loop-exit, */ + } + + finish_isel_test(); +END_TEST + +/* + * if (divergent) { + * terminate_if + * //potentially empty + * loop { + * terminate_if + * //potentially empty + * loop { + * terminate_if + * //potentially empty + * val = ... + * if (uniform) break + * break + * } + * if (uniform) break + * } + * } + * use(val) + */ +BEGIN_TEST(isel.cf.empty_exec.repair_ssa) + if (!setup_nir_cs(GFX11)) + return; + + nir_def* val_sgpr; + nir_def* val_vgpr; + nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 0)); + { + //>> BB1 + //! /* logical preds: BB0, / linear preds: BB0, / kind: uniform, discard, */ + //>> s2: %_ = p_unit_test 1 + //>> s2: %_ = p_cbranch_z %0:exec rarely_taken + nir_terminate_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 1)); + + nir_push_loop(nb); + { + //>> BB3 + //! /* logical preds: BB2, BB20, / linear preds: BB2, BB22, / kind: uniform, loop-header, discard, */ + //>> s2: %_ = p_unit_test 2 + //>> s2: %_ = p_cbranch_z %0:exec rarely_taken + nir_terminate_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 2)); + + nir_push_loop(nb); + { + //>> BB5 + //! /* logical preds: BB4, / linear preds: BB4, / kind: uniform, loop-header, discard, */ + //>> s2: %_ = p_unit_test 3 + //>> s2: %_ = p_cbranch_z %0:exec rarely_taken + nir_terminate_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 3)); + + //>> BB6 + //! /* logical preds: BB5, / linear preds: BB5, / kind: uniform, */ + //>> s1: %sgpr0 = p_parallelcopy 42 + //>> v1: %vgpr0 = v_mbcnt_hi_u32_b32_e64 -1, %_ + val_sgpr = nir_imm_int(nb, 42); + val_vgpr = nir_load_subgroup_invocation(nb); + + //>> BB7 + //! /* logical preds: BB6, / linear preds: BB6, / kind: uniform, break, */ + nir_break_if(nb, nir_unit_test_uniform_amd(nb, 1, 1, .base = 4)); + + //>> BB10 + //! /* logical preds: / linear preds: BB5, / kind: uniform, */ + //>> BB11 + //! /* logical preds: BB9, / linear preds: BB9, BB10, / kind: uniform, break, */ + //! s1: %sgpr1 = p_linear_phi %sgpr0, s1: undef + nir_jump(nb, nir_jump_break); + } + nir_pop_loop(nb, NULL); + //>> BB12 + //! /* logical preds: BB7, BB11, / linear preds: BB7, BB11, / kind: uniform, loop-exit, */ + //! s1: %sgpr2 = p_linear_phi %sgpr0, %sgpr1 + //>> BB13 + //! /* logical preds: / linear preds: BB3, / kind: uniform, */ + //>> BB14 + //! /* logical preds: BB12, / linear preds: BB12, BB13, / kind: uniform, */ + //! s1: %sgpr3 = p_linear_phi %sgpr2, s1: undef + //>> s2: %_ = p_cbranch_z %0:exec rarely_taken + + //>> BB15 + //! /* logical preds: BB14, / linear preds: BB14, / kind: uniform, */ + //>> p_unit_test 5, %sgpr3 + //>> p_unit_test 6, %vgpr3 + //>> p_unit_test 7, %sgpr3 + //>> p_unit_test 8, %vgpr3 + nir_unit_test_amd(nb, val_sgpr, .base = 5); + nir_unit_test_amd(nb, val_vgpr, .base = 6); + nir_unit_test_amd(nb, val_sgpr, .base = 7); + nir_unit_test_amd(nb, val_vgpr, .base = 8); + + //>> BB16 + //! /* logical preds: BB15, / linear preds: BB15, / kind: uniform, break, */ + nir_break_if(nb, nir_unit_test_uniform_amd(nb, 1, 1, .base = 9)); + //>> BB20 + //! /* logical preds: BB18, / linear preds: BB18, BB19, / kind: uniform, continue_or_break, */ + } + nir_pop_loop(nb, NULL); + //>> BB23 + //! /* logical preds: BB16, / linear preds: BB16, BB21, / kind: uniform, loop-exit, */ + //>> BB24 + //! /* logical preds: / linear preds: BB1, / kind: uniform, */ + //>> BB25 + //! /* logical preds: BB23, / linear preds: BB23, BB24, / kind: uniform, */ + //! s1: %sgpr4 = p_linear_phi %sgpr3, s1: undef + } + nir_pop_if(nb, NULL); + //>> BB27 + //! /* logical preds: / linear preds: BB25, BB26, / kind: invert, */ + //! s1: %sgpr5 = p_linear_phi %sgpr4, s1: undef + //>> BB30 + //! /* logical preds: BB25, BB28, / linear preds: BB28, BB29, / kind: uniform, top-level, merge, */ + //! v1: %vgpr = p_phi %vgpr0, v1: undef + //! s1: %sgpr = p_linear_phi %sgpr5, %sgpr5 + val_sgpr = nir_if_phi(nb, val_sgpr, nir_undef(nb, 1, 32)); + val_vgpr = nir_if_phi(nb, val_vgpr, nir_undef(nb, 1, 32)); + + //>> p_unit_test 10, %sgpr + //>> p_unit_test 11, %vgpr + nir_unit_test_amd(nb, val_sgpr, .base = 10); + nir_unit_test_amd(nb, val_vgpr, .base = 11); + + finish_isel_test(); +END_TEST