nir: Let nir_fixup_deref_modes() fix deref_casts when possible
authorCaio Oliveira <caio.oliveira@intel.com>
Mon, 19 Jun 2023 20:49:21 +0000 (13:49 -0700)
committerMarge Bot <emma+marge@anholt.net>
Thu, 27 Jul 2023 16:20:36 +0000 (16:20 +0000)
If a deref_cast parent is also a deref, and the parent mode is not
generic, we can safely propagate the parent mode down to the
deref_cast.

This will allow the fixup to work when the deref_cast is used just
to change the glsl_type when accessing a variable/deref-chain.

Reviewed-by: Faith Ekstrand <faith@gfxstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23734>

src/compiler/nir/nir_deref.c

index 03c2728..63f7c36 100644 (file)
@@ -421,16 +421,23 @@ nir_fixup_deref_modes_instr(UNUSED struct nir_builder *b, nir_instr *instr, UNUS
       return false;
 
    nir_deref_instr *deref = nir_instr_as_deref(instr);
-   if (deref->deref_type == nir_deref_type_cast)
-      return false;
-
    nir_variable_mode parent_modes;
    if (deref->deref_type == nir_deref_type_var) {
       parent_modes = deref->var->data.mode;
    } else {
-      assert(deref->parent.is_ssa);
-      nir_deref_instr *parent =
-         nir_instr_as_deref(deref->parent.ssa->parent_instr);
+      nir_deref_instr *parent = nir_src_as_deref(deref->parent);
+      if (parent == NULL) {
+         /* Cast to some non-deref value, nothing to propagate. */
+         assert(deref->deref_type == nir_deref_type_cast);
+         return false;
+      }
+
+      /* It's safe to propagate a specific mode into a more generic one
+       * but never the other way around.
+       */
+      if (util_bitcount(parent->modes) != 1)
+         return false;
+
       parent_modes = parent->modes;
    }