nir: Add lowering for nir_op_irem and nir_op_imod
authorSagar Ghuge <sagar.ghuge@intel.com>
Tue, 16 Apr 2019 06:06:23 +0000 (23:06 -0700)
committerSagar Ghuge <sagar.ghuge@intel.com>
Wed, 24 Jul 2019 17:33:09 +0000 (10:33 -0700)
Tested on Gen > 9.

v2: 1) Fix lowering
    2) Keep a consistent i/u order (Matt Turner)

Signed-off-by: Sagar Ghuge <sagar.ghuge@intel.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
src/compiler/nir/nir_lower_idiv.c

index 4e7e2408ae8cc3b1dde02654adaaade5bd43a963..96e9412c80ee5994640054929140bf280d898dc1 100644 (file)
@@ -45,10 +45,14 @@ convert_instr(nir_builder *bld, nir_alu_instr *alu)
 
    if ((op != nir_op_idiv) &&
        (op != nir_op_udiv) &&
-       (op != nir_op_umod))
+       (op != nir_op_imod) &&
+       (op != nir_op_umod) &&
+       (op != nir_op_irem))
       return false;
 
-   is_signed = (op == nir_op_idiv);
+   is_signed = (op == nir_op_idiv ||
+                op == nir_op_imod ||
+                op == nir_op_irem);
 
    bld->cursor = nir_before_instr(&alu->instr);
 
@@ -104,6 +108,16 @@ convert_instr(nir_builder *bld, nir_alu_instr *alu)
       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) {