aco: skip continue_or_break LCSSA phis when not needed

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 <pendingchaos02@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Fixes: bbe4652430 ("aco: create lcssa phis for continue_or_break loops when necessary")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11333
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29838>
This commit is contained in:
Rhys Perry
2024-06-21 13:55:26 +01:00
committed by Marge Bot
parent 77759f7683
commit e3ffc244f5
2 changed files with 12 additions and 1 deletions

View File

@@ -10186,6 +10186,17 @@ lcssa_workaround(isel_context* ctx, nir_loop* loop)
std::map<unsigned, unsigned> 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)

View File

@@ -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");