nir: Add a helper for getting binop identities
authorJason Ekstrand <jason.ekstrand@intel.com>
Wed, 30 Aug 2017 03:36:55 +0000 (20:36 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Wed, 7 Mar 2018 20:13:47 +0000 (12:13 -0800)
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
src/compiler/nir/nir.c
src/compiler/nir/nir.h

index f5fd1dc586b73edaa471bb7c8bcdc22d2db0bb20..a97b119bf72c7d85b34d999a697acd349aa470fa 100644 (file)
@@ -27,7 +27,9 @@
 
 #include "nir.h"
 #include "nir_control_flow_private.h"
+#include "util/half_float.h"
 #include <assert.h>
+#include <math.h>
 
 nir_shader *
 nir_shader_create(void *mem_ctx,
@@ -893,6 +895,72 @@ nir_deref_get_const_initializer_load(nir_shader *shader, nir_deref_var *deref)
    return load;
 }
 
+static nir_const_value
+const_value_float(double d, unsigned bit_size)
+{
+   nir_const_value v;
+   switch (bit_size) {
+   case 16: v.u16[0] = _mesa_float_to_half(d);  break;
+   case 32: v.f32[0] = d;                       break;
+   case 64: v.f64[0] = d;                       break;
+   default:
+      unreachable("Invalid bit size");
+   }
+   return v;
+}
+
+static nir_const_value
+const_value_int(int64_t i, unsigned bit_size)
+{
+   nir_const_value v;
+   switch (bit_size) {
+   case 8:  v.i8[0]  = i;  break;
+   case 16: v.i16[0] = i;  break;
+   case 32: v.i32[0] = i;  break;
+   case 64: v.i64[0] = i;  break;
+   default:
+      unreachable("Invalid bit size");
+   }
+   return v;
+}
+
+nir_const_value
+nir_alu_binop_identity(nir_op binop, unsigned bit_size)
+{
+   const int64_t max_int = (1ull << (bit_size - 1)) - 1;
+   const int64_t min_int = -max_int - 1;
+   switch (binop) {
+   case nir_op_iadd:
+      return const_value_int(0, bit_size);
+   case nir_op_fadd:
+      return const_value_float(0, bit_size);
+   case nir_op_imul:
+      return const_value_int(1, bit_size);
+   case nir_op_fmul:
+      return const_value_float(1, bit_size);
+   case nir_op_imin:
+      return const_value_int(max_int, bit_size);
+   case nir_op_umin:
+      return const_value_int(~0ull, bit_size);
+   case nir_op_fmin:
+      return const_value_float(INFINITY, bit_size);
+   case nir_op_imax:
+      return const_value_int(min_int, bit_size);
+   case nir_op_umax:
+      return const_value_int(0, bit_size);
+   case nir_op_fmax:
+      return const_value_float(-INFINITY, bit_size);
+   case nir_op_iand:
+      return const_value_int(~0ull, bit_size);
+   case nir_op_ior:
+      return const_value_int(0, bit_size);
+   case nir_op_ixor:
+      return const_value_int(0, bit_size);
+   default:
+      unreachable("Invalid reduction operation");
+   }
+}
+
 nir_function_impl *
 nir_cf_node_get_function(nir_cf_node *node)
 {
index 65c5343de4d799b981cac4f9a926ad53586bef9d..5b28c727c80386fbc56e8bf4d33d985987f9b937 100644 (file)
@@ -2064,6 +2064,8 @@ bool nir_deref_foreach_leaf(nir_deref_var *deref,
 nir_load_const_instr *
 nir_deref_get_const_initializer_load(nir_shader *shader, nir_deref_var *deref);
 
+nir_const_value nir_alu_binop_identity(nir_op binop, unsigned bit_size);
+
 /**
  * NIR Cursors and Instruction Insertion API
  * @{