From 789221dcfa5df3c88e28978c90ccfb9eafb30e10 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Tue, 29 Aug 2017 20:36:55 -0700 Subject: nir: Add a helper for getting binop identities Reviewed-by: Lionel Landwerlin Reviewed-by: Iago Toral Quiroga --- src/compiler/nir/nir.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/compiler/nir/nir.h | 2 ++ 2 files changed, 70 insertions(+) (limited to 'src/compiler/nir') diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index f5fd1dc586b..a97b119bf72 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -27,7 +27,9 @@ #include "nir.h" #include "nir_control_flow_private.h" +#include "util/half_float.h" #include +#include 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) { diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 65c5343de4d..5b28c727c80 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -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 * @{ -- cgit v1.2.3