summaryrefslogtreecommitdiff
path: root/src/compiler/nir/nir_lower_idiv.c
diff options
context:
space:
mode:
authorSagar Ghuge <sagar.ghuge@intel.com>2019-07-22 16:30:56 -0700
committerSagar Ghuge <sagar.ghuge@intel.com>2019-07-26 11:19:23 -0700
commitd5992ab134f6d3d8d8a885be50fe2f696fe0354e (patch)
treefaf3569f101fe1c121843a79734f2d247e85639f /src/compiler/nir/nir_lower_idiv.c
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 <sagar.ghuge@intel.com> Reviewed-by: Matt Turner <mattst88@gmail.com>
Diffstat (limited to 'src/compiler/nir/nir_lower_idiv.c')
-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));