i965/vec4: Consider sources of non-GRF-dst instructions for dead channels.
authorMatt Turner <mattst88@gmail.com>
Tue, 1 Apr 2014 21:05:39 +0000 (14:05 -0700)
committerMatt Turner <mattst88@gmail.com>
Sat, 5 Apr 2014 16:47:36 +0000 (09:47 -0700)
Previously we'd ignore the sources of instructions with non-GRF
destinations when calculating calculating the dead channels. This would
lead to us incorrectly removing the first instruction in this sequence:

   mov vgrf11, ...
   cmp.ne.f0 null, vgrf11, 1.0
   mov vgrf11, ...

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=76616

src/mesa/drivers/dri/i965/brw_vec4.cpp

index a86d42c925d906804ea13fec71f751f3adba57cb..740d9ff60339507c86a3f30c3df82c8ffded103b 100644 (file)
@@ -325,6 +325,9 @@ static bool
 try_eliminate_instruction(vec4_instruction *inst, int new_writemask,
                           const struct brw_context *brw)
 {
+   if (inst->has_side_effects())
+      return false;
+
    if (new_writemask == 0) {
       /* Don't dead code eliminate instructions that write to the
        * accumulator as a side-effect. Instead just set the destination
@@ -387,9 +390,6 @@ vec4_visitor::dead_code_eliminate()
 
       seen_control_flow = inst->is_control_flow() || seen_control_flow;
 
-      if (inst->has_side_effects())
-         continue;
-
       bool inst_writes_flag = false;
       if (inst->dst.file != GRF) {
          if (inst->dst.is_null() && inst->writes_flag()) {
@@ -443,22 +443,18 @@ vec4_visitor::dead_code_eliminate()
            node = prev, prev = prev->prev) {
          vec4_instruction *scan_inst = (vec4_instruction  *)node;
 
-         if (scan_inst->has_side_effects())
-            continue;
-
          if (inst_writes_flag) {
             if (scan_inst->dst.is_null() && scan_inst->writes_flag()) {
                scan_inst->remove();
                progress = true;
+               continue;
             } else if (scan_inst->reads_flag()) {
-               dead_channels = 0;
+               break;
             }
-            continue;
-         } else if (scan_inst->dst.file != GRF) {
-            continue;
          }
 
-         if (inst->dst.reg == scan_inst->dst.reg) {
+         if (inst->dst.file == scan_inst->dst.file &&
+             inst->dst.reg == scan_inst->dst.reg) {
             int new_writemask = scan_inst->dst.writemask & ~dead_channels;
 
             progress = try_eliminate_instruction(scan_inst, new_writemask, brw) ||
@@ -466,7 +462,7 @@ vec4_visitor::dead_code_eliminate()
          }
 
          for (int i = 0; i < 3; i++) {
-            if (scan_inst->src[i].file != GRF ||
+            if (scan_inst->src[i].file != inst->dst.file ||
                 scan_inst->src[i].reg != inst->dst.reg)
                continue;