nir/lower_non_uniform_access: fix fusing loops for same index but different array variable

struct nu_handle is hashed and deduplicated using struct nu_handle_key, which ignored
parent_deref. That means all instructions will use the first parent_deref when rewriting
the sources.

Avoid this by not including the parent deref in the struct, and instead querying it
when needed.

Fixes: 4d09cd7fa5 ("nir/lower_non_uniform_access: Group accesses using the same resource")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/15173
Reviewed-by: Konstantin Seurer <konstantin.seurer@gmail.com>
(cherry picked from commit e7077e8f5c)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40752>
This commit is contained in:
Georg Lehmann 2026-03-26 15:44:59 +01:00 committed by Eric Engestrom
parent b084df3ed6
commit 2527900bbc
2 changed files with 9 additions and 8 deletions

View file

@ -1274,7 +1274,7 @@
"description": "nir/lower_non_uniform_access: fix fusing loops for same index but different array variable",
"nominated": true,
"nomination_type": 2,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "4d09cd7fa590cbd52d8772d5a251fab8b0874ab7",
"notes": null

View file

@ -29,7 +29,6 @@
struct nu_handle {
nir_def *handle;
nir_deref_instr *parent_deref;
nir_def *first;
};
@ -81,7 +80,6 @@ nu_handle_init(struct nu_handle *h, nir_src *src)
return false;
h->handle = deref->arr.index.ssa;
h->parent_deref = parent;
return true;
} else {
@ -89,7 +87,6 @@ nu_handle_init(struct nu_handle *h, nir_src *src)
return false;
h->handle = src->ssa;
h->parent_deref = NULL;
return true;
}
@ -123,11 +120,15 @@ nu_handle_compare(const nir_lower_non_uniform_access_options *options,
static void
nu_handle_rewrite(nir_builder *b, struct nu_handle *h, nir_src *src)
{
if (h->parent_deref) {
if (nir_src_is_deref(*src)) {
nir_deref_instr *deref = nir_src_as_deref(*src);
assert(deref->deref_type == nir_deref_type_array);
nir_deref_instr *parent = nir_deref_instr_parent(deref);
/* Replicate the deref. */
nir_deref_instr *deref =
nir_build_deref_array(b, h->parent_deref, h->first);
nir_src_rewrite(src, &deref->def);
nir_deref_instr *new_deref =
nir_build_deref_array(b, parent, h->first);
nir_src_rewrite(src, &new_deref->def);
} else {
nir_src_rewrite(src, h->first);
}