diff options
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/builtins.c | 31 | ||||
-rw-r--r-- | gcc/fold-const.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtins-20.c | 81 |
5 files changed, 110 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a4c8553..df5448b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2006-11-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + * builtins.c (fold_builtin_cos): Use fold_strip_sign_ops(). + (fold_builtin_hypot): Likewise. + * fold-const.c (fold_strip_sign_ops): Handle "odd" builtins. + * fold-const.c (negate_mathfn_p): Add BUILT_IN_ERF. 2006-11-10 Roger Sayle <roger@eyesopen.com> diff --git a/gcc/builtins.c b/gcc/builtins.c index 9d27243..f1fa123 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -7242,7 +7242,7 @@ static tree fold_builtin_cos (tree arglist, tree type, tree fndecl) { tree arg = TREE_VALUE (arglist); - tree res; + tree res, narg; if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) return NULL_TREE; @@ -7252,12 +7252,9 @@ fold_builtin_cos (tree arglist, tree type, tree fndecl) return res; /* Optimize cos(-x) into cos (x). */ - if (TREE_CODE (arg) == NEGATE_EXPR) - { - tree args = build_tree_list (NULL_TREE, - TREE_OPERAND (arg, 0)); - return build_function_call_expr (fndecl, args); - } + if ((narg = fold_strip_sign_ops (arg))) + return build_function_call_expr (fndecl, + build_tree_list (NULL_TREE, narg)); return NULL_TREE; } @@ -7765,7 +7762,7 @@ fold_builtin_hypot (tree fndecl, tree arglist, tree type) { tree arg0 = TREE_VALUE (arglist); tree arg1 = TREE_VALUE (TREE_CHAIN (arglist)); - tree res; + tree res, narg0, narg1; if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) return NULL_TREE; @@ -7776,17 +7773,13 @@ fold_builtin_hypot (tree fndecl, tree arglist, tree type) /* If either argument to hypot has a negate or abs, strip that off. E.g. hypot(-x,fabs(y)) -> hypot(x,y). */ - if (TREE_CODE (arg0) == NEGATE_EXPR || TREE_CODE (arg1) == NEGATE_EXPR - || TREE_CODE (arg0) == ABS_EXPR || TREE_CODE (arg1) == ABS_EXPR) - { - tree narg0 = (TREE_CODE (arg0) == NEGATE_EXPR - || TREE_CODE (arg0) == ABS_EXPR) - ? TREE_OPERAND (arg0, 0) : arg0; - tree narg1 = (TREE_CODE (arg1) == NEGATE_EXPR - || TREE_CODE (arg1) == ABS_EXPR) - ? TREE_OPERAND (arg1, 0) : arg1; - tree narglist = tree_cons (NULL_TREE, narg0, - build_tree_list (NULL_TREE, narg1)); + narg0 = fold_strip_sign_ops (arg0); + narg1 = fold_strip_sign_ops (arg1); + if (narg0 || narg1) + { + tree narglist = tree_cons (NULL_TREE, narg0 ? narg0 : arg0, + build_tree_list (NULL_TREE, + narg1 ? narg1 : arg1)); return build_function_call_expr (fndecl, narglist); } diff --git a/gcc/fold-const.c b/gcc/fold-const.c index fedc3ca..7c769d5 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -13296,6 +13296,17 @@ fold_strip_sign_ops (tree exp) arg1 ? arg1 : TREE_OPERAND (exp, 1)); break; + case CALL_EXPR: + /* Strip sign ops from the argument of "odd" math functions. */ + if (negate_mathfn_p (builtin_mathfn_code (exp))) + { + arg0 = fold_strip_sign_ops (TREE_VALUE (TREE_OPERAND (exp, 1))); + if (arg0) + return build_function_call_expr (get_callee_fndecl (exp), + build_tree_list (NULL_TREE, arg0)); + } + break; + default: break; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7566130..b928b36 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2006-11-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + * gcc.dg/builtins-20.c: Add more cases for stripping sign ops. + * gcc.dg/torture/builtin-symmetric-1.c: New test. 2006-11-10 Paul Thomas <pault@gcc.gnu.org> diff --git a/gcc/testsuite/gcc.dg/builtins-20.c b/gcc/testsuite/gcc.dg/builtins-20.c index 0c6736c..e9f27a0 100644 --- a/gcc/testsuite/gcc.dg/builtins-20.c +++ b/gcc/testsuite/gcc.dg/builtins-20.c @@ -38,6 +38,15 @@ void test1(double x) if (cos(x) != cos(-x)) link_error (); + if (cos(x) != cos(fabs(x))) + link_error (); + + if (cos(x) != cos(-fabs(x))) + link_error (); + + if (cos(tan(x)) != cos(tan(-fabs(x)))) + link_error (); + if (sin(x)/cos(x) != tan(x)) link_error (); @@ -65,6 +74,21 @@ void test2(double x, double y) if (-sin(x-y) != sin(y-x)) link_error (); + if (cos(-x*y) != cos(x*y)) + link_error (); + + if (cos(x*-y) != cos(x*y)) + link_error (); + + if (cos(-x/y) != cos(x/y)) + link_error (); + + if (cos(x/-y) != cos(x/y)) + link_error (); + + if (cos(-fabs(tan(x/-y))) != cos(tan(x/y))) + link_error (); + if (hypot (x, 0) != fabs(x)) link_error (); @@ -103,6 +127,9 @@ void test2(double x, double y) if (hypot (pure(x), -pure(x)) != fabs(pure(x)) * __builtin_sqrt(2)) link_error (); + + if (hypot (tan(-x), tan(-fabs(y))) != hypot (tan(x), tan(y))) + link_error (); } void test1f(float x) @@ -110,6 +137,15 @@ void test1f(float x) if (cosf(x) != cosf(-x)) link_error (); + if (cosf(x) != cosf(fabsf(x))) + link_error (); + + if (cosf(x) != cosf(-fabsf(x))) + link_error (); + + if (cosf(tanf(x)) != cosf(tanf(-fabsf(x)))) + link_error (); + #ifdef HAVE_C99_RUNTIME if (sinf(x)/cosf(x) != tanf(x)) link_error (); @@ -139,6 +175,21 @@ void test2f(float x, float y) if (-sinf(x-y) != sinf(y-x)) link_error (); + if (cosf(-x*y) != cosf(x*y)) + link_error (); + + if (cosf(x*-y) != cosf(x*y)) + link_error (); + + if (cosf(-x/y) != cosf(x/y)) + link_error (); + + if (cosf(x/-y) != cosf(x/y)) + link_error (); + + if (cosf(-fabsf(tanf(x/-y))) != cosf(tanf(x/y))) + link_error (); + if (hypotf (x, 0) != fabsf(x)) link_error (); @@ -177,6 +228,9 @@ void test2f(float x, float y) if (hypotf (puref(x), -puref(x)) != fabsf(puref(x)) * __builtin_sqrtf(2)) link_error (); + + if (hypotf (tanf(-x), tanf(-fabsf(y))) != hypotf (tanf(x), tanf(y))) + link_error (); } @@ -185,6 +239,15 @@ void test1l(long double x) if (cosl(x) != cosl(-x)) link_error (); + if (cosl(x) != cosl(fabsl(x))) + link_error (); + + if (cosl(x) != cosl(-fabsl(x))) + link_error (); + + if (cosl(tanl(x)) != cosl(tanl(-fabsl(x)))) + link_error (); + #ifdef HAVE_C99_RUNTIME if (sinl(x)/cosl(x) != tanl(x)) link_error (); @@ -214,6 +277,21 @@ void test2l(long double x, long double y) if (-sinl(x-y) != sinl(y-x)) link_error (); + if (cosl(-x*y) != cosl(x*y)) + link_error (); + + if (cosl(x*-y) != cosl(x*y)) + link_error (); + + if (cosl(-x/y) != cosl(x/y)) + link_error (); + + if (cosl(x/-y) != cosl(x/y)) + link_error (); + + if (cosl(-fabsl(tanl(x/-y))) != cosl(tanl(x/y))) + link_error (); + if (hypotl (x, 0) != fabsl(x)) link_error (); @@ -252,6 +330,9 @@ void test2l(long double x, long double y) if (hypotl (purel(x), -purel(x)) != fabsl(purel(x)) * __builtin_sqrtl(2)) link_error (); + + if (hypotl (tanl(-x), tanl(-fabsl(y))) != hypotl (tanl(x), tanl(y))) + link_error (); } int main() |