r600g: don't change the order of writes in merge_inst_group
authorVadim Girlin <vadimgirlin@gmail.com>
Wed, 16 Nov 2011 23:33:57 +0000 (03:33 +0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 17 Nov 2011 14:10:37 +0000 (09:10 -0500)
Merge may produce incorrect order of operations for r600-eg:

x: inst1 R0.x, ... ;  //from current group
...
t: inst0 R0.x, ... ;  //from previous group, same destination

Result of inst1 will be lost.

So compare destinations and don't allow this.

Signed-off-by: Vadim Girlin <vadimgirlin@gmail.com>
src/gallium/drivers/r600/r600_asm.c

index 6b1ad65b60fe1f4e4f21786ffc898b1a4d6fdaed..1ab16f288218068e6d5c571129700c68987f0104 100644 (file)
@@ -1010,6 +1010,11 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu
                                        result[i] = prev[i];
                                        result[4] = slots[i];
                                } else if (is_alu_any_unit_inst(bc, prev[i])) {
+                                       if (slots[i]->dst.sel == prev[i]->dst.sel &&
+                                               (slots[i]->dst.write == 1 || slots[i]->is_op3) &&
+                                               (prev[i]->dst.write == 1 || prev[i]->is_op3))
+                                               return 0;
+
                                        result[i] = slots[i];
                                        result[4] = prev[i];
                                } else
@@ -1018,8 +1023,16 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu
                                return 0;
                } else if(!slots[i]) {
                        continue;
-               } else
+               } else {
+                       if (max_slots == 5 && slots[i] && prev[4] &&
+                                       slots[i]->dst.sel == prev[4]->dst.sel &&
+                                       slots[i]->dst.chan == prev[4]->dst.chan &&
+                                       (slots[i]->dst.write == 1 || slots[i]->is_op3) &&
+                                       (prev[4]->dst.write == 1 || prev[4]->is_op3))
+                               return 0;
+
                        result[i] = slots[i];
+               }
 
                alu = slots[i];
                num_once_inst += is_alu_once_inst(bc, alu);