diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 295ab30f24c..b6387fd398e 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -1531,6 +1531,7 @@ typedef struct { union { struct { nir_src index; + bool in_bounds; } arr; struct { diff --git a/src/compiler/nir/nir_clone.c b/src/compiler/nir/nir_clone.c index 0a58f328507..ee509da06e2 100644 --- a/src/compiler/nir/nir_clone.c +++ b/src/compiler/nir/nir_clone.c @@ -331,6 +331,7 @@ clone_deref_instr(clone_state *state, const nir_deref_instr *deref) case nir_deref_type_ptr_as_array: __clone_src(state, &nderef->instr, &nderef->arr.index, &deref->arr.index); + nderef->arr.in_bounds = deref->arr.in_bounds; break; case nir_deref_type_array_wildcard: diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c index bb1bb91fdc7..f9d599c02d5 100644 --- a/src/compiler/nir/nir_deref.c +++ b/src/compiler/nir/nir_deref.c @@ -1219,6 +1219,8 @@ opt_deref_ptr_as_array(nir_builder *b, nir_deref_instr *deref) assert(parent->arr.index.is_ssa); assert(deref->arr.index.is_ssa); + deref->arr.in_bounds &= parent->arr.in_bounds; + nir_ssa_def *new_idx = nir_iadd(b, parent->arr.index.ssa, deref->arr.index.ssa); diff --git a/src/compiler/nir/nir_instr_set.c b/src/compiler/nir/nir_instr_set.c index 443928136fb..9ce5793594e 100644 --- a/src/compiler/nir/nir_instr_set.c +++ b/src/compiler/nir/nir_instr_set.c @@ -168,6 +168,7 @@ hash_deref(uint32_t hash, const nir_deref_instr *instr) case nir_deref_type_array: case nir_deref_type_ptr_as_array: hash = hash_src(hash, &instr->arr.index); + hash = HASH(hash, instr->arr.in_bounds); break; case nir_deref_type_cast: @@ -623,6 +624,8 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2) case nir_deref_type_ptr_as_array: if (!nir_srcs_equal(deref1->arr.index, deref2->arr.index)) return false; + if (deref1->arr.in_bounds != deref2->arr.in_bounds) + return false; break; case nir_deref_type_cast: diff --git a/src/compiler/nir/nir_serialize.c b/src/compiler/nir/nir_serialize.c index 4c12afbba87..bd69225dd19 100644 --- a/src/compiler/nir/nir_serialize.c +++ b/src/compiler/nir/nir_serialize.c @@ -630,7 +630,8 @@ union packed_instr { unsigned deref_type:3; unsigned cast_type_same_as_last:1; unsigned modes:5; /* See (de|en)code_deref_modes() */ - unsigned _pad:10; + unsigned _pad:9; + unsigned in_bounds:1; unsigned packed_src_ssa_16bit:1; /* deref_var redefines this */ unsigned dest:8; } deref; @@ -1039,6 +1040,8 @@ write_deref(write_ctx *ctx, const nir_deref_instr *deref) header.deref.packed_src_ssa_16bit = deref->parent.is_ssa && deref->arr.index.is_ssa && are_object_ids_16bit(ctx); + + header.deref.in_bounds = deref->arr.in_bounds; } write_dest(ctx, &deref->dest, header, deref->instr.type); @@ -1126,6 +1129,8 @@ read_deref(read_ctx *ctx, union packed_instr header) read_src(ctx, &deref->arr.index, &deref->instr); } + deref->arr.in_bounds = header.deref.in_bounds; + parent = nir_src_as_deref(deref->parent); if (deref->deref_type == nir_deref_type_array) deref->type = glsl_get_array_element(parent->type); diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h index 6a9d1394760..b4b0513ee07 100644 --- a/src/compiler/spirv/vtn_private.h +++ b/src/compiler/spirv/vtn_private.h @@ -481,6 +481,8 @@ struct vtn_access_chain { /* Access qualifiers */ enum gl_access_qualifier access; + bool in_bounds; + /** Struct elements and array offsets. * * This is an array of 1 so that it can conveniently be created on the diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index e8161e2e565..0eb7f60b24c 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -459,6 +459,7 @@ vtn_pointer_dereference(struct vtn_builder *b, tail = nir_build_deref_array(&b->nb, tail, arr_index); type = type->array_element; } + tail->arr.in_bounds = deref_chain->in_bounds; access |= type->access; } @@ -2464,6 +2465,8 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, struct vtn_pointer *base = vtn_pointer(b, w[3]); + chain->in_bounds = (opcode == SpvOpInBoundsAccessChain || opcode == SpvOpInBoundsPtrAccessChain); + /* Workaround for https://gitlab.freedesktop.org/mesa/mesa/-/issues/3406 */ access |= base->access & ACCESS_NON_UNIFORM;