summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir
diff options
context:
space:
mode:
authorSagar Ghuge <[email protected]>2019-07-22 16:30:56 -0700
committerSagar Ghuge <[email protected]>2019-07-26 11:19:23 -0700
commitd5992ab134f6d3d8d8a885be50fe2f696fe0354e (patch)
treefaf3569f101fe1c121843a79734f2d247e85639f /src/compiler/nir
parentf8c71d7632914c3ce27f7e71ca8f28a6fb30001d (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.c48
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));