[Mesa-dev] [PATCH 1/2] glsl: add lowering passes for carry/borrow

Ilia Mirkin imirkin at alum.mit.edu
Mon Apr 28 20:17:29 PDT 2014


Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
---

It didn't seem useful to add 2 separate lowering flags. I can't really imagine
wanting to lower one but not the other.

Also, this is my first foray into the GLSL compiler, so please look out for
noob mistakes. This did pass piglit tests though.

 src/glsl/ir_optimization.h      |  1 +
 src/glsl/lower_instructions.cpp | 55 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+)

diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
index 40bb613..5f0267d 100644
--- a/src/glsl/ir_optimization.h
+++ b/src/glsl/ir_optimization.h
@@ -38,6 +38,7 @@
 #define INT_DIV_TO_MUL_RCP 0x40
 #define BITFIELD_INSERT_TO_BFM_BFI 0x80
 #define LDEXP_TO_ARITH     0x100
+#define CARRY_TO_ARITH     0x200
 
 /**
  * \see class lower_packing_builtins_visitor
diff --git a/src/glsl/lower_instructions.cpp b/src/glsl/lower_instructions.cpp
index 49316d0..ecbda96 100644
--- a/src/glsl/lower_instructions.cpp
+++ b/src/glsl/lower_instructions.cpp
@@ -39,6 +39,7 @@
  * - MOD_TO_FRACT
  * - LDEXP_TO_ARITH
  * - BITFIELD_INSERT_TO_BFM_BFI
+ * - CARRY_TO_ARITH
  *
  * SUB_TO_ADD_NEG:
  * ---------------
@@ -91,6 +92,10 @@
  * Breaks ir_quadop_bitfield_insert into ir_binop_bfm (bitfield mask) and
  * ir_triop_bfi (bitfield insert).
  *
+ * CARRY_TO_ARITH:
+ * ---------------
+ * Converts ir_carry and ir_borrow into (x + y) > x and (x < y)
+ *
  * Many GPUs implement the bitfieldInsert() built-in from ARB_gpu_shader_5
  * with a pair of instructions.
  *
@@ -127,6 +132,8 @@ private:
    void log_to_log2(ir_expression *);
    void bitfield_insert_to_bfm_bfi(ir_expression *);
    void ldexp_to_arith(ir_expression *);
+   void carry_to_arith(ir_expression *);
+   void borrow_to_arith(ir_expression *);
 };
 
 } /* anonymous namespace */
@@ -436,6 +443,44 @@ lower_instructions_visitor::ldexp_to_arith(ir_expression *ir)
    this->progress = true;
 }
 
+void
+lower_instructions_visitor::carry_to_arith(ir_expression *ir)
+{
+   /* Translates
+    *   ir_binop_carry x y
+    * into
+    *   sum = ir_binop_add x y
+    *   bcarry = ir_binop_less sum x
+    *   carry = ir_unop_b2i bcarry
+    */
+
+   ir_rvalue *x_clone = ir->operands[0]->clone(ir, NULL);
+   ir->operation = ir_unop_i2u;
+   ir->operands[0] = b2i(less(
+         add(ir->operands[0], ir->operands[1]),
+         x_clone));
+   ir->operands[1] = NULL;
+
+   this->progress = true;
+}
+
+void
+lower_instructions_visitor::borrow_to_arith(ir_expression *ir)
+{
+   /* Translates
+    *   ir_binop_borrow x y
+    * into
+    *   bcarry = ir_binop_less x y
+    *   carry = ir_unop_b2i bcarry
+    */
+
+   ir->operation = ir_unop_i2u;
+   ir->operands[0] = b2i(less(ir->operands[0], ir->operands[1]));
+   ir->operands[1] = NULL;
+
+   this->progress = true;
+}
+
 ir_visitor_status
 lower_instructions_visitor::visit_leave(ir_expression *ir)
 {
@@ -482,6 +527,16 @@ lower_instructions_visitor::visit_leave(ir_expression *ir)
          ldexp_to_arith(ir);
       break;
 
+   case ir_binop_carry:
+      if (lowering(CARRY_TO_ARITH))
+         carry_to_arith(ir);
+      break;
+
+   case ir_binop_borrow:
+      if (lowering(CARRY_TO_ARITH))
+         borrow_to_arith(ir);
+      break;
+
    default:
       return visit_continue;
    }
-- 
1.8.3.2



More information about the mesa-dev mailing list