diff options
author | Alyssa Rosenzweig <alyssa@collabora.com> | 2022-08-01 18:56:01 -0400 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2022-08-03 14:24:38 +0000 |
commit | a4a15f500ce43b18b2ee99b740b7f2575abcfa4e (patch) | |
tree | a2009190a8a1e1753f858e623557e0508e9b0ee6 | |
parent | e13c9d2168dfb216a4920e84d89dbcc08de3dfe0 (diff) | |
download | mesa-a4a15f500ce43b18b2ee99b740b7f2575abcfa4e.tar.gz |
nir/lower_idiv: Be less creative about signs
I'm sorry to whoever wrote this, but
(x - (int) (x < 0)) ^ -((int) (x < 0))
is not an acceptable way to write iabs.
Shader-db results on Intel Tiger Lake with lower_idiv enabled:
total instructions in shared programs: 21122548 -> 21122570 (<.01%)
instructions in affected programs: 2369 -> 2391 (0.93%)
helped: 2
HURT: 8
total cycles in shared programs: 791609360 -> 791608062 (<.01%)
cycles in affected programs: 114106 -> 112808 (-1.14%)
helped: 9
HURT: 1
If we make the Intel back-end less stupid, we get to 9/1 helped/HURT for
instructions as well but that's for a different MR.
Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17845>
-rw-r--r-- | src/compiler/nir/nir_lower_idiv.c | 14 |
1 files changed, 4 insertions, 10 deletions
diff --git a/src/compiler/nir/nir_lower_idiv.c b/src/compiler/nir/nir_lower_idiv.c index 1f1c940e22f..ebbdaac1bcd 100644 --- a/src/compiler/nir/nir_lower_idiv.c +++ b/src/compiler/nir/nir_lower_idiv.c @@ -162,23 +162,17 @@ emit_idiv(nir_builder *bld, nir_ssa_def *numer, nir_ssa_def *denom, nir_op op) { nir_ssa_def *lh_sign = nir_ilt(bld, numer, nir_imm_int(bld, 0)); nir_ssa_def *rh_sign = nir_ilt(bld, denom, nir_imm_int(bld, 0)); - lh_sign = nir_bcsel(bld, lh_sign, nir_imm_int(bld, -1), nir_imm_int(bld, 0)); - rh_sign = nir_bcsel(bld, rh_sign, nir_imm_int(bld, -1), nir_imm_int(bld, 0)); - nir_ssa_def *lhs = nir_iadd(bld, numer, lh_sign); - nir_ssa_def *rhs = nir_iadd(bld, denom, rh_sign); - lhs = nir_ixor(bld, lhs, lh_sign); - rhs = nir_ixor(bld, rhs, rh_sign); + nir_ssa_def *lhs = nir_iabs(bld, numer); + nir_ssa_def *rhs = nir_iabs(bld, denom); if (op == nir_op_idiv) { nir_ssa_def *d_sign = nir_ixor(bld, lh_sign, rh_sign); nir_ssa_def *res = emit_udiv(bld, lhs, rhs, false); - res = nir_ixor(bld, res, d_sign); - return nir_isub(bld, res, d_sign); + return nir_bcsel(bld, d_sign, nir_ineg(bld, res), res); } else { nir_ssa_def *res = emit_udiv(bld, lhs, rhs, true); - res = nir_ixor(bld, res, lh_sign); - res = nir_isub(bld, res, lh_sign); + res = nir_bcsel(bld, lh_sign, nir_ineg(bld, res), res); if (op == nir_op_imod) { nir_ssa_def *cond = nir_ieq_imm(bld, res, 0); cond = nir_ior(bld, nir_ieq(bld, lh_sign, rh_sign), cond); |