[Mesa-dev] [RFC 2/5] nir: Add unordered comparisons and ordered fne

Jason Ekstrand jason at jlekstrand.net
Thu Nov 22 18:46:45 UTC 2018


---
 src/compiler/nir/nir.h                |  8 ++++++++
 src/compiler/nir/nir_loop_analyze.c   | 12 ++++++++----
 src/compiler/nir/nir_opcodes.py       |  4 ++++
 src/compiler/nir/nir_opt_algebraic.py |  5 +++++
 4 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 4271f237235..20ff9a87297 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -1561,6 +1561,10 @@ nir_alu_instr_is_comparison(const nir_alu_instr *instr)
    case nir_op_flt:
    case nir_op_fge:
    case nir_op_feq:
+   case nir_op_fne:
+   case nir_op_fltu:
+   case nir_op_fgeu:
+   case nir_op_fequ:
    case nir_op_fneu:
    case nir_op_ilt:
    case nir_op_ult:
@@ -2132,6 +2136,10 @@ typedef struct nir_shader_compiler_options {
 
    bool lower_ldexp;
 
+   bool lower_fltu;
+   bool lower_fgeu;
+   bool lower_fne_to_fequ;
+
    bool lower_pack_half_2x16;
    bool lower_pack_unorm_2x16;
    bool lower_pack_snorm_2x16;
diff --git a/src/compiler/nir/nir_loop_analyze.c b/src/compiler/nir/nir_loop_analyze.c
index d73314a8a44..d6cba541a10 100644
--- a/src/compiler/nir/nir_loop_analyze.c
+++ b/src/compiler/nir/nir_loop_analyze.c
@@ -376,6 +376,10 @@ get_iteration(nir_op cond_op, nir_const_value *initial, nir_const_value *step,
    case nir_op_fge:
    case nir_op_flt:
    case nir_op_feq:
+   case nir_op_fne:
+   case nir_op_fgeu:
+   case nir_op_fltu:
+   case nir_op_fequ:
    case nir_op_fneu: {
       float initial_val = initial->f32[0];
       float span = limit->f32[0] - initial_val;
@@ -547,10 +551,10 @@ find_trip_count(loop_info_state *state)
       bool limit_rhs = true;
 
       switch (alu->op) {
-      case nir_op_fge:      case nir_op_ige:      case nir_op_uge:
-      case nir_op_flt:      case nir_op_ilt:      case nir_op_ult:
-      case nir_op_feq:      case nir_op_ieq:
-      case nir_op_fneu:     case nir_op_ine:
+      case nir_op_fgeu: case nir_op_fge:  case nir_op_ige:  case nir_op_uge:
+      case nir_op_fltu: case nir_op_flt:  case nir_op_ilt:  case nir_op_ult:
+      case nir_op_fequ: case nir_op_feq:  case nir_op_ieq:
+      case nir_op_fneu: case nir_op_fne:  case nir_op_ine:
 
          /* We assume that the limit is the "right" operand */
          basic_ind = get_loop_var(alu->src[0].src.ssa, state);
diff --git a/src/compiler/nir/nir_opcodes.py b/src/compiler/nir/nir_opcodes.py
index 2375309aca6..032168bae49 100644
--- a/src/compiler/nir/nir_opcodes.py
+++ b/src/compiler/nir/nir_opcodes.py
@@ -491,6 +491,10 @@ binop("frem", tfloat, "", "src0 - src1 * truncf(src0 / src1)")
 binop_compare("flt", tfloat, "", "src0 < src1")
 binop_compare("fge", tfloat, "", "src0 >= src1")
 binop_compare("feq", tfloat, commutative, "src0 == src1")
+binop_compare("fne", tfloat, commutative, "!isnan(src0) && !isnan(src1) && src0 == src1")
+binop_compare("fltu", tfloat, "", "!(src0 >= src1)")
+binop_compare("fgeu", tfloat, "", "!(src0 < src1)")
+binop_compare("fequ", tfloat, commutative, "isnan(src0) || isnan(src1) || src0 == src1")
 binop_compare("fneu", tfloat, commutative, "src0 != src1")
 binop_compare("ilt", tint, "", "src0 < src1")
 binop_compare("ige", tint, "", "src0 >= src1")
diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py
index 131d2721934..64327708a66 100644
--- a/src/compiler/nir/nir_opt_algebraic.py
+++ b/src/compiler/nir/nir_opt_algebraic.py
@@ -164,6 +164,11 @@ optimizations = [
    (('inot', ('ieq', a, b)), ('ine', a, b)),
    (('inot', ('ine', a, b)), ('ieq', a, b)),
 
+   # Comparison lowering
+   (('fltu', a, b), ('inot', ('fge', a, b)), 'options->lower_fltu'),
+   (('fgeu', a, b), ('inot', ('flt', a, b)), 'options->lower_fgeu'),
+   (('fne', a, b), ('inot', ('fequ', a, b)), 'options->lower_fne_to_fequ'),
+
    # 0.0 >= b2f(a)
    # b2f(a) <= 0.0
    # b2f(a) == 0.0 because b2f(a) can only be 0 or 1
-- 
2.19.1



More information about the mesa-dev mailing list