nir: Optimize umod lowering
authorSagar Ghuge <sagar.ghuge@intel.com>
Mon, 22 Jul 2019 23:30:56 +0000 (16:30 -0700)
committerSagar Ghuge <sagar.ghuge@intel.com>
Fri, 26 Jul 2019 18:19:23 +0000 (11:19 -0700)
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>
src/compiler/nir/nir_lower_idiv.c

index 96e9412c80ee5994640054929140bf280d898dc1..c59a3eb8b3d8ed89465b9716c34ba6c75a7cdee5 100644 (file)
@@ -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));