summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2017-01-24 12:26:54 -0800
committerFrancisco Jerez <[email protected]>2017-01-31 10:32:43 -0800
commit69042a5be4664c7928a21bd23e4f6795bfb19f60 (patch)
tree3252b6a3bd9ac89788aee548fbba05bcb5b4046f
parent7ec3af3f8ff6584542f029c28abc2bcae1402259 (diff)
i965/fs: Fix nir_op_fsign of absolute value.
This does point at the front-end emitting silly code that could have been optimized out, but the current fsign implementation would emit bogus IR if abs was set for the argument (because it would apply the abs modifier on an unsigned integer type), and we shouldn't rely on the upper layer's optimization passes for correctness. Reviewed-by: Ian Romanick <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_nir.cpp9
1 files changed, 8 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index e1ab59854e6..e0c2fa01ce3 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -701,7 +701,14 @@ fs_visitor::nir_emit_alu(const fs_builder &bld, nir_alu_instr *instr)
break;
case nir_op_fsign: {
- if (type_sz(op[0].type) < 8) {
+ if (op[0].abs) {
+ /* Straightforward since the source can be assumed to be
+ * non-negative.
+ */
+ set_condmod(BRW_CONDITIONAL_NZ, bld.MOV(result, op[0]));
+ set_predicate(BRW_PREDICATE_NORMAL, bld.MOV(result, brw_imm_f(1.0f)));
+
+ } else if (type_sz(op[0].type) < 8) {
/* AND(val, 0x80000000) gives the sign bit.
*
* Predicated OR ORs 1.0 (0x3f800000) with the sign bit if val is not