nir,spirv: Preserve inbounds access information

Preserving information about inbounds access and
the required bit size for the bounds will help
with avoiding 64-bit operations when lowering io.

Signed-off-by: Konstantin Seurer <konstantin.seurer@gmail.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16729>
This commit is contained in:
Konstantin Seurer 2022-05-26 21:12:33 +02:00 committed by Marge Bot
parent e6301b886b
commit f19cbe98e3
7 changed files with 18 additions and 1 deletions

View File

@ -1531,6 +1531,7 @@ typedef struct {
union {
struct {
nir_src index;
bool in_bounds;
} arr;
struct {

View File

@ -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:

View File

@ -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);

View File

@ -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:

View File

@ -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);

View File

@ -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

View File

@ -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;