i965: Fix constant propagation into 32-bit integer MUL.
authorPaul Berry <stereotype441@gmail.com>
Wed, 2 Nov 2011 03:35:23 +0000 (20:35 -0700)
committerPaul Berry <stereotype441@gmail.com>
Fri, 4 Nov 2011 01:18:34 +0000 (18:18 -0700)
i965's MUL instruction can't take an immediate value as its first
argument.  So normally, if constant propagation wants to propagate a
constant into the first argument of a MUL instruction, it swaps the
order of the two arguments.

This doesn't work for 32-bit integer (and unsigned integer)
multiplies, because the MUL operation is asymmetric in that case (it
multiplies 16 bits of one operand by 32 bits of the other).

Fixes piglit tests {vs,fs}-multiply-const-{ivec4,uvec4}.

Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp

index e58545bb9d97f5c656dc39ce7e5d042e5b4b655f..b66febbde003311d4b0df2c6f3b767160b93a9c9 100644 (file)
@@ -1127,7 +1127,14 @@ fs_visitor::propagate_constants()
                  scan_inst->src[i] = inst->src[0];
                  progress = true;
               } else if (i == 0 && scan_inst->src[1].file != IMM) {
-                 /* Fit this constant in by commuting the operands */
+                 /* Fit this constant in by commuting the operands.
+                  * Exception: we can't do this for 32-bit integer MUL
+                  * because it's asymmetric.
+                  */
+                 if (scan_inst->opcode == BRW_OPCODE_MUL &&
+                     (scan_inst->src[1].type == BRW_REGISTER_TYPE_D ||
+                      scan_inst->src[1].type == BRW_REGISTER_TYPE_UD))
+                    break;
                  scan_inst->src[0] = scan_inst->src[1];
                  scan_inst->src[1] = inst->src[0];
                  progress = true;
index c3a9deee76b8b3f5923c6dac1c60ebe07b9914d1..93ae3d61cac8d30bbc8c8832f85c2c71afdc25db 100644 (file)
@@ -101,7 +101,13 @@ try_constant_propagation(vec4_instruction *inst, int arg, src_reg *values[4])
         inst->src[arg] = value;
         return true;
       } else if (arg == 0 && inst->src[1].file != IMM) {
-        /* Fit this constant in by commuting the operands */
+        /* Fit this constant in by commuting the operands.  Exception: we
+         * can't do this for 32-bit integer MUL because it's asymmetric.
+         */
+        if (inst->opcode == BRW_OPCODE_MUL &&
+            (inst->src[1].type == BRW_REGISTER_TYPE_D ||
+             inst->src[1].type == BRW_REGISTER_TYPE_UD))
+           break;
         inst->src[0] = inst->src[1];
         inst->src[1] = value;
         return true;