nir/lower_io: force src offset=0 for any indirect access with num_slots == 1

This reduces indirect indexing of 1-element arrays to indexing with 0.
Without this, we fail an assertion later.

Discovered when writing a test.

Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38113>
This commit is contained in:
Marek Olšák 2025-10-27 22:47:26 -04:00 committed by Marge Bot
parent 9125e34372
commit 390023f9fd

View file

@ -317,6 +317,17 @@ get_interp_mode(const nir_variable *var)
return interp_mode;
}
static nir_def *
simplify_offset_src(nir_builder *b, nir_def *offset, unsigned num_slots)
{
/* Force index=0 for any indirect access to array[1]. */
if (num_slots == 1 &&
offset->parent_instr->type != nir_instr_type_load_const)
return nir_imm_int(b, 0);
return offset;
}
static nir_def *
emit_load(struct lower_io_state *state,
nir_def *array_index, nir_variable *var, nir_def *offset,
@ -430,6 +441,8 @@ emit_load(struct lower_io_state *state,
*/
semantics.interp_explicit_strict = var->data.per_vertex;
nir_intrinsic_set_io_semantics(load, semantics);
offset = simplify_offset_src(b, offset, num_slots);
}
if (array_index) {
@ -558,6 +571,9 @@ emit_store(struct lower_io_state *state, nir_def *data,
if (array_index)
store->src[1] = nir_src_for_ssa(array_index);
unsigned num_slots = get_number_of_slots(state, var);
offset = simplify_offset_src(b, offset, num_slots);
store->src[array_index ? 2 : 1] = nir_src_for_ssa(offset);
unsigned gs_streams = 0;
@ -573,7 +589,6 @@ emit_store(struct lower_io_state *state, nir_def *data,
}
int location = var->data.location;
unsigned num_slots = get_number_of_slots(state, var);
/* Maximum values in nir_io_semantics. */
assert(num_slots <= 63);
@ -711,6 +726,8 @@ lower_interpolate_at(nir_intrinsic_instr *intrin, struct lower_io_state *state,
semantics.num_slots = get_number_of_slots(state, var);
semantics.medium_precision = is_medium_precision(b->shader, var);
offset = simplify_offset_src(b, offset, semantics.num_slots);
nir_def *load =
nir_load_interpolated_input(&state->builder,
intrin->def.num_components,