[Mesa-dev] i965/fs: fix copy propagation from sources with stride 0

Submitted by Iago Toral Quiroga on Feb. 18, 2016, 11:59 a.m.

Details

Message ID 1455796782-27440-1-git-send-email-itoral@igalia.com
State New
Headers show
Series "i965/fs: fix copy propagation from sources with stride 0" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Iago Toral Quiroga Feb. 18, 2016, 11:59 a.m.
We should not offset into them based on the relative offset of
our source and the destination of the instruction we are copy
propagating from, so we don't turn this:

mov(16) vgrf6:F, vgrf7+0.0<0>:F
(...)
load_payload(8) vgrf28:F, vgrf6+1.0:F 2ndhalf
mov(8) vgrf29:DF, vgrf28:F 2ndhalf

into:

mov(16) vgrf6:F, vgrf7+0.0<0>:F
(...)
load_payload(8) vgrf28:F, vgrf7+1.0<0>:F 2ndhalf
mov(8) vgrf29:DF, vgrf7+1.0<0>:F 2ndhalf

and instead we do this:

mov(16) vgrf6:F, vgrf7+0.0<0>:F
(...)
load_payload(8) vgrf28:F, vgrf7+0.0<0>:F 2ndhalf
mov(8) vgrf29:DF, vgrf7+0.0<0>:F 2ndhalf
---

This hit me while working on FP64 (that's why there are DF references
in the snippets above) but the problem is not specific to that so I
figured it was best to send this ahead.

 src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
index f0b9110..a6da13d 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
@@ -460,10 +460,20 @@  fs_visitor::try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry)
           * parts of vgrfs so we have to do some reg_offset magic.
           */
 
-         /* Compute the offset of inst->src[arg] relative to inst->dst */
+         /* Compute the offset of inst->src[arg] relative to inst->dst
+          *
+          * If the source we are copy propagating from has a stride of 0, then
+          * we must not offset into it based on the offset of our source
+          * relative to entry->dst
+          */
          assert(entry->dst.subreg_offset == 0);
-         int rel_offset = inst->src[arg].reg_offset - entry->dst.reg_offset;
-         int rel_suboffset = inst->src[arg].subreg_offset;
+         int rel_offset, rel_suboffset;
+         if (entry->src.stride != 0) {
+            rel_offset = inst->src[arg].reg_offset - entry->dst.reg_offset;
+            rel_suboffset = inst->src[arg].subreg_offset;
+         } else {
+            rel_offset = rel_suboffset = 0;
+         }
 
          /* Compute the final register offset (in bytes) */
          int offset = entry->src.reg_offset * 32 + entry->src.subreg_offset;