tree-vectorizer.h (NUM_PATTERNS): Increase.
authorRichard Guenther <rguenther@suse.de>
Tue, 21 Nov 2006 14:29:53 +0000 (14:29 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 21 Nov 2006 14:29:53 +0000 (14:29 +0000)
2006-11-21  Richard Guenther  <rguenther@suse.de>

* tree-vectorizer.h (NUM_PATTERNS): Increase.
* tree-vect-patterns.c (vect_vect_recog_func_ptrs): Add
vect_recog_pow_pattern.
(vect_recog_pow_pattern): New function.

* gcc.dg/vect/vect-pow-1.c: New testcase.
* gcc.dg/vect/vect-pow-2.c: Likewise.

From-SVN: r119056

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/vect-pow-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-pow-2.c [new file with mode: 0644]
gcc/tree-vect-patterns.c
gcc/tree-vectorizer.h

index 99b91c0..fb4844a 100644 (file)
@@ -1,3 +1,10 @@
+2006-11-21  Richard Guenther  <rguenther@suse.de>
+
+       * tree-vectorizer.h (NUM_PATTERNS): Increase.
+       * tree-vect-patterns.c (vect_vect_recog_func_ptrs): Add
+       vect_recog_pow_pattern.
+       (vect_recog_pow_pattern): New function.
+
 2006-11-21  Bernd Schmidt  <bernd.schmidt@analog.com>
 
        * config/bfin/bfin.opt (mstack-check-l1): New.
index d0f9bc0..b6d5d4a 100644 (file)
@@ -1,3 +1,8 @@
+2006-11-21  Richard Guenther  <rguenther@suse.de>
+
+       * gcc.dg/vect/vect-pow-1.c: New testcase.
+       * gcc.dg/vect/vect-pow-2.c: Likewise.
+
 2006-11-21  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/29570
diff --git a/gcc/testsuite/gcc.dg/vect/vect-pow-1.c b/gcc/testsuite/gcc.dg/vect/vect-pow-1.c
new file mode 100644 (file)
index 0000000..2c29cba
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math -fdump-tree-vect-details" } */
+
+double x[256];
+
+void foo(void)
+{
+  int i;
+  for (i=0; i<256; ++i)
+    x[i] = x[i] * x[i];
+}
+
+/* { dg-final { scan-tree-dump "pattern recognized" "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-pow-2.c b/gcc/testsuite/gcc.dg/vect/vect-pow-2.c
new file mode 100644 (file)
index 0000000..dc3e7c0
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-math-errno -fdump-tree-vect-details" } */
+
+double x[256];
+
+void foo(void)
+{
+  int i;
+  for (i=0; i<256; ++i)
+    x[i] = __builtin_pow (x[i], 0.5);
+}
+
+/* { dg-final { scan-tree-dump "pattern recognized" "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
index 67ab90f..3e40fc7 100644 (file)
@@ -50,10 +50,12 @@ static bool widened_name_p (tree, tree, tree *, tree *);
 static tree vect_recog_widen_sum_pattern (tree, tree *, tree *);
 static tree vect_recog_widen_mult_pattern (tree, tree *, tree *);
 static tree vect_recog_dot_prod_pattern (tree, tree *, tree *);
+static tree vect_recog_pow_pattern (tree, tree *, tree *);
 static vect_recog_func_ptr vect_vect_recog_func_ptrs[NUM_PATTERNS] = {
        vect_recog_widen_mult_pattern,
        vect_recog_widen_sum_pattern,
-       vect_recog_dot_prod_pattern};
+       vect_recog_dot_prod_pattern,
+       vect_recog_pow_pattern};
 
 
 /* Function widened_name_p
@@ -400,6 +402,93 @@ vect_recog_widen_mult_pattern (tree last_stmt,
 }
 
 
+/* Function vect_recog_pow_pattern
+
+   Try to find the following pattern:
+
+     x = POW (y, N);
+
+   with POW being one of pow, powf, powi, powif and N being
+   either 2 or 0.5.
+
+   Input:
+
+   * LAST_STMT: A stmt from which the pattern search begins.
+
+   Output:
+
+   * TYPE_IN: The type of the input arguments to the pattern.
+
+   * TYPE_OUT: The type of the output of this pattern.
+
+   * Return value: A new stmt that will be used to replace the sequence of
+   stmts that constitute the pattern. In this case it will be:
+        x * x
+   or
+       sqrt (x)
+*/
+
+static tree
+vect_recog_pow_pattern (tree last_stmt, tree *type_in, tree *type_out)
+{
+  tree expr;
+  tree type;
+  tree fn, arglist, base, exp;
+
+  if (TREE_CODE (last_stmt) != MODIFY_EXPR)
+    return NULL;
+
+  expr = TREE_OPERAND (last_stmt, 1);
+  type = TREE_TYPE (expr);
+
+  if (TREE_CODE (expr) != CALL_EXPR)
+    return NULL_TREE;
+
+  fn = get_callee_fndecl (expr);
+  arglist = TREE_OPERAND (expr, 1);
+  switch (DECL_FUNCTION_CODE (fn))
+    {
+    case BUILT_IN_POWIF:
+    case BUILT_IN_POWI:
+    case BUILT_IN_POWF:
+    case BUILT_IN_POW:
+      base = TREE_VALUE (arglist);
+      exp = TREE_VALUE (TREE_CHAIN (arglist));
+      if (TREE_CODE (exp) != REAL_CST
+         && TREE_CODE (exp) != INTEGER_CST)
+        return NULL_TREE;
+      break;
+
+    default:;
+      return NULL_TREE;
+    }
+
+  /* We now have a pow or powi builtin function call with a constant
+     exponent.  */
+
+  *type_in = get_vectype_for_scalar_type (TREE_TYPE (base));
+  *type_out = NULL_TREE;
+
+  /* Catch squaring.  */
+  if ((host_integerp (exp, 0)
+       && tree_low_cst (exp, 0) == 2)
+      || (TREE_CODE (exp) == REAL_CST
+          && REAL_VALUES_EQUAL (TREE_REAL_CST (exp), dconst2)))
+    return build2 (MULT_EXPR, TREE_TYPE (base), base, base);
+
+  /* Catch square root.  */
+  if (TREE_CODE (exp) == REAL_CST
+      && REAL_VALUES_EQUAL (TREE_REAL_CST (exp), dconsthalf))
+    {
+      tree newfn = mathfn_built_in (TREE_TYPE (base), BUILT_IN_SQRT);
+      tree newarglist = build_tree_list (NULL_TREE, base);
+      return build_function_call_expr (newfn, newarglist);
+    }
+
+  return NULL_TREE;
+}
+
+
 /* Function vect_recog_widen_sum_pattern
 
    Try to find the following pattern:
index 55e1377..8341ad0 100644 (file)
@@ -357,7 +357,7 @@ extern loop_vec_info vect_analyze_loop (struct loop *);
    Additional pattern recognition functions can (and will) be added
    in the future.  */
 typedef tree (* vect_recog_func_ptr) (tree, tree *, tree *);
-#define NUM_PATTERNS 3
+#define NUM_PATTERNS 4
 void vect_pattern_recog (loop_vec_info);