[Mesa-dev,27/32] i965: Handle negated unsigned immediate values in constant propagation.

Submitted by Francisco Jerez on Feb. 6, 2015, 2:43 p.m.

Details

Message ID 1423233792-11767-27-git-send-email-currojerez@riseup.net
State New
Headers show

Not browsing as part of any series.

Commit Message

Francisco Jerez Feb. 6, 2015, 2:43 p.m.
Negation of UD/UW sources behaves the same as for D/W sources, taking
the two's complement of the source, except for bitwise logical
operations on Gen8 and up which take the one's complement.  Fixes
crash in a GLSL shader with subtraction of two unsigned values.
---
 .../drivers/dri/i965/brw_fs_copy_propagation.cpp   |  6 ++++--
 src/mesa/drivers/dri/i965/brw_shader.cpp           |  8 ++------
 .../drivers/dri/i965/brw_vec4_copy_propagation.cpp | 24 ++++++++++++----------
 3 files changed, 19 insertions(+), 19 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 60a1b8c..3bc4435 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
@@ -453,13 +453,15 @@  fs_visitor::try_constant_propagate(fs_inst *inst, acp_entry *entry)
       val.type = inst->src[i].type;
 
       if (inst->src[i].abs) {
-         if (!brw_abs_immediate(val.type, &val.fixed_hw_reg)) {
+         if ((brw->gen >= 8 && is_logic_op(inst->opcode)) ||
+             !brw_abs_immediate(val.type, &val.fixed_hw_reg)) {
             continue;
          }
       }
 
       if (inst->src[i].negate) {
-         if (!brw_negate_immediate(val.type, &val.fixed_hw_reg)) {
+         if ((brw->gen >= 8 && is_logic_op(inst->opcode)) ||
+             !brw_negate_immediate(val.type, &val.fixed_hw_reg)) {
             continue;
          }
       }
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
index af59b8a..67d8de4 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -623,9 +623,11 @@  brw_negate_immediate(enum brw_reg_type type, struct brw_reg *reg)
 {
    switch (type) {
    case BRW_REGISTER_TYPE_D:
+   case BRW_REGISTER_TYPE_UD:
       reg->dw1.d = -reg->dw1.d;
       return true;
    case BRW_REGISTER_TYPE_W:
+   case BRW_REGISTER_TYPE_UW:
       reg->dw1.d = -(int16_t)reg->dw1.ud;
       return true;
    case BRW_REGISTER_TYPE_F:
@@ -637,12 +639,6 @@  brw_negate_immediate(enum brw_reg_type type, struct brw_reg *reg)
    case BRW_REGISTER_TYPE_UB:
    case BRW_REGISTER_TYPE_B:
       unreachable("no UB/B immediates");
-   case BRW_REGISTER_TYPE_UD:
-   case BRW_REGISTER_TYPE_UW:
-      /* Presumably the negate modifier on an unsigned source is the same as
-       * on a signed source but it would be nice to confirm.
-       */
-      assert(!"unimplemented: negate UD/UW immediate");
    case BRW_REGISTER_TYPE_UV:
    case BRW_REGISTER_TYPE_V:
       assert(!"unimplemented: negate UV/V immediate");
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
index 0a961ce..cc2d825 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
@@ -96,6 +96,15 @@  swizzle_vf_imm(unsigned vf4, unsigned swizzle)
 }
 
 static bool
+is_logic_op(enum opcode opcode)
+{
+   return (opcode == BRW_OPCODE_AND ||
+           opcode == BRW_OPCODE_OR  ||
+           opcode == BRW_OPCODE_XOR ||
+           opcode == BRW_OPCODE_NOT);
+}
+
+static bool
 try_constant_propagate(struct brw_context *brw, vec4_instruction *inst,
                        int arg, struct copy_entry *entry)
 {
@@ -124,13 +133,15 @@  try_constant_propagate(struct brw_context *brw, vec4_instruction *inst,
    }
 
    if (inst->src[arg].abs) {
-      if (!brw_abs_immediate(value.type, &value.fixed_hw_reg)) {
+      if ((brw->gen >= 8 && is_logic_op(inst->opcode)) ||
+          !brw_abs_immediate(value.type, &value.fixed_hw_reg)) {
          return false;
       }
    }
 
    if (inst->src[arg].negate) {
-      if (!brw_negate_immediate(value.type, &value.fixed_hw_reg)) {
+      if ((brw->gen >= 8 && is_logic_op(inst->opcode)) ||
+          !brw_negate_immediate(value.type, &value.fixed_hw_reg)) {
          return false;
       }
    }
@@ -236,15 +247,6 @@  try_constant_propagate(struct brw_context *brw, vec4_instruction *inst,
 }
 
 static bool
-is_logic_op(enum opcode opcode)
-{
-   return (opcode == BRW_OPCODE_AND ||
-           opcode == BRW_OPCODE_OR  ||
-           opcode == BRW_OPCODE_XOR ||
-           opcode == BRW_OPCODE_NOT);
-}
-
-static bool
 try_copy_propagate(struct brw_context *brw, vec4_instruction *inst,
                    int arg, struct copy_entry *entry, int reg)
 {