Move more cproj simplifications to match.pd
authorRichard Sandiford <richard.sandiford@arm.com>
Thu, 22 Oct 2015 08:27:04 +0000 (08:27 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 22 Oct 2015 08:27:04 +0000 (08:27 +0000)
Also make build_complex_cproj available globally and use
it for the existing match.pd rules.

Tested on x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi.

gcc/
* builtins.c (fold_builtin_cproj): Delete.
(fold_builtin_1): Handle constant arguments here.
(build_complex_cproj): Move and rename to...
* tree.c: (build_complex_inf): ...this.
* tree.h (build_complex_inf): Declare.
* match.pd: Fold cproj(x)->x if x has no infinity.
Use build_complex_inf for existing cproj rules.

From-SVN: r229164

gcc/ChangeLog
gcc/builtins.c
gcc/match.pd
gcc/tree.c
gcc/tree.h

index 7385acd..bd5aef5 100644 (file)
@@ -1,3 +1,13 @@
+2015-10-22  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * builtins.c (fold_builtin_cproj): Delete.
+       (fold_builtin_1): Handle constant arguments here.
+       (build_complex_cproj): Move and rename to...
+       * tree.c: (build_complex_inf): ...this.
+       * tree.h (build_complex_inf): Declare.
+       * match.pd: Fold cproj(x)->x if x has no infinity.
+       Use build_complex_inf for existing cproj rules.
+
 2015-10-22  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
 
        PR target/68015
index 2318b28..eec4b88 100644 (file)
@@ -7538,50 +7538,6 @@ fold_fixed_mathfn (location_t loc, tree fndecl, tree arg)
   return NULL_TREE;
 }
 
-/* Build a complex (inf +- 0i) for the result of cproj.  TYPE is the
-   complex tree type of the result.  If NEG is true, the imaginary
-   zero is negative.  */
-
-static tree
-build_complex_cproj (tree type, bool neg)
-{
-  REAL_VALUE_TYPE rinf, rzero = dconst0;
-  
-  real_inf (&rinf);
-  rzero.sign = neg;
-  return build_complex (type, build_real (TREE_TYPE (type), rinf),
-                       build_real (TREE_TYPE (type), rzero));
-}
-
-/* Fold call to builtin cproj, cprojf or cprojl with argument ARG.  TYPE is the
-   return type.  Return NULL_TREE if no simplification can be made.  */
-
-static tree
-fold_builtin_cproj (location_t loc, tree arg, tree type)
-{
-  if (!validate_arg (arg, COMPLEX_TYPE)
-      || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
-    return NULL_TREE;
-
-  /* If there are no infinities, return arg.  */
-  if (! HONOR_INFINITIES (type))
-    return non_lvalue_loc (loc, arg);
-
-  /* Calculate the result when the argument is a constant.  */
-  if (TREE_CODE (arg) == COMPLEX_CST)
-    {
-      const REAL_VALUE_TYPE *real = TREE_REAL_CST_PTR (TREE_REALPART (arg));
-      const REAL_VALUE_TYPE *imag = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
-      
-      if (real_isinf (real) || real_isinf (imag))
-       return build_complex_cproj (type, imag->sign);
-      else
-       return arg;
-    }
-
-  return NULL_TREE;
-}
-
 /* Fold function call to builtin tan, tanf, or tanl with argument ARG.
    Return NULL_TREE if no simplification can be made.  */
 
@@ -9504,7 +9460,20 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
       break;
 
     CASE_FLT_FN (BUILT_IN_CPROJ):
-      return fold_builtin_cproj (loc, arg0, type);
+      if (TREE_CODE (arg0) == COMPLEX_CST
+         && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
+       {
+         const REAL_VALUE_TYPE *real
+           = TREE_REAL_CST_PTR (TREE_REALPART (arg0));
+         const REAL_VALUE_TYPE *imag
+           = TREE_REAL_CST_PTR (TREE_IMAGPART (arg0));
+
+         if (real_isinf (real) || real_isinf (imag))
+           return build_complex_inf (type, imag->sign);
+         else
+           return arg0;
+       }
+      break;
 
     CASE_FLT_FN (BUILT_IN_CSIN):
       if (validate_arg (arg0, COMPLEX_TYPE)
index 0a9598e..6b18189 100644 (file)
@@ -2479,30 +2479,24 @@ along with GCC; see the file COPYING3.  If not see
   (CABS (complex @0 @0))
   (mult (abs @0) { build_real_truncate (type, dconst_sqrt2 ()); })))
 
+/* cproj(x) -> x if we're ignoring infinities.  */
+(simplify
+ (CPROJ @0)
+ (if (!HONOR_INFINITIES (type))
+   @0))
+
 /* If the real part is inf and the imag part is known to be
    nonnegative, return (inf + 0i).  */
 (simplify
  (CPROJ (complex REAL_CST@0 tree_expr_nonnegative_p@1))
  (if (real_isinf (TREE_REAL_CST_PTR (@0)))
-  (with
-    {
-      REAL_VALUE_TYPE rinf;
-      real_inf (&rinf);
-    }
-   { build_complex (type, build_real (TREE_TYPE (type), rinf),
-                   build_zero_cst (TREE_TYPE (type))); })))
+  { build_complex_inf (type, false); }))
+
 /* If the imag part is inf, return (inf+I*copysign(0,imag)).  */
 (simplify
  (CPROJ (complex @0 REAL_CST@1))
  (if (real_isinf (TREE_REAL_CST_PTR (@1)))
-  (with
-    {
-      REAL_VALUE_TYPE rinf, rzero = dconst0;
-      real_inf (&rinf);
-      rzero.sign = TREE_REAL_CST_PTR (@1)->sign;
-    }
-   { build_complex (type, build_real (TREE_TYPE (type), rinf),
-                   build_real (TREE_TYPE (type), rzero)); })))
+  { build_complex_inf (type, TREE_REAL_CST_PTR (@1)->sign); }))
 
 
 /* Narrowing of arithmetic and logical operations. 
index adc8748..09df67e 100644 (file)
@@ -1986,6 +1986,21 @@ build_complex (tree type, tree real, tree imag)
   return t;
 }
 
+/* Build a complex (inf +- 0i), such as for the result of cproj.
+   TYPE is the complex tree type of the result.  If NEG is true, the
+   imaginary zero is negative.  */
+
+tree
+build_complex_inf (tree type, bool neg)
+{
+  REAL_VALUE_TYPE rinf, rzero = dconst0;
+
+  real_inf (&rinf);
+  rzero.sign = neg;
+  return build_complex (type, build_real (TREE_TYPE (type), rinf),
+                       build_real (TREE_TYPE (type), rzero));
+}
+
 /* Return the constant 1 in type TYPE.  If TYPE has several elements, each
    element is set to 1.  In particular, this is 1 + i for complex types.  */
 
index 300077c..ece083b 100644 (file)
@@ -3853,6 +3853,7 @@ extern tree build_constructor_from_list (tree, tree);
 extern tree build_constructor_va (tree, int, ...);
 extern tree build_real_from_int_cst (tree, const_tree);
 extern tree build_complex (tree, tree, tree);
+extern tree build_complex_inf (tree, bool);
 extern tree build_each_one_cst (tree);
 extern tree build_one_cst (tree);
 extern tree build_minus_one_cst (tree);