diff --git a/src/compiler/nir/nir_lower_io_to_vector.c b/src/compiler/nir/nir_lower_io_to_vector.c index 81836312d0c..e49fda5d587 100644 --- a/src/compiler/nir/nir_lower_io_to_vector.c +++ b/src/compiler/nir/nir_lower_io_to_vector.c @@ -613,7 +613,7 @@ nir_vectorize_tess_levels_impl(nir_function_impl *impl) 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; @@ -633,7 +633,8 @@ nir_vectorize_tess_levels_impl(nir_function_impl *impl) 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; @@ -641,7 +642,23 @@ nir_vectorize_tess_levels_impl(nir_function_impl *impl) 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);