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

Iago Toral Quiroga itoral at igalia.com
Thu Feb 18 11:59:42 UTC 2016


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(-)

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;
-- 
2.1.4



More information about the mesa-dev mailing list