nir: Two shared memory *blocks* may alias each other
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Wed, 8 Jul 2020 00:38:03 +0000 (17:38 -0700)
committerMarge Bot <eric+marge@anholt.net>
Wed, 27 Jan 2021 22:20:53 +0000 (22:20 +0000)
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8699>

src/compiler/nir/nir_deref.c
src/compiler/nir/nir_remove_dead_variables.c

index 4735175..f406c87 100644 (file)
@@ -492,6 +492,18 @@ nir_compare_deref_paths(nir_deref_path *a_path,
              deref_path_contains_coherent_decoration(b_path))
             return nir_derefs_may_alias_bit;
 
+         /* Per SPV_KHR_workgroup_memory_explicit_layout and GL_EXT_shared_memory_block,
+          * shared blocks alias each other.
+          */
+         if (a_path->path[0]->modes & nir_var_mem_shared &&
+             b_path->path[0]->modes & nir_var_mem_shared &&
+             (glsl_type_is_interface(a_path->path[0]->var->type) ||
+              glsl_type_is_interface(b_path->path[0]->var->type))) {
+            assert(glsl_type_is_interface(a_path->path[0]->var->type) &&
+                   glsl_type_is_interface(b_path->path[0]->var->type));
+            return nir_derefs_may_alias_bit;
+         }
+
          /* If we can chase the deref all the way back to the variable and
           * they're not the same variable and at least one is not declared
           * coherent, we know they can't possibly alias.
index 19e56d0..0182c98 100644 (file)
@@ -71,8 +71,16 @@ add_var_use_deref(nir_deref_instr *deref, struct set *live)
     * make them live.  Only keep them if they are used by some intrinsic.
     */
    if ((deref->var->data.mode & (nir_var_function_temp |
-                                 nir_var_shader_temp |
-                                 nir_var_mem_shared)) &&
+                                 nir_var_shader_temp)) &&
+       !deref_used_for_not_store(deref))
+      return;
+
+   /*
+    * Shared memory blocks (interface type) alias each other, so be
+    * conservative in that case.
+    */
+   if ((deref->var->data.mode & nir_var_mem_shared) &&
+       !glsl_type_is_interface(deref->var->type) &&
        !deref_used_for_not_store(deref))
       return;