nir: get ffma support from NIR options for nir_lower_flrp
[mesa.git] / src / compiler / nir / nir_opt_combine_stores.c
index 6bd2c5349716f8dca221e87a7b0f9e95c1d01130..08fa4ac4463b32705ee04dc5817f74be16e614d6 100644 (file)
@@ -287,10 +287,11 @@ combine_stores_block(struct combine_stores_state *state, nir_block *block)
    nir_foreach_instr_safe(instr, block) {
       if (instr->type == nir_instr_type_call) {
          combine_stores_with_modes(state, nir_var_shader_out |
-                                              nir_var_shader_temp |
-                                              nir_var_function_temp |
-                                              nir_var_mem_ssbo |
-                                              nir_var_mem_shared);
+                                          nir_var_shader_temp |
+                                          nir_var_function_temp |
+                                          nir_var_mem_ssbo |
+                                          nir_var_mem_shared |
+                                          nir_var_mem_global);
          continue;
       }
 
@@ -300,27 +301,44 @@ combine_stores_block(struct combine_stores_state *state, nir_block *block)
       nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
       switch (intrin->intrinsic) {
       case nir_intrinsic_store_deref:
-         update_combined_store(state, intrin);
+         if (nir_intrinsic_access(intrin) & ACCESS_VOLATILE) {
+            nir_deref_instr *dst = nir_src_as_deref(intrin->src[0]);
+            /* When we see a volatile store, we go ahead and combine all
+             * previous non-volatile stores which touch that address and
+             * specifically don't add the volatile store to the list.  This
+             * way we guarantee that the volatile store isn't combined with
+             * anything and no non-volatile stores are combined across a
+             * volatile store.
+             */
+            combine_stores_with_deref(state, dst);
+         } else {
+            update_combined_store(state, intrin);
+         }
          break;
 
-      case nir_intrinsic_barrier:
+      case nir_intrinsic_control_barrier:
       case nir_intrinsic_group_memory_barrier:
       case nir_intrinsic_memory_barrier:
          combine_stores_with_modes(state, nir_var_shader_out |
-                                              nir_var_mem_ssbo |
-                                              nir_var_mem_shared);
+                                          nir_var_mem_ssbo |
+                                          nir_var_mem_shared |
+                                          nir_var_mem_global);
          break;
 
-      case nir_intrinsic_memory_barrier_atomic_counter:
       case nir_intrinsic_memory_barrier_buffer:
-         combine_stores_with_modes(state, nir_var_mem_ssbo);
+         combine_stores_with_modes(state, nir_var_mem_ssbo |
+                                          nir_var_mem_global);
          break;
 
       case nir_intrinsic_memory_barrier_shared:
          combine_stores_with_modes(state, nir_var_mem_shared);
          break;
 
-      case nir_intrinsic_scoped_memory_barrier:
+      case nir_intrinsic_memory_barrier_tcs_patch:
+         combine_stores_with_modes(state, nir_var_shader_out);
+         break;
+
+      case nir_intrinsic_scoped_barrier:
          if (nir_intrinsic_memory_semantics(intrin) & NIR_MEMORY_RELEASE) {
             combine_stores_with_modes(state,
                                       nir_intrinsic_memory_modes(intrin));
@@ -382,6 +400,8 @@ combine_stores_impl(struct combine_stores_state *state, nir_function_impl *impl)
    if (state->progress) {
       nir_metadata_preserve(impl, nir_metadata_block_index |
                                   nir_metadata_dominance);
+   } else {
+      nir_metadata_preserve(impl, nir_metadata_all);
    }
 
    return state->progress;