From a7147ef1e86af5dbc39371885664f05030b3b418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Wed, 6 Apr 2022 18:53:20 +0200 Subject: [PATCH] nir: Handle out of bounds access in nir_vectorize_tess_levels. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace out of bounds loads with undef. Then, delete instructions with out of bounds access. Fixes: f5adf27fb926a330a13af716f0a03da1a224656d "nir,radv: add and use nir_vectorize_tess_levels()" Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6264 Signed-off-by: Timur Kristóf Reviewed-by: Rhys Perry Part-of: --- src/compiler/nir/nir_lower_io_to_vector.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) 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);