From e3ffc244f51860f9c5530136a8816c4f36aa0eaa Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Fri, 21 Jun 2024 13:55:26 +0100 Subject: [PATCH] aco: skip continue_or_break LCSSA phis when not needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: //exec is empty here loop { %1:s[16-17] = ... if () { break } %2:s[16-17] = ... continue_or_break } %3 = phi %1, undef //because of the undef, %2 can use s[16-17] and overwrite the address load(%3:s[16-17]) No fossil-db changes. Signed-off-by: Rhys Perry Reviewed-by: Daniel Schürmann Fixes: bbe46524307e ("aco: create lcssa phis for continue_or_break loops when necessary") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11333 Part-of: --- src/amd/compiler/aco_instruction_selection.cpp | 11 +++++++++++ src/amd/compiler/aco_instruction_selection_setup.cpp | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp index d74f928e1a1..0de5b85b94c 100644 --- a/src/amd/compiler/aco_instruction_selection.cpp +++ b/src/amd/compiler/aco_instruction_selection.cpp @@ -10186,6 +10186,17 @@ lcssa_workaround(isel_context* ctx, nir_loop* loop) std::map renames; nir_foreach_block_in_cf_node (block, &loop->cf_node) { + /* These values are reachable from the loop exit even when continue_or_break is used. We + * shouldn't create phis with undef operands in case the contents are important even if exec + * is zero (for example, memory access addresses). */ + if (nir_block_dominates(block, nir_loop_last_block(loop))) + continue; + + /* Definitions in this block are not reachable from the loop exit, and so all uses are inside + * the loop. */ + if (!nir_block_dominates(block, block_after_loop)) + continue; + nir_foreach_instr (instr, block) { nir_def* def = nir_instr_def(instr); if (!def) diff --git a/src/amd/compiler/aco_instruction_selection_setup.cpp b/src/amd/compiler/aco_instruction_selection_setup.cpp index 5fe46c2e93c..8f8225f6e40 100644 --- a/src/amd/compiler/aco_instruction_selection_setup.cpp +++ b/src/amd/compiler/aco_instruction_selection_setup.cpp @@ -289,7 +289,7 @@ init_context(isel_context* ctx, nir_shader* shader) nir_metadata_preserve(impl, nir_metadata_none); /* we'll need these for isel */ - nir_metadata_require(impl, nir_metadata_block_index); + nir_metadata_require(impl, nir_metadata_block_index | nir_metadata_dominance); if (ctx->options->dump_preoptir) { fprintf(stderr, "NIR shader before instruction selection:\n");