Commit 28f4586b by Richard Guenther Committed by Richard Biener

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
parent 9f539671
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 ).
......
......@@ -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);
......
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.
......@@ -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)
......
/* { 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" } } */
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment