aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2006-12-14 13:14:23 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2006-12-14 13:14:23 +0000
commit28f4586bf8676b0c6a44d239e366432d5e1fbe1b (patch)
treeff05698d7bed697273367ce096bf05306d5df40e
parent9f5396713d9e188bad160c5816f3bfd21b6f32ca (diff)
downloadgcc-28f4586bf8676b0c6a44d239e366432d5e1fbe1b.zip
gcc-28f4586bf8676b0c6a44d239e366432d5e1fbe1b.tar.gz
gcc-28f4586bf8676b0c6a44d239e366432d5e1fbe1b.tar.bz2
re PR middle-end/30197 (cexp ( __complex__ ( 0, x ) ) can be folded to cexpi (x))
2006-12-14 Richard Guenther <rguenther@suse.de> PR tree-optimization/30197 * builtins.c (fold_builtin_cexp): New function to fold cexp to cexpi and exp parts. * tree-ssa-pre.c (try_combine_conversion): Also handle REALPART_EXPR and IMAGPART_EXPR. * gcc.c-torture/execute/complex-1.c: Fix function name. * gcc.dg/builtins-61.c: New testcase. From-SVN: r119860
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/builtins.c64
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/complex-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/builtins-61.c31
-rw-r--r--gcc/tree-ssa-pre.c4
6 files changed, 114 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c81598c..82a3641 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
2006-12-14 Richard Guenther <rguenther@suse.de>
+ PR tree-optimization/30197
+ * builtins.c (fold_builtin_cexp): New function to fold cexp
+ to cexpi and exp parts.
+ * tree-ssa-pre.c (try_combine_conversion): Also handle
+ REALPART_EXPR and IMAGPART_EXPR.
+
+2006-12-14 Richard Guenther <rguenther@suse.de>
+
PR middle-end/30172
* fold-const.c (fold_binary): Fold __complex__ ( x, 0 )
+ __complex__ ( 0, y ) to __complex__ ( x, y ).
diff --git a/gcc/builtins.c b/gcc/builtins.c
index d0271bc..f5798e7 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -7367,6 +7367,67 @@ fold_builtin_sincos (tree arglist)
build1 (REALPART_EXPR, type, call)));
}
+/* Fold function call to builtin cexp, cexpf, or cexpl. Return
+ NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_cexp (tree arglist, tree type)
+{
+ tree arg0, rtype;
+ tree realp, imagp, ifn;
+
+ if (!validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
+ return NULL_TREE;
+
+ arg0 = TREE_VALUE (arglist);
+ rtype = TREE_TYPE (TREE_TYPE (arg0));
+
+ /* In case we can figure out the real part of arg0 and it is constant zero
+ fold to cexpi. */
+ ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
+ if (!ifn)
+ return NULL_TREE;
+
+ if ((realp = fold_unary (REALPART_EXPR, rtype, arg0))
+ && real_zerop (realp))
+ {
+ tree narg = fold_build1 (IMAGPART_EXPR, rtype, arg0);
+ return build_function_call_expr (ifn, build_tree_list (NULL_TREE, narg));
+ }
+
+ /* In case we can easily decompose real and imaginary parts split cexp
+ to exp (r) * cexpi (i). */
+ if (flag_unsafe_math_optimizations
+ && realp)
+ {
+ tree rfn, rcall, icall;
+
+ rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
+ if (!rfn)
+ return NULL_TREE;
+
+ imagp = fold_unary (IMAGPART_EXPR, rtype, arg0);
+ if (!imagp)
+ return NULL_TREE;
+
+ icall = build_function_call_expr (ifn,
+ build_tree_list (NULL_TREE, imagp));
+ icall = builtin_save_expr (icall);
+ rcall = build_function_call_expr (rfn,
+ build_tree_list (NULL_TREE, realp));
+ rcall = builtin_save_expr (rcall);
+ return build2 (COMPLEX_EXPR, type,
+ build2 (MULT_EXPR, rtype,
+ rcall,
+ build1 (REALPART_EXPR, rtype, icall)),
+ build2 (MULT_EXPR, rtype,
+ rcall,
+ build1 (IMAGPART_EXPR, rtype, icall)));
+ }
+
+ return NULL_TREE;
+}
+
/* Fold function call to builtin trunc, truncf or truncl. Return
NULL_TREE if no simplification can be made. */
@@ -9312,6 +9373,9 @@ fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
CASE_FLT_FN (BUILT_IN_SINCOS):
return fold_builtin_sincos (arglist);
+ CASE_FLT_FN (BUILT_IN_CEXP):
+ return fold_builtin_cexp (arglist, type);
+
CASE_FLT_FN (BUILT_IN_CEXPI):
if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
return do_mpfr_sincos (TREE_VALUE (arglist), NULL_TREE, NULL_TREE);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 296a34c..ee65e74 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2006-12-14 Richard Guenther <rguenther@suse.de>
+ PR tree-optimization/30197
+ * gcc.c-torture/execute/complex-1.c: Fix function name.
+ * gcc.dg/builtins-61.c: New testcase.
+
+2006-12-14 Richard Guenther <rguenther@suse.de>
+
PR middle-end/30172
* gcc.dg/pr30172-1.c: New testcase.
diff --git a/gcc/testsuite/gcc.c-torture/execute/complex-1.c b/gcc/testsuite/gcc.c-torture/execute/complex-1.c
index 424fa65..5910179 100644
--- a/gcc/testsuite/gcc.c-torture/execute/complex-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/complex-1.c
@@ -17,7 +17,7 @@ g2 (double x)
}
__complex__ double
-cexp (__complex__ double x)
+xcexp (__complex__ double x)
{
double r;
@@ -31,7 +31,7 @@ main ()
{
__complex__ double x;
- x = cexp (1.0i);
+ x = xcexp (1.0i);
if (__real__ x != -1.0)
abort ();
if (__imag__ x != 0.0)
diff --git a/gcc/testsuite/gcc.dg/builtins-61.c b/gcc/testsuite/gcc.dg/builtins-61.c
new file mode 100644
index 0000000..9f0c990
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtins-61.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O -ffast-math -fdump-tree-optimized" } */
+
+double test1 (double x)
+{
+ return __real __builtin_cexp(x * (__extension__ 1.0iF));
+}
+
+double test2(double x)
+{
+ return __imag __builtin_cexp((__extension__ 1.0iF) * x);
+}
+
+double test3(double x)
+{
+ _Complex c = __builtin_cexp(x * (__extension__ 1.0iF));
+ return __imag c + __real c;
+}
+
+double test4(double x, double y)
+{
+ _Complex c = __builtin_cexp(x);
+ x = __builtin_exp (x);
+ return x - __real c;
+}
+
+/* { dg-final { scan-tree-dump "cexpi" "optimized" } } */
+/* { dg-final { scan-tree-dump "sin" "optimized" } } */
+/* { dg-final { scan-tree-dump "cos" "optimized" } } */
+/* { dg-final { scan-tree-dump "return 0.0" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 871006d..72af16d 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -3613,7 +3613,9 @@ try_combine_conversion (tree *expr_p)
unsigned int firstbit;
if (!((TREE_CODE (expr) == NOP_EXPR
- || TREE_CODE (expr) == CONVERT_EXPR)
+ || TREE_CODE (expr) == CONVERT_EXPR
+ || TREE_CODE (expr) == REALPART_EXPR
+ || TREE_CODE (expr) == IMAGPART_EXPR)
&& TREE_CODE (TREE_OPERAND (expr, 0)) == VALUE_HANDLE
&& !VALUE_HANDLE_VUSES (TREE_OPERAND (expr, 0))))
return false;