From: Danylo Piliaiev Date: Fri, 21 Aug 2020 10:42:55 +0000 (+0300) Subject: nir/lower_io: Eliminate oob writes and return zero for oob reads X-Git-Tag: upstream/21.0.0~5202 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=66669eb5295c207622425d9767422a62e1228407;p=platform%2Fupstream%2Fmesa.git nir/lower_io: Eliminate oob writes and return zero for oob reads Out-of-bounds writes could be eliminated per spec: Section 5.11 (Out-of-Bounds Accesses) of the GLSL 4.60 spec says: "In the subsections described above for array, vector, matrix and structure accesses, any out-of-bounds access produced undefined behavior.... Out-of-bounds writes may be discarded or overwrite other variables of the active program. Out-of-bounds reads return undefined values, which include values from other variables of the active program or zero." GL_KHR_robustness and GL_ARB_robustness encourage us to return zero for reads. Otherwise get_io_offset would return out-of-bound offset which may result in out-of-bound loading/storing of inputs/outputs, that could cause issues in drivers down the line. E.g. this fixes such dereference: int vue_slot = vue_map->varying_to_slot[intrin->const_index[0]]; in brw_nir.c CC: Signed-off-by: Danylo Piliaiev Reviewed-by: Eric Anholt Part-of: --- diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c index 986c4c0..c90119b 100644 --- a/src/compiler/nir/nir_lower_io.c +++ b/src/compiler/nir/nir_lower_io.c @@ -636,6 +636,37 @@ nir_lower_io_block(nir_block *block, mode == nir_var_shader_out || var->data.bindless; + if (nir_deref_instr_is_known_out_of_bounds(deref)) { + /* Section 5.11 (Out-of-Bounds Accesses) of the GLSL 4.60 spec says: + * + * In the subsections described above for array, vector, matrix and + * structure accesses, any out-of-bounds access produced undefined + * behavior.... + * Out-of-bounds reads return undefined values, which + * include values from other variables of the active program or zero. + * Out-of-bounds writes may be discarded or overwrite + * other variables of the active program. + * + * GL_KHR_robustness and GL_ARB_robustness encourage us to return zero + * for reads. + * + * Otherwise get_io_offset would return out-of-bound offset which may + * result in out-of-bound loading/storing of inputs/outputs, + * that could cause issues in drivers down the line. + */ + if (intrin->intrinsic != nir_intrinsic_store_deref) { + nir_ssa_def *zero = + nir_imm_zero(b, intrin->dest.ssa.num_components, + intrin->dest.ssa.bit_size); + nir_ssa_def_rewrite_uses(&intrin->dest.ssa, + nir_src_for_ssa(zero)); + } + + nir_instr_remove(&intrin->instr); + progress = true; + continue; + } + offset = get_io_offset(b, deref, per_vertex ? &vertex_index : NULL, state->type_size, &component_offset, bindless_type_size);