nir,spirv: Preserve inbounds access information
authorKonstantin Seurer <konstantin.seurer@gmail.com>
Thu, 26 May 2022 19:12:33 +0000 (21:12 +0200)
committerMarge Bot <emma+marge@anholt.net>
Thu, 9 Jun 2022 16:20:16 +0000 (16:20 +0000)
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>

src/compiler/nir/nir.h
src/compiler/nir/nir_clone.c
src/compiler/nir/nir_deref.c
src/compiler/nir/nir_instr_set.c
src/compiler/nir/nir_serialize.c
src/compiler/spirv/vtn_private.h
src/compiler/spirv/vtn_variables.c

index 295ab30..b6387fd 100644 (file)
@@ -1531,6 +1531,7 @@ typedef struct {
    union {
       struct {
          nir_src index;
+         bool in_bounds;
       } arr;
 
       struct {
index 0a58f32..ee509da 100644 (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:
index bb1bb91..f9d599c 100644 (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);
 
index 4439281..9ce5793 100644 (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:
index 4c12afb..bd69225 100644 (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);
index 6a9d139..b4b0513 100644 (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
index e8161e2..0eb7f60 100644 (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;