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>
(cherry picked from commit e3ffc244f5)
This commit is contained in:
Rhys Perry 2024-06-21 13:55:26 +01:00 committed by Eric Engestrom
parent 7c9f396544
commit 63f161ff96
3 changed files with 13 additions and 2 deletions

View file

@ -84,7 +84,7 @@
"description": "aco: skip continue_or_break LCSSA phis when not needed",
"nominated": true,
"nomination_type": 1,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "bbe46524307e5e834d5b3d593763b72120d6a3ee",
"notes": null

View file

@ -10446,6 +10446,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

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