Signed-off-by: Elie Tournier <elie.tourn...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev