diff options
author | Matt Turner <[email protected]> | 2015-01-13 13:35:15 -0800 |
---|---|---|
committer | Matt Turner <[email protected]> | 2015-01-15 10:10:44 -0800 |
commit | 3654b6d43ceef9f74465ee20404513892761b8da (patch) | |
tree | 79c4734501c3e0317f25111ce77b59f94b9c8daf | |
parent | c4fab711ed5bbdb6b8421a1b980215032fc795b8 (diff) |
i965/fs: Emit MADs from (x + abs(y * z)).
Just use the abs source modifier on both of the multiplicand
arguments.
instructions in affected programs: 300 -> 296 (-1.33%)
Reviewed-by: Kristian Høgsberg <[email protected]>
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 7c062ec8abd..4f899748e9e 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -431,8 +431,11 @@ fs_visitor::try_emit_mad(ir_expression *ir) ir_rvalue *nonmul = ir->operands[1]; ir_expression *mul = ir->operands[0]->as_expression(); - bool mul_negate = false; - if (mul && mul->operation == ir_unop_neg) { + bool mul_negate = false, mul_abs = false; + if (mul && mul->operation == ir_unop_abs) { + mul = mul->operands[0]->as_expression(); + mul_abs = true; + } else if (mul && mul->operation == ir_unop_neg) { mul = mul->operands[0]->as_expression(); mul_negate = true; } @@ -441,7 +444,10 @@ fs_visitor::try_emit_mad(ir_expression *ir) nonmul = ir->operands[0]; mul = ir->operands[1]->as_expression(); - if (mul && mul->operation == ir_unop_neg) { + if (mul && mul->operation == ir_unop_abs) { + mul = mul->operands[0]->as_expression(); + mul_abs = true; + } else if (mul && mul->operation == ir_unop_neg) { mul = mul->operands[0]->as_expression(); mul_negate = true; } @@ -461,9 +467,15 @@ fs_visitor::try_emit_mad(ir_expression *ir) mul->operands[0]->accept(this); fs_reg src1 = this->result; src1.negate ^= mul_negate; + src1.abs = mul_abs; + if (mul_abs) + src1.negate = false; mul->operands[1]->accept(this); fs_reg src2 = this->result; + src2.abs = mul_abs; + if (mul_abs) + src2.negate = false; this->result = fs_reg(this, ir->type); emit(BRW_OPCODE_MAD, this->result, src0, src1, src2); |