nir/load_store_vectorize: fix combining stores with aliasing loads between
[mesa.git] / src / compiler / nir / nir_opt_peephole_select.c
index 14f36e799de8ba00a002548976333c85afb295da..869f663a89a6636b6c06656b5cc6b541c254ed8c 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "nir.h"
 #include "nir_control_flow.h"
+#include "nir_search_helpers.h"
 
 /*
  * Implements a small peephole optimization that looks for
@@ -107,6 +108,8 @@ block_check_for_allowed_instrs(nir_block *block, unsigned *count,
 
       case nir_instr_type_alu: {
          nir_alu_instr *mov = nir_instr_as_alu(instr);
+         bool movelike = false;
+
          switch (mov->op) {
          case nir_op_mov:
          case nir_op_fneg:
@@ -116,6 +119,7 @@ block_check_for_allowed_instrs(nir_block *block, unsigned *count,
          case nir_op_vec2:
          case nir_op_vec3:
          case nir_op_vec4:
+            movelike = true;
             break;
 
          case nir_op_fcos:
@@ -148,8 +152,18 @@ block_check_for_allowed_instrs(nir_block *block, unsigned *count,
          if (!mov->dest.dest.is_ssa)
             return false;
 
+         const struct nir_block *const expected_block = mov->instr.block;
+         const nir_alu_type expected_type =
+            nir_alu_type_get_base_type(nir_op_infos[mov->op].output_type);
+
          if (alu_ok) {
-            (*count)++;
+            /* If the ALU operation is an fsat or a move-like operation, do
+             * not count it.  The expectation is that it will eventually be
+             * merged as a destination modifier or source modifier on some
+             * other instruction.
+             */
+            if (mov->op != nir_op_fsat && !movelike)
+               (*count)++;
          } else {
             /* Can't handle saturate */
             if (mov->dest.saturate)