nir/copy_prop_vars: Handle volatile better
authorJason Ekstrand <jason@jlekstrand.net>
Tue, 14 Apr 2020 16:01:15 +0000 (11:01 -0500)
committerMarge Bot <eric+marge@anholt.net>
Tue, 28 Apr 2020 22:55:25 +0000 (22:55 +0000)
For deref_store, we can still delete invalid stores that write to
statically OOB data.  For everything, we need to make sure that we kill
aliases of destinations even if it's volatile.

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4767>

src/compiler/nir/nir_opt_copy_prop_vars.c

index 05bdec50f453b76ebac1489830f76d7103d47163..dca5320a6761072ce1999f4563d90bfb21b070b6 100644 (file)
@@ -930,9 +930,6 @@ copy_prop_vars_block(struct copy_prop_var_state *state,
       case nir_intrinsic_store_deref: {
          if (debug) dump_instr(instr);
 
-         if (nir_intrinsic_access(intrin) & ACCESS_VOLATILE)
-            break;
-
          nir_deref_instr *dst = nir_src_as_deref(intrin->src[0]);
          assert(glsl_type_is_vector_or_scalar(dst->type));
 
@@ -954,6 +951,12 @@ copy_prop_vars_block(struct copy_prop_var_state *state,
             }
          }
 
+         if (nir_intrinsic_access(intrin) & ACCESS_VOLATILE) {
+            unsigned wrmask = nir_intrinsic_write_mask(intrin);
+            kill_aliases(copies, dst, wrmask);
+            break;
+         }
+
          struct copy_entry *entry =
             lookup_entry_for_deref(copies, dst, nir_derefs_equal_bit);
          if (entry && value_equals_store_src(&entry->src, intrin)) {
@@ -977,25 +980,27 @@ copy_prop_vars_block(struct copy_prop_var_state *state,
       case nir_intrinsic_copy_deref: {
          if (debug) dump_instr(instr);
 
-         if ((nir_intrinsic_src_access(intrin) & ACCESS_VOLATILE) ||
-             (nir_intrinsic_dst_access(intrin) & ACCESS_VOLATILE))
-            break;
-
          nir_deref_instr *dst = nir_src_as_deref(intrin->src[0]);
          nir_deref_instr *src = nir_src_as_deref(intrin->src[1]);
 
-         if (nir_compare_derefs(src, dst) & nir_derefs_equal_bit) {
-            /* This is a no-op self-copy.  Get rid of it */
-            nir_instr_remove(instr);
-            continue;
-         }
-
          /* The copy_deref intrinsic doesn't keep track of num_components, so
           * get it ourselves.
           */
          unsigned num_components = glsl_get_vector_elements(dst->type);
          unsigned full_mask = (1 << num_components) - 1;
 
+         if ((nir_intrinsic_src_access(intrin) & ACCESS_VOLATILE) ||
+             (nir_intrinsic_dst_access(intrin) & ACCESS_VOLATILE)) {
+            kill_aliases(copies, dst, full_mask);
+            break;
+         }
+
+         if (nir_compare_derefs(src, dst) & nir_derefs_equal_bit) {
+            /* This is a no-op self-copy.  Get rid of it */
+            nir_instr_remove(instr);
+            continue;
+         }
+
          /* Copy of direct array derefs of vectors are not handled.  Just
           * invalidate what's written and bail.
           */
@@ -1058,9 +1063,6 @@ copy_prop_vars_block(struct copy_prop_var_state *state,
       case nir_intrinsic_deref_atomic_comp_swap:
          if (debug) dump_instr(instr);
 
-         if (nir_intrinsic_access(intrin) & ACCESS_VOLATILE)
-            break;
-
          nir_deref_instr *dst = nir_src_as_deref(intrin->src[0]);
          unsigned num_components = glsl_get_vector_elements(dst->type);
          unsigned full_mask = (1 << num_components) - 1;