From d5992ab134f6d3d8d8a885be50fe2f696fe0354e Mon Sep 17 00:00:00 2001 From: Sagar Ghuge Date: Mon, 22 Jul 2019 16:30:56 -0700 Subject: [PATCH] nir: Optimize umod lowering We don't have calculate final quotient in order to calculate unsigned modulo result. Once we are done with error correction we have partial result which can be used to find out modulo operation result Signed-off-by: Sagar Ghuge Reviewed-by: Matt Turner --- src/compiler/nir/nir_lower_idiv.c | 48 +++++++++++++++---------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/compiler/nir/nir_lower_idiv.c b/src/compiler/nir/nir_lower_idiv.c index 96e9412c80e..c59a3eb8b3d 100644 --- a/src/compiler/nir/nir_lower_idiv.c +++ b/src/compiler/nir/nir_lower_idiv.c @@ -39,7 +39,7 @@ static bool convert_instr(nir_builder *bld, nir_alu_instr *alu) { - nir_ssa_def *numer, *denom, *af, *bf, *a, *b, *q, *r; + nir_ssa_def *numer, *denom, *af, *bf, *a, *b, *q, *r, *rt; nir_op op = alu->op; bool is_signed; @@ -97,35 +97,33 @@ convert_instr(nir_builder *bld, nir_alu_instr *alu) /* correction: if modulus >= divisor, add 1 */ r = nir_imul(bld, q, b); r = nir_isub(bld, a, r); + rt = nir_uge(bld, r, b); - r = nir_uge(bld, r, b); - r = nir_b2i32(bld, r); - - q = nir_iadd(bld, q, r); - if (is_signed) { - /* fix the sign: */ - r = nir_ixor(bld, numer, denom); - r = nir_ilt(bld, r, nir_imm_int(bld, 0)); - b = nir_ineg(bld, q); - q = nir_bcsel(bld, r, b, q); - - if (op == nir_op_imod || op == nir_op_irem) { - q = nir_imul(bld, q, denom); - q = nir_isub(bld, numer, q); - if (op == nir_op_imod) { - q = nir_bcsel(bld, nir_ieq(bld, q, nir_imm_int(bld, 0)), - nir_imm_int(bld, 0), - nir_bcsel(bld, r, nir_iadd(bld, q, denom), q)); + if (op == nir_op_umod) { + q = nir_bcsel(bld, rt, nir_isub(bld, r, b), r); + } else { + r = nir_b2i32(bld, rt); + + q = nir_iadd(bld, q, r); + if (is_signed) { + /* fix the sign: */ + r = nir_ixor(bld, numer, denom); + r = nir_ilt(bld, r, nir_imm_int(bld, 0)); + b = nir_ineg(bld, q); + q = nir_bcsel(bld, r, b, q); + + if (op == nir_op_imod || op == nir_op_irem) { + q = nir_imul(bld, q, denom); + q = nir_isub(bld, numer, q); + if (op == nir_op_imod) { + q = nir_bcsel(bld, nir_ieq(bld, q, nir_imm_int(bld, 0)), + nir_imm_int(bld, 0), + nir_bcsel(bld, r, nir_iadd(bld, q, denom), q)); + } } } } - if (op == nir_op_umod) { - /* division result in q */ - r = nir_imul(bld, q, b); - q = nir_isub(bld, a, r); - } - assert(alu->dest.dest.is_ssa); nir_ssa_def_rewrite_uses(&alu->dest.dest.ssa, nir_src_for_ssa(q)); -- 2.30.2