i965: Don't copy propagate bitcasts with source modifiers.
authorMatt Turner <mattst88@gmail.com>
Thu, 8 Aug 2013 23:41:48 +0000 (16:41 -0700)
committerMatt Turner <mattst88@gmail.com>
Fri, 16 Aug 2013 20:11:07 +0000 (13:11 -0700)
Previously, copy propagation would cause bitcast_f2u(abs(float)) to
be performed in a single step, but the application of source modifiers
(abs, neg) happens after type conversion, leading to incorrect results.

That is, for bitcast_f2u(abs(float)) we would in fact generate code to
do abs(bitcast_f2u(float)).

For example, whereas bitcast_f2u(abs(float)) might result in a register
argument such as
   (abs)g2.2<0,1,0>UD

v2: Set interfered = true and break in register_coalesce instead of
    returning false.

Reviewed-by: Paul Berry <stereoytpe441@gmail.com>
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp

index 69e544aa4e1b20202e5acd7d2941c39099e5dc1b..d111cbd28cd322a50c941815146c39cbf006d11b 100644 (file)
@@ -2118,6 +2118,20 @@ fs_visitor::register_coalesce()
            }
         }
 
+         if (has_source_modifiers) {
+            for (int i = 0; i < 3; i++) {
+               if (scan_inst->src[i].file == GRF &&
+                   scan_inst->src[i].reg == inst->dst.reg &&
+                   scan_inst->src[i].reg_offset == inst->dst.reg_offset &&
+                   inst->dst.type != scan_inst->src[i].type)
+               {
+                 interfered = true;
+                 break;
+               }
+            }
+         }
+
+
         /* The gen6 MATH instruction can't handle source modifiers or
          * unusual register regions, so avoid coalescing those for
          * now.  We should do something more specific.
index 234f8bd3870c988094ee207c96ca5e9c67265f21..61b2617a9e099262cd900d517bab79b3af934d71 100644 (file)
@@ -221,6 +221,9 @@ fs_visitor::try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry)
         entry->src.smear != -1) && !can_do_source_mods(inst))
       return false;
 
+   if (has_source_modifiers && entry->dst.type != inst->src[arg].type)
+      return false;
+
    inst->src[arg].file = entry->src.file;
    inst->src[arg].reg = entry->src.reg;
    inst->src[arg].reg_offset = entry->src.reg_offset;
index c28d0dee2d82b94d993cf18f59f641effcc6b600..fdbe96c2e01d36f84a8e627543a1dda3d46d69f0 100644 (file)
@@ -206,14 +206,16 @@ vec4_visitor::try_copy_propagation(vec4_instruction *inst, int arg,
    if (inst->src[arg].negate)
       value.negate = !value.negate;
 
-   bool has_source_modifiers = (value.negate || value.abs ||
-                                value.swizzle != BRW_SWIZZLE_XYZW ||
-                                value.file == UNIFORM);
+   bool has_source_modifiers = value.negate || value.abs;
 
    /* gen6 math and gen7+ SENDs from GRFs ignore source modifiers on
     * instructions.
     */
-   if (has_source_modifiers && !can_do_source_mods(inst))
+   if ((has_source_modifiers || value.file == UNIFORM ||
+        value.swizzle != BRW_SWIZZLE_XYZW) && !can_do_source_mods(inst))
+      return false;
+
+   if (has_source_modifiers && value.type != inst->src[arg].type)
       return false;
 
    bool is_3src_inst = (inst->opcode == BRW_OPCODE_LRP ||