From 4ccbaa2cd8b75ebfce144b8612359f5fb53eca5f Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Fri, 1 Mar 2024 09:18:50 -0800 Subject: [PATCH] microsoft/compiler: Remove deref load/store/atomic ops that statically go out of array bounds Part-of: --- src/microsoft/compiler/dxil_nir.c | 49 ++++++++++++++++++++++++++++ src/microsoft/compiler/dxil_nir.h | 1 + src/microsoft/compiler/nir_to_dxil.c | 1 + 3 files changed, 51 insertions(+) diff --git a/src/microsoft/compiler/dxil_nir.c b/src/microsoft/compiler/dxil_nir.c index 15f225135cf..973d12a0114 100644 --- a/src/microsoft/compiler/dxil_nir.c +++ b/src/microsoft/compiler/dxil_nir.c @@ -608,6 +608,55 @@ dxil_nir_lower_var_bit_size(nir_shader *shader, nir_variable_mode modes, return true; } +static bool +remove_oob_array_access(nir_builder *b, nir_intrinsic_instr *intr, void *data) +{ + uint32_t num_derefs = 1; + + switch (intr->intrinsic) { + case nir_intrinsic_copy_deref: + num_derefs = 2; + FALLTHROUGH; + case nir_intrinsic_load_deref: + case nir_intrinsic_store_deref: + case nir_intrinsic_deref_atomic: + case nir_intrinsic_deref_atomic_swap: + break; + default: + return false; + } + + for (uint32_t i = 0; i < num_derefs; ++i) { + if (nir_deref_instr_is_known_out_of_bounds(nir_src_as_deref(intr->src[i]))) { + switch (intr->intrinsic) { + case nir_intrinsic_load_deref: + case nir_intrinsic_deref_atomic: + case nir_intrinsic_deref_atomic_swap: + b->cursor = nir_before_instr(&intr->instr); + nir_def *undef = nir_undef(b, intr->def.num_components, intr->def.bit_size); + nir_def_rewrite_uses(&intr->def, undef); + break; + default: + break; + } + nir_instr_remove(&intr->instr); + return true; + } + } + + return false; +} + +bool +dxil_nir_remove_oob_array_accesses(nir_shader *shader) +{ + return nir_shader_intrinsics_pass(shader, remove_oob_array_access, + nir_metadata_block_index | + nir_metadata_dominance | + nir_metadata_loop_analysis, + NULL); +} + static bool lower_shared_atomic(nir_builder *b, nir_intrinsic_instr *intr, nir_variable *var) { diff --git a/src/microsoft/compiler/dxil_nir.h b/src/microsoft/compiler/dxil_nir.h index 8f5aaa26dd2..f85568fb144 100644 --- a/src/microsoft/compiler/dxil_nir.h +++ b/src/microsoft/compiler/dxil_nir.h @@ -40,6 +40,7 @@ bool dxil_nir_lower_constant_to_temp(nir_shader *shader); bool dxil_nir_flatten_var_arrays(nir_shader *shader, nir_variable_mode modes); bool dxil_nir_lower_var_bit_size(nir_shader *shader, nir_variable_mode modes, unsigned min_bit_size, unsigned max_bit_size); +bool dxil_nir_remove_oob_array_accesses(nir_shader *shader); struct dxil_nir_lower_loads_stores_options { bool use_16bit_ssbo; }; diff --git a/src/microsoft/compiler/nir_to_dxil.c b/src/microsoft/compiler/nir_to_dxil.c index 9e3c8e9a358..59c4c2ed480 100644 --- a/src/microsoft/compiler/nir_to_dxil.c +++ b/src/microsoft/compiler/nir_to_dxil.c @@ -6331,6 +6331,7 @@ optimize_nir(struct nir_shader *s, const struct nir_to_dxil_options *opts) NIR_PASS(progress, s, nir_lower_phis_to_scalar, true); NIR_PASS(progress, s, nir_opt_loop_unroll); NIR_PASS(progress, s, nir_lower_pack); + NIR_PASS(progress, s, dxil_nir_remove_oob_array_accesses); NIR_PASS_V(s, nir_lower_system_values); } while (progress);