glsl: Transform pow(x, 4) into (x*x)*(x*x).
authorMatt Turner <mattst88@gmail.com>
Tue, 17 Mar 2015 04:33:31 +0000 (21:33 -0700)
committerMatt Turner <mattst88@gmail.com>
Fri, 24 Apr 2015 18:39:01 +0000 (11:39 -0700)
Reviewed-by: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/glsl/opt_algebraic.cpp

index 3d2f2ca0bab4f28a34223bc6edded3412480549a..fa5db70f2dd3b3ae6eed13adebd9b03a4c571439 100644 (file)
@@ -98,6 +98,12 @@ is_vec_two(ir_constant *ir)
    return (ir == NULL) ? false : ir->is_value(2.0, 2);
 }
 
+static inline bool
+is_vec_four(ir_constant *ir)
+{
+   return (ir == NULL) ? false : ir->is_value(4.0, 4);
+}
+
 static inline bool
 is_vec_negative_one(ir_constant *ir)
 {
@@ -774,6 +780,20 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
          return mul(x, x);
       }
 
+      if (is_vec_four(op_const[1])) {
+         ir_variable *x = new(ir) ir_variable(ir->operands[1]->type, "x",
+                                              ir_var_temporary);
+         base_ir->insert_before(x);
+         base_ir->insert_before(assign(x, ir->operands[0]));
+
+         ir_variable *squared = new(ir) ir_variable(ir->operands[1]->type,
+                                                    "squared",
+                                                    ir_var_temporary);
+         base_ir->insert_before(squared);
+         base_ir->insert_before(assign(squared, mul(x, x)));
+         return mul(squared, squared);
+      }
+
       break;
 
    case ir_binop_min: