[Mesa-dev] [RFC 02/10] nir/lower_double_ops: lower neg()

Elie Tournier tournier.elie at gmail.com
Wed Apr 12 22:43:11 UTC 2017


Signed-off-by: Elie Tournier <elie.tournier at collabora.com>
---
 src/compiler/nir/nir.h                  |  3 ++-
 src/compiler/nir/nir_lower_double_ops.c | 45 +++++++++++++++++++++++++++++++++
 src/intel/compiler/brw_nir.c            |  3 ++-
 3 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 0ec09f54e2..e891d21499 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -2569,7 +2569,8 @@ typedef enum {
    nir_lower_dfract = (1 << 6),
    nir_lower_dround_even = (1 << 7),
    nir_lower_dmod = (1 << 8),
-   nir_lower_dabs = (1 << 9)
+   nir_lower_dabs = (1 << 9),
+   nir_lower_dneg = (1 << 10)
 } nir_lower_doubles_options;
 
 bool nir_lower_doubles(nir_shader *shader, nir_lower_doubles_options options);
diff --git a/src/compiler/nir/nir_lower_double_ops.c b/src/compiler/nir/nir_lower_double_ops.c
index 4ea8d339cc..eb16e513ae 100644
--- a/src/compiler/nir/nir_lower_double_ops.c
+++ b/src/compiler/nir/nir_lower_double_ops.c
@@ -62,6 +62,24 @@ get_exponent(nir_builder *b, nir_ssa_def *src)
    return nir_ubitfield_extract(b, hi, nir_imm_int(b, 20), nir_imm_int(b, 11));
 }
 
+static nir_ssa_def *
+is_nan(nir_builder *b, nir_ssa_def *src)
+{
+   nir_ssa_def *src_lo = nir_unpack_64_2x32_split_x(b, src);
+   nir_ssa_def *src_hi = nir_unpack_64_2x32_split_y(b, src);
+
+   /* return (0xFFE00000 <= (src_hi<<1)) &&
+    *    (src_lo || (src_hi & 0x000FFFFF));
+    */
+   return nir_iand(b,
+                   nir_fge(b,
+                           nir_ishl(b, src_hi, nir_imm_int(b, 1)),
+                           nir_imm_int(b, 0xFFE00000)),
+                   nir_ior(b, src_lo,
+                              nir_iand(b,src_hi,
+                                         nir_imm_int(b, 0x000FFFFF))));
+}
+
 /* Return infinity with the sign of the given source which is +/-0 */
 
 static nir_ssa_def *
@@ -466,6 +484,24 @@ lower_fabs64(nir_builder *b, nir_ssa_def *src)
    return nir_pack_64_2x32_split(b, src_lo, new_src_hi);
 }
 
+static nir_ssa_def *
+lower_fneg64(nir_builder *b, nir_ssa_def *src)
+{
+   nir_ssa_def *src_lo = nir_unpack_64_2x32_split_x(b, src);
+   nir_ssa_def *src_hi = nir_unpack_64_2x32_split_y(b, src);
+   src_hi = nir_ixor(b, src_hi,
+                        nir_ishl(b,
+                                 nir_imm_int(b, 1),
+                                 nir_imm_int(b, 31)));
+
+   /* Return the negate value of the src.
+    * If the src is not a number (NaN), return the src.
+    */
+   return nir_bcsel(b, is_nan(b, src),
+                       src,
+                       nir_pack_64_2x32_split(b, src_lo, src_hi));
+}
+
 static bool
 lower_doubles_instr(nir_alu_instr *instr, nir_lower_doubles_options options)
 {
@@ -524,6 +560,11 @@ lower_doubles_instr(nir_alu_instr *instr, nir_lower_doubles_options options)
          return false;
       break;
 
+   case nir_op_fneg:
+      if (!(options & nir_lower_dneg))
+         return false;
+      break;
+
    default:
       return false;
    }
@@ -574,6 +615,10 @@ lower_doubles_instr(nir_alu_instr *instr, nir_lower_doubles_options options)
       result = lower_fabs64(&bld, src);
       break;
 
+   case nir_op_fneg:
+      result = lower_fneg64(&bld, src);
+      break;
+
    default:
       unreachable("unhandled opcode");
    }
diff --git a/src/intel/compiler/brw_nir.c b/src/intel/compiler/brw_nir.c
index 8e41a6eaea..bf6935b1c2 100644
--- a/src/intel/compiler/brw_nir.c
+++ b/src/intel/compiler/brw_nir.c
@@ -510,7 +510,8 @@ nir_optimize(nir_shader *nir, const struct brw_compiler *compiler,
                              nir_lower_dfract |
                              nir_lower_dround_even |
                              nir_lower_dmod |
-                             nir_lower_dabs);
+                             nir_lower_dabs |
+                             nir_lower_dneg);
       OPT(nir_lower_64bit_pack);
    } while (progress);
 
-- 
2.11.0



More information about the mesa-dev mailing list