i965/fs: Fix nir_op_fsign of absolute value.
authorFrancisco Jerez <currojerez@riseup.net>
Tue, 24 Jan 2017 20:26:54 +0000 (12:26 -0800)
committerFrancisco Jerez <currojerez@riseup.net>
Tue, 31 Jan 2017 18:32:43 +0000 (10:32 -0800)
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 <ian.d.romanick@intel.com>
src/mesa/drivers/dri/i965/brw_fs_nir.cpp

index e1ab59854e664d132af28ed5f40f9ee5695f58f5..e0c2fa01ce3c1fef38d6b0107009568476cf9610 100644 (file)
@@ -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