i965/vec4: Fix handling of multiple register reads and writes in opt_cse().
authorFrancisco Jerez <currojerez@riseup.net>
Wed, 18 Mar 2015 17:51:01 +0000 (19:51 +0200)
committerFrancisco Jerez <currojerez@riseup.net>
Mon, 23 Mar 2015 12:12:56 +0000 (14:12 +0200)
Reviewed-by: Matt Turner <mattst88@gmail.com>
src/mesa/drivers/dri/i965/brw_vec4_cse.cpp

index 2c29d9f89996283b9c524fd7bc223d71e1e567ae..0a687313a4ebb08022c90418340c46a43d942b1a 100644 (file)
@@ -114,6 +114,7 @@ instructions_match(vec4_instruction *a, vec4_instruction *b)
           a->conditional_mod == b->conditional_mod &&
           a->dst.type == b->dst.type &&
           a->dst.writemask == b->dst.writemask &&
+          a->regs_written == b->regs_written &&
           operands_match(a, b);
 }
 
@@ -160,21 +161,29 @@ vec4_visitor::opt_cse_local(bblock_t *block)
              */
             bool no_existing_temp = entry->tmp.file == BAD_FILE;
             if (no_existing_temp && !entry->generator->dst.is_null()) {
-               entry->tmp = src_reg(this, glsl_type::float_type);
-               entry->tmp.type = inst->dst.type;
-               entry->tmp.swizzle = BRW_SWIZZLE_XYZW;
+               entry->tmp = retype(src_reg(GRF, alloc.allocate(
+                                              entry->generator->regs_written),
+                                           NULL), inst->dst.type);
+
+               for (unsigned i = 0; i < entry->generator->regs_written; ++i) {
+                  vec4_instruction *copy = MOV(offset(entry->generator->dst, i),
+                                               offset(entry->tmp, i));
+                  entry->generator->insert_after(block, copy);
+               }
 
-               vec4_instruction *copy = MOV(entry->generator->dst, entry->tmp);
-               entry->generator->insert_after(block, copy);
                entry->generator->dst = dst_reg(entry->tmp);
             }
 
             /* dest <- temp */
             if (!inst->dst.is_null()) {
                assert(inst->dst.type == entry->tmp.type);
-               vec4_instruction *copy = MOV(inst->dst, entry->tmp);
-               copy->force_writemask_all = inst->force_writemask_all;
-               inst->insert_before(block, copy);
+
+               for (unsigned i = 0; i < inst->regs_written; ++i) {
+                  vec4_instruction *copy = MOV(offset(inst->dst, i),
+                                               offset(entry->tmp, i));
+                  copy->force_writemask_all = inst->force_writemask_all;
+                  inst->insert_before(block, copy);
+               }
             }
 
             /* Set our iterator so that next time through the loop inst->next