From: Francisco Jerez Date: Fri, 6 Feb 2015 12:38:20 +0000 (+0200) Subject: i965: Handle negated unsigned immediate values in constant propagation. X-Git-Tag: upstream/17.1.0~20904 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=aef83957e1e13ecb96df436d53373ecc4cedeb08;p=platform%2Fupstream%2Fmesa.git i965: Handle negated unsigned immediate values in constant propagation. 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. Reviewed-by: Matt Turner --- 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 807b81d..d6daac0 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.cpp +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp @@ -625,9 +625,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: @@ -639,12 +641,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 81567d2..4614e07 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) { @@ -114,13 +123,15 @@ try_constant_propagate(struct brw_context *brw, vec4_instruction *inst, return false; 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; } } @@ -226,15 +237,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) {