diff options
author | Sagar Ghuge <[email protected]> | 2019-07-22 16:30:56 -0700 |
---|---|---|
committer | Sagar Ghuge <[email protected]> | 2019-07-26 11:19:23 -0700 |
commit | d5992ab134f6d3d8d8a885be50fe2f696fe0354e (patch) | |
tree | faf3569f101fe1c121843a79734f2d247e85639f /src/compiler/nir | |
parent | f8c71d7632914c3ce27f7e71ca8f28a6fb30001d (diff) |
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 <[email protected]>
Reviewed-by: Matt Turner <[email protected]>
Diffstat (limited to 'src/compiler/nir')
-rw-r--r-- | src/compiler/nir/nir_lower_idiv.c | 48 |
1 files 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)); |