r600: fix cayman sfn_nir_legalize_image_load_store ssa dominance

After dae57e184a ("glsl,st/mesa: always lower IO for GLSL, unlower
IO for drivers"), the shaders updated by sfn_nir_legalize_image_load_store
on cayman could trigger a segmentation fault. The main issue is that
sfn_nir_legalize_image_load_store does not handle properly the ssa
dominance functionality and this issue is exacerbated by this last
mesa update.

This change makes the ssa dominance functionality operational.

This commit implements pass_flags to avoid an infinite loop.

For instance, this issue is triggered on cayman using this
environment variable NIR_DEBUG=validate_ssa_dominance with:
"piglit/bin/oes_egl_image_external_essl3 -auto -fbo":
NIR validation failed after r600_legalize_image_load_store in ../src/gallium/drivers/r600/sfn/sfn_nir.cpp

Signed-off-by: Patrick Lerda <patrick9876@free.fr>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32894>
This commit is contained in:
Patrick Lerda 2025-01-05 14:27:21 +01:00 committed by Marge Bot
parent 1d5d809818
commit c707bb5e8f

View file

@ -10,6 +10,10 @@
#include "nir_intrinsics_indices.h"
#include "sfn_nir.h"
enum legalize_image_load_store_pass_flags {
FLAG_LEGALIZE_DONE = BITFIELD_BIT(7),
};
static nir_def *
r600_legalize_image_load_store_impl(nir_builder *b,
nir_instr *instr,
@ -113,6 +117,7 @@ r600_legalize_image_load_store_impl(nir_builder *b,
auto new_load_ir = nir_instr_as_intrinsic(new_load);
nir_builder_instr_insert(b, new_load);
new_load_ir->instr.pass_flags |= FLAG_LEGALIZE_DONE;
if (load_value)
result = &new_load_ir->def;
@ -137,10 +142,12 @@ r600_legalize_image_load_store_impl(nir_builder *b,
if (load_value)
result = nir_if_phi(b, result, default_value);
if (load_value)
b->cursor = nir_after_instr(result->parent_instr);
else
{
nir_cf_list cf_list;
nir_cf_extract(&cf_list, nir_before_instr(instr), nir_after_instr(instr));
nir_cf_reinsert(&cf_list, nir_before_block(nir_if_first_then_block(if_exists)));
b->cursor = nir_after_cf_node(&else_exists->cf_node);
}
return result;
}
@ -158,7 +165,7 @@ r600_legalize_image_load_store_filter(const nir_instr *instr, UNUSED const void
case nir_intrinsic_image_atomic:
case nir_intrinsic_image_atomic_swap:
case nir_intrinsic_image_size:
return true;
return (instr->pass_flags & FLAG_LEGALIZE_DONE) ? false : true;
default:
return false;
}