intel/fs/gen12: Fix hangs with per-sample SIMD32 fragment shader dispatch.
[mesa.git] / src / intel / compiler / brw_vec4_cse.cpp
index d9f08c96317232ae0bdb4cab6d3b38c3fd85f1a2..585676a904280230f1ae0312f081170fc9d4d91a 100644 (file)
@@ -104,6 +104,25 @@ operands_match(const vec4_instruction *a, const vec4_instruction *b)
       return xs[0].equals(ys[0]) &&
              ((xs[1].equals(ys[1]) && xs[2].equals(ys[2])) ||
               (xs[2].equals(ys[1]) && xs[1].equals(ys[2])));
+   } else if (a->opcode == BRW_OPCODE_MOV &&
+              xs[0].file == IMM &&
+              xs[0].type == BRW_REGISTER_TYPE_VF) {
+      src_reg tmp_x = xs[0];
+      src_reg tmp_y = ys[0];
+
+      /* Smash out the values that are not part of the writemask.  Otherwise
+       * the equals operator will fail due to mismatches in unused components.
+       */
+      const unsigned ab_writemask = a->dst.writemask & b->dst.writemask;
+      const uint32_t mask = ((ab_writemask & WRITEMASK_X) ? 0x000000ff : 0) |
+                            ((ab_writemask & WRITEMASK_Y) ? 0x0000ff00 : 0) |
+                            ((ab_writemask & WRITEMASK_Z) ? 0x00ff0000 : 0) |
+                            ((ab_writemask & WRITEMASK_W) ? 0xff000000 : 0);
+
+      tmp_x.ud &= mask;
+      tmp_y.ud &= mask;
+
+      return tmp_x.equals(tmp_y);
    } else if (!a->is_commutative()) {
       return xs[0].equals(ys[0]) && xs[1].equals(ys[1]) && xs[2].equals(ys[2]);
    } else {
@@ -144,7 +163,7 @@ instructions_match(vec4_instruction *a, vec4_instruction *b)
 }
 
 bool
-vec4_visitor::opt_cse_local(bblock_t *block)
+vec4_visitor::opt_cse_local(bblock_t *block, const vec4_live_variables &live)
 {
    bool progress = false;
    exec_list aeb;
@@ -269,7 +288,7 @@ vec4_visitor::opt_cse_local(bblock_t *block)
              * more -- a sure sign they'll fail operands_match().
              */
             if (src->file == VGRF) {
-               if (var_range_end(var_from_reg(alloc, dst_reg(*src)), 8) < ip) {
+               if (live.var_range_end(var_from_reg(alloc, *src), 8) < ip) {
                   entry->remove();
                   ralloc_free(entry);
                   break;
@@ -290,15 +309,14 @@ bool
 vec4_visitor::opt_cse()
 {
    bool progress = false;
-
-   calculate_live_intervals();
+   const vec4_live_variables &live = live_analysis.require();
 
    foreach_block (block, cfg) {
-      progress = opt_cse_local(block) || progress;
+      progress = opt_cse_local(block, live) || progress;
    }
 
    if (progress)
-      invalidate_live_intervals();
+      invalidate_analysis(DEPENDENCY_INSTRUCTIONS | DEPENDENCY_VARIABLES);
 
    return progress;
 }