[Mesa-dev] [PATCH 12/23] glsl: Rewrite (-abs(x) >= 0) and (-abs(x) >= abs(x)) as (x == 0)

Ian Romanick idr at freedesktop.org
Fri Mar 20 13:58:12 PDT 2015


From: Ian Romanick <ian.d.romanick at intel.com>

v2: Use existing op_expr and op_const data.

v3: Add support for (-abs(x) >= abs(x)).

Shader-db results:

GM45 (0x2A42):
total instructions in shared programs: 3545720 -> 3545713 (-0.00%)
instructions in affected programs:     3911 -> 3904 (-0.18%)
helped:                                7

Iron Lake (0x0046):
total instructions in shared programs: 4976076 -> 4976069 (-0.00%)
instructions in affected programs:     3874 -> 3867 (-0.18%)
helped:                                7

Sandy Bridge (0x0116):
total instructions in shared programs: 6803596 -> 6803294 (-0.00%)
instructions in affected programs:     59645 -> 59343 (-0.51%)
helped:                                136

Sandy Bridge (0x0116) NIR:
total instructions in shared programs: 6817191 -> 6817199 (0.00%)
instructions in affected programs:     4884 -> 4892 (0.16%)
HURT:                                  8

Ivy Bridge (0x0166):
total instructions in shared programs: 6278560 -> 6278324 (-0.00%)
instructions in affected programs:     36542 -> 36306 (-0.65%)
helped:                                105

Ivy Bridge (0x0166) NIR:
total instructions in shared programs: 6324626 -> 6324632 (0.00%)
instructions in affected programs:     3778 -> 3784 (0.16%)
helped:                                1
HURT:                                  7

Haswell (0x0426):
total instructions in shared programs: 5764021 -> 5763785 (-0.00%)
instructions in affected programs:     34555 -> 34319 (-0.68%)
helped:                                105

Haswell (0x0426) NIR:
total instructions in shared programs: 5800358 -> 5800362 (0.00%)
instructions in affected programs:     2038 -> 2042 (0.20%)
HURT:                                  4

Broadwell (0x162E):
total instructions in shared programs: 6812047 -> 6811811 (-0.00%)
instructions in affected programs:     35213 -> 34977 (-0.67%)
helped:                                107

Broadwell (0x162E) NIR:
total instructions in shared programs: 7015422 -> 7015134 (-0.00%)
instructions in affected programs:     22293 -> 22005 (-1.29%)
helped:                                81
HURT:                                  4

Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
---
 src/glsl/opt_algebraic.cpp | 43 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/src/glsl/opt_algebraic.cpp b/src/glsl/opt_algebraic.cpp
index b14f82d..228bb6c 100644
--- a/src/glsl/opt_algebraic.cpp
+++ b/src/glsl/opt_algebraic.cpp
@@ -683,10 +683,51 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
       }
       break;
 
+   case ir_binop_gequal: {
+      /* Thanks to limitations of DX9 hardware, the HLSL compiler generates
+       * expressions like (-abs(x) >= 0) instead of (x == 0).  If a backend
+       * needs that, it can generate it from the actual expression.  This
+       * saves memory and makes it easier for other optimization passes to see
+       * what's happening.
+       */
+      if (op_expr[0] != NULL && op_expr[0]->operation == ir_unop_neg &&
+          op_const[1] != NULL && op_const[1]->is_zero()) {
+         ir_expression *const subexpr =
+            op_expr[0]->operands[0]->as_expression();
+
+         if (subexpr != NULL && subexpr->operation == ir_unop_abs) {
+            return new(mem_ctx) ir_expression(ir_binop_equal,
+                                              subexpr->operands[0],
+                                              op_const[1]);
+         }
+      }
+
+      /* In some cases the HLSL compiler generates expressions like (-abs(x)
+       * >= abs(x)) instead of (x == 0).
+       *
+       * This form seems most common in vertex shaders.
+       */
+      if (op_expr[0] != NULL && op_expr[0]->operation == ir_unop_neg &&
+          op_expr[1] != NULL && op_expr[1]->operation == ir_unop_abs) {
+         ir_expression *const subexpr =
+            op_expr[0]->operands[0]->as_expression();
+
+         if (subexpr != NULL && subexpr->operation == ir_unop_abs) {
+            ir_rvalue *const left_inner = subexpr->operands[0]->as_rvalue();
+            ir_rvalue *const right_inner = op_expr[1]->operands[0]->as_rvalue();
+
+            if (left_inner->equals(right_inner)) {
+               return new(mem_ctx) ir_expression(ir_binop_equal,
+                                                 left_inner,
+                                                 ir_constant::zero(mem_ctx, left_inner->type));
+            }
+         }
+      }
+   }
+      /* FALLTHROUGH */
    case ir_binop_less:
    case ir_binop_lequal:
    case ir_binop_greater:
-   case ir_binop_gequal:
    case ir_binop_equal:
    case ir_binop_nequal:
       for (int add_pos = 0; add_pos < 2; add_pos++) {
-- 
2.1.0



More information about the mesa-dev mailing list