summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorMatt Turner <[email protected]>2013-09-19 19:31:31 -0700
committerMatt Turner <[email protected]>2013-10-07 10:41:17 -0700
commit92dc16c3e2e2b9e3e71baaccc67bbe727e9d68ab (patch)
tree9914701a22acd54cb4ed8bead7cb2430521567da /src/mesa
parent014cce3dc49f5b0bfd7fbb1940ed661c9fc7bbd7 (diff)
i965: Don't dead-code eliminate instructions that write to the accumulator.
Reviewed-by: Paul Berry <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp16
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.cpp16
2 files changed, 30 insertions, 2 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index b2c9f5a8e32..b83aca447e5 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -1846,7 +1846,21 @@ fs_visitor::dead_code_eliminate()
if (inst->dst.file == GRF) {
assert(this->virtual_grf_end[inst->dst.reg] >= pc);
if (this->virtual_grf_end[inst->dst.reg] == pc) {
- inst->remove();
+ /* Don't dead code eliminate instructions that write to the
+ * accumulator as a side-effect. Instead just set the destination
+ * to the null register to free it.
+ */
+ switch (inst->opcode) {
+ case BRW_OPCODE_ADDC:
+ case BRW_OPCODE_SUBB:
+ case BRW_OPCODE_MACH:
+ inst->dst.file = ARF;
+ inst->dst.reg = BRW_ARF_NULL;
+ break;
+ default:
+ inst->remove();
+ break;
+ }
progress = true;
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index 75c3d344b5e..790ff2ebc72 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -314,7 +314,21 @@ vec4_visitor::dead_code_eliminate()
if (inst->dst.file == GRF) {
assert(this->virtual_grf_end[inst->dst.reg] >= pc);
if (this->virtual_grf_end[inst->dst.reg] == pc) {
- inst->remove();
+ /* Don't dead code eliminate instructions that write to the
+ * accumulator as a side-effect. Instead just set the destination
+ * to the null register to free it.
+ */
+ switch (inst->opcode) {
+ case BRW_OPCODE_ADDC:
+ case BRW_OPCODE_SUBB:
+ case BRW_OPCODE_MACH:
+ inst->dst.file = ARF;
+ inst->dst.reg = BRW_ARF_NULL;
+ break;
+ default:
+ inst->remove();
+ break;
+ }
progress = true;
}
}