diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/builtins.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtins-54.c | 44 |
4 files changed, 68 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6268ad0..4dcbbf1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2006-05-31 Roger Sayle <roger@eyesopen.com> + + * builtins.c (fold_builtin_cabs): Delete prototype. Require an + additional FNDECL argument. Optimize cabs(-z) and cabs(~z) as + cabs(z). + (fold_builtin_decl) <BUILT_IN_CABS>: Update fold_builtin_cabs call. + 2006-05-31 Jie Zhang <jie.zhang@analog.com> * config/bfin/bfin-protos.h (bfin_hardware_loop): Declare. diff --git a/gcc/builtins.c b/gcc/builtins.c index b9d94eb..7113681 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -146,7 +146,6 @@ static tree fold_trunc_transparent_mathfn (tree, tree); static bool readonly_data_expr (tree); static rtx expand_builtin_fabs (tree, rtx, rtx); static rtx expand_builtin_signbit (tree, rtx); -static tree fold_builtin_cabs (tree, tree); static tree fold_builtin_sqrt (tree, tree); static tree fold_builtin_cbrt (tree, tree); static tree fold_builtin_pow (tree, tree, tree); @@ -6772,11 +6771,12 @@ fold_fixed_mathfn (tree fndecl, tree arglist) } /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST - is the argument list and TYPE is the return type. Return - NULL_TREE if no if no simplification can be made. */ + is the argument list, TYPE is the return type and FNDECL is the + original function DECL. Return NULL_TREE if no if no simplification + can be made. */ static tree -fold_builtin_cabs (tree arglist, tree type) +fold_builtin_cabs (tree arglist, tree type, tree fndecl) { tree arg; @@ -6817,6 +6817,14 @@ fold_builtin_cabs (tree arglist, tree type) && real_zerop (TREE_OPERAND (arg, 1))) return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)); + /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */ + if (TREE_CODE (arg) == NEGATE_EXPR + || TREE_CODE (arg) == CONJ_EXPR) + { + tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0)); + return build_function_call_expr (fndecl, arglist); + } + /* Don't do this when optimizing for size. */ if (flag_unsafe_math_optimizations && optimize && !optimize_size) @@ -8648,7 +8656,7 @@ fold_builtin_1 (tree fndecl, tree arglist, bool ignore) break; CASE_FLT_FN (BUILT_IN_CABS): - return fold_builtin_cabs (arglist, type); + return fold_builtin_cabs (arglist, type, fndecl); CASE_FLT_FN (BUILT_IN_SQRT): return fold_builtin_sqrt (arglist, type); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ddd2fda..c0b7c04 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2006-05-31 Roger Sayle <roger@eyesopen.com> + + * gcc.dg/builtins-54.c: New test case. + 2006-05-30 Mark Mitchell <mark@codesourcery.com> PR c++/26433 diff --git a/gcc/testsuite/gcc.dg/builtins-54.c b/gcc/testsuite/gcc.dg/builtins-54.c new file mode 100644 index 0000000..29cdf20 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtins-54.c @@ -0,0 +1,44 @@ +/* { dg-do link } */ +/* { dg-options "-O2 -ffast-math" } */ + +double cabs(__complex__ double); +float cabsf(__complex__ float); +long double cabsl(__complex__ long double); + +void link_error (void); + +void test(__complex__ double x) +{ + if (cabs(x) != cabs(-x)) + link_error(); + + if (cabs(x) != cabs(~x)) + link_error(); +} + +void testf(__complex__ float x) +{ + if (cabsf(x) != cabsf(-x)) + link_error(); + + if (cabsf(x) != cabsf(~x)) + link_error(); +} + +void testl(__complex__ long double x) +{ + if (cabsl(x) != cabsl(-x)) + link_error(); + + if (cabsl(x) != cabsl(~x)) + link_error(); +} + +int main() +{ + test(0.0); + testf(0.0); + testl(0.0); + return 0; +} + |