[Mesa-dev] [PATCH 05/22] glsl: Add sqrt, rsq, exp, exp2 to get_range

Thomas Helland thomashelland90 at gmail.com
Sat Jan 3 11:18:10 PST 2015


Also handle undefined behaviour for sqrt(x) where x < 0
and rsq(x) where x <= 0.

This gives us some reduction in instruction count on three
Dungeon Defenders shaders as they are doing: max(exp(x), 0)

v2: Change to use new IS_CONSTANT() macro
    Fix high unintenionally not being returned
    Add some air for readability
    Comment on the exploit of undefined behavior
    Constify mem_ctx
---
 src/glsl/opt_minmax.cpp | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/src/glsl/opt_minmax.cpp b/src/glsl/opt_minmax.cpp
index 56805c0..2faa3c3 100644
--- a/src/glsl/opt_minmax.cpp
+++ b/src/glsl/opt_minmax.cpp
@@ -274,9 +274,40 @@ get_range(ir_rvalue *rval)
    minmax_range r0;
    minmax_range r1;
 
+   void *const mem_ctx = ralloc_parent(rval);
+
+   ir_constant *low = NULL;
+   ir_constant *high = NULL;
+
    if (expr) {
       switch (expr->operation) {
 
+      case ir_unop_exp:
+      case ir_unop_exp2:
+      case ir_unop_sqrt:
+      case ir_unop_rsq:
+         r0 = get_range(expr->operands[0]);
+
+         /* The spec says sqrt is undefined if x < 0
+          * We can use this to set the range to whatever we want
+          */
+         if (expr->operation == ir_unop_sqrt &&
+             IS_CONSTANT(r0.high, <, 0.0f))
+            high = new(mem_ctx) ir_constant(0.0f);
+
+         /* The spec says rsq is undefined if x <= 0
+          * We can use this to set the range to whatever we want
+          */
+         if (expr->operation == ir_unop_rsq &&
+             IS_CONSTANT(r0.high, <=, 0.0f))
+            high = new(mem_ctx) ir_constant(0.0f);
+
+         /* TODO: If we know, i.e, the lower range of the operand
+          * we can calculate the lower range
+          */
+         low = new(mem_ctx) ir_constant(0.0f);
+         return minmax_range(low, high);
+
       case ir_binop_min:
       case ir_binop_max:
          r0 = get_range(expr->operands[0]);
-- 
2.2.1



More information about the mesa-dev mailing list