diff options
author | Richard Guenther <rguenther@suse.de> | 2006-12-14 13:14:23 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2006-12-14 13:14:23 +0000 |
commit | 28f4586bf8676b0c6a44d239e366432d5e1fbe1b (patch) | |
tree | ff05698d7bed697273367ce096bf05306d5df40e /gcc/builtins.c | |
parent | 9f5396713d9e188bad160c5816f3bfd21b6f32ca (diff) | |
download | gcc-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
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index d0271bc..f5798e7894 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); |