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
This commit is contained in:
parent
9f5396713d
commit
28f4586bf8
6 changed files with 114 additions and 3 deletions
|
@ -1,3 +1,11 @@
|
|||
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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
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
|
||||
|
|
|
@ -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)
|
||||
|
|
31
gcc/testsuite/gcc.dg/builtins-61.c
Normal file
31
gcc/testsuite/gcc.dg/builtins-61.c
Normal file
|
@ -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" } } */
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue