[Mesa-dev] [PATCH] glsl: Add ir_binop_mul to get_range

Thomas Helland thomashelland90 at gmail.com
Sun Jan 4 04:38:21 PST 2015


V2: Add some air for readability
    Use the new IS_CONSTANT macro
    Combine if-blocks for reduced code-duplication
    Split out into separate function for reuse later

V3: Fix flawed logic (Spotted by Bruno)
---
 src/glsl/opt_minmax.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/src/glsl/opt_minmax.cpp b/src/glsl/opt_minmax.cpp
index 4153a48..373ba26 100644
--- a/src/glsl/opt_minmax.cpp
+++ b/src/glsl/opt_minmax.cpp
@@ -300,6 +300,46 @@ resolv_add_range(minmax_range r0, minmax_range r1)
    return minmax_range(low, high);
 }
 
+/* Takes the range of the operands in a mul-operation as parameters
+ * and uses this to solve the range of the mul-operation itself.
+ */
+static minmax_range
+resolv_mul_range(minmax_range r0, minmax_range r1)
+{
+   ir_constant *low = NULL;
+   ir_constant *high = NULL;
+
+   // Both are positive, result is positive
+   if (IS_CONSTANT(r0.low, >=, 0.0f) && IS_CONSTANT(r1.low, >=, 0.0f)) {
+      low = mul(r0.low, r1.low)->constant_expression_value();
+      if (r0.high && r1.high)
+         high = mul(r0.high, r1.high)->constant_expression_value();
+   }
+
+   // Both are negative, result is positive
+   if (IS_CONSTANT(r0.high, <=, 0.0f) && IS_CONSTANT(r1.high, <=, 0.0f)) {
+      low = mul(r0.high, r1.high)->constant_expression_value();
+      if (r0.low && r1.low)
+         high = mul(r0.low, r1.low)->constant_expression_value();
+   }
+
+   // r0 pos and r1 neg,  result is negative
+   if (IS_CONSTANT(r0.low, >=, 0.0f) && IS_CONSTANT(r1.high, <=, 0.0f)) {
+      high = mul(r0.low, r1.high)->constant_expression_value();
+      if (r0.high && r1.low)
+         low = mul(r0.high, r1.low)->constant_expression_value();
+   }
+
+   // r0 neg and r1 pos, result is negative
+   if (IS_CONSTANT(r1.low, >=, 0.0f) && IS_CONSTANT(r0.high, <=, 0.0f)) {
+      high = mul(r1.low, r0.high)->constant_expression_value();
+      if (r1.high && r0.low)
+         low = mul(r1.high, r0.low)->constant_expression_value();
+   }
+
+   return minmax_range(low, high);
+}
+
 static minmax_range
 get_range(ir_rvalue *rval)
 {
@@ -389,6 +429,11 @@ get_range(ir_rvalue *rval)
          r1 = get_range(expr->operands[1]);
          return combine_range(r0, r1, expr->operation == ir_binop_min);
 
+      case ir_binop_mul:
+         r0 = get_range(expr->operands[0]);
+         r1 = get_range(expr->operands[1]);
+         return resolv_mul_range(r0, r1);
+
       default:
          break;
       }
-- 
2.2.1



More information about the mesa-dev mailing list