From a4a15f500ce43b18b2ee99b740b7f2575abcfa4e Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Mon, 1 Aug 2022 18:56:01 -0400 Subject: [PATCH] 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 Reviewed-by: Jason Ekstrand Reviewed-by: Ian Romanick Part-of: --- src/compiler/nir/nir_lower_idiv.c | 14 ++++---------- 1 file 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);