nir_builder_init(&b, impl);
nir_foreach_block(block, impl) {
- nir_foreach_instr(instr, block) {
+ nir_foreach_instr_safe(instr, block) {
if (instr->type != nir_instr_type_intrinsic)
continue;
assert(deref->deref_type == nir_deref_type_array);
assert(nir_src_is_const(deref->arr.index));
- unsigned index = nir_src_as_uint(deref->arr.index);;
+ unsigned index = nir_src_as_uint(deref->arr.index);
+ unsigned vec_size = glsl_get_vector_elements(var->type);
b.cursor = nir_before_instr(instr);
nir_ssa_def *new_deref = &nir_build_deref_var(&b, var)->dest.ssa;
nir_deref_instr_remove_if_unused(deref);
- intrin->num_components = glsl_get_vector_elements(var->type);
+ intrin->num_components = vec_size;
+
+ /* Handle out of bounds access. */
+ if (index >= vec_size) {
+ if (intrin->intrinsic == nir_intrinsic_load_deref) {
+ /* Return undef from out of bounds loads. */
+ b.cursor = nir_after_instr(instr);
+ nir_ssa_def *val = &intrin->dest.ssa;
+ nir_ssa_def *u = nir_ssa_undef(&b, val->num_components, val->bit_size);
+ nir_ssa_def_rewrite_uses(val, u);
+ }
+
+ /* Finally, remove the out of bounds access. */
+ nir_instr_remove(instr);
+ progress = true;
+ continue;
+ }
if (intrin->intrinsic == nir_intrinsic_store_deref) {
nir_intrinsic_set_write_mask(intrin, 1 << index);