i965: split EU defines to brw_eu_defines.h
[mesa.git] / src / mesa / drivers / dri / i965 / brw_vec4_cmod_propagation.cpp
index 7aa8f5d9b8fb060f883744b224aa4e97a4250f48..4454cdbfc94a25e153e2a18357141a10148b99d4 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "brw_vec4.h"
 #include "brw_cfg.h"
+#include "brw_eu.h"
 
 namespace brw {
 
@@ -67,15 +68,17 @@ opt_cmod_propagation_local(bblock_t *block)
 
       bool read_flag = false;
       foreach_inst_in_block_reverse_starting_from(vec4_instruction, scan_inst, inst) {
-         if (inst->src[0].in_range(scan_inst->dst,
-                                   scan_inst->regs_written)) {
+         if (regions_overlap(inst->src[0], inst->size_read(0),
+                             scan_inst->dst, scan_inst->size_written)) {
             if ((scan_inst->predicate && scan_inst->opcode != BRW_OPCODE_SEL) ||
-                scan_inst->dst.reg_offset != inst->src[0].reg_offset ||
+                scan_inst->dst.offset != inst->src[0].offset ||
                 (scan_inst->dst.writemask != WRITEMASK_X &&
                  scan_inst->dst.writemask != WRITEMASK_XYZW) ||
                 (scan_inst->dst.writemask == WRITEMASK_XYZW &&
                  inst->src[0].swizzle != BRW_SWIZZLE_XYZW) ||
-                (inst->dst.writemask & ~scan_inst->dst.writemask) != 0) {
+                (inst->dst.writemask & ~scan_inst->dst.writemask) != 0 ||
+                scan_inst->exec_size != inst->exec_size ||
+                scan_inst->group != inst->group) {
                break;
             }
 
@@ -114,6 +117,18 @@ opt_cmod_propagation_local(bblock_t *block)
                break;
             }
 
+            /* The conditional mod of the CMP/CMPN instructions behaves
+             * specially because the flag output is not calculated from the
+             * result of the instruction, but the other way around, which
+             * means that even if the condmod to propagate and the condmod
+             * from the CMP instruction are the same they will in general give
+             * different results because they are evaluated based on different
+             * inputs.
+             */
+            if (scan_inst->opcode == BRW_OPCODE_CMP ||
+                scan_inst->opcode == BRW_OPCODE_CMPN)
+               break;
+
             /* Otherwise, try propagating the conditional. */
             enum brw_conditional_mod cond =
                inst->src[0].negate ? brw_swap_cmod(inst->conditional_mod)