nir: Account for atomics in copy propagation.
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Thu, 17 Jan 2019 18:54:20 +0000 (19:54 +0100)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Thu, 17 Jan 2019 23:55:35 +0000 (00:55 +0100)
Otherwise writes get propagated across atomics if no barrier is
used. Without barrier writes should still be visible in the same
invocation, so an atomic has to be considered a write.

CC: <mesa-stable@lists.freedesktop.org>
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Fixes: b3c61469255 "nir: Copy propagation between blocks"
Fixes: 62332d139c8 "nir: Add a local variable-based copy propagation pass"
src/compiler/nir/nir_opt_copy_prop_vars.c

index 3dc0ad805738381506b7c3117bfc4a2a59ec188f..8a5e11550826f1c72bdccf11722cf0a92d47f8de 100644 (file)
@@ -157,9 +157,19 @@ gather_vars_written(struct copy_prop_var_state *state,
             written->modes = nir_var_shader_out;
             break;
 
+         case nir_intrinsic_deref_atomic_add:
+         case nir_intrinsic_deref_atomic_imin:
+         case nir_intrinsic_deref_atomic_umin:
+         case nir_intrinsic_deref_atomic_imax:
+         case nir_intrinsic_deref_atomic_umax:
+         case nir_intrinsic_deref_atomic_and:
+         case nir_intrinsic_deref_atomic_or:
+         case nir_intrinsic_deref_atomic_xor:
+         case nir_intrinsic_deref_atomic_exchange:
+         case nir_intrinsic_deref_atomic_comp_swap:
          case nir_intrinsic_store_deref:
          case nir_intrinsic_copy_deref: {
-            /* Destination in _both_ store_deref and copy_deref is src[0]. */
+            /* Destination in all of store_deref, copy_deref and the atomics is src[0]. */
             nir_deref_instr *dst = nir_src_as_deref(intrin->src[0]);
 
             uintptr_t mask = intrin->intrinsic == nir_intrinsic_store_deref ?
@@ -770,6 +780,19 @@ copy_prop_vars_block(struct copy_prop_var_state *state,
          break;
       }
 
+      case nir_intrinsic_deref_atomic_add:
+      case nir_intrinsic_deref_atomic_imin:
+      case nir_intrinsic_deref_atomic_umin:
+      case nir_intrinsic_deref_atomic_imax:
+      case nir_intrinsic_deref_atomic_umax:
+      case nir_intrinsic_deref_atomic_and:
+      case nir_intrinsic_deref_atomic_or:
+      case nir_intrinsic_deref_atomic_xor:
+      case nir_intrinsic_deref_atomic_exchange:
+      case nir_intrinsic_deref_atomic_comp_swap:
+         kill_aliases(copies, nir_src_as_deref(intrin->src[0]), 0xf);
+         break;
+
       default:
          break;
       }