diff options
author | Kaveh R. Ghazi <ghazi@caip.rutgers.edu> | 2006-10-29 23:08:23 +0000 |
---|---|---|
committer | Kaveh Ghazi <ghazi@gcc.gnu.org> | 2006-10-29 23:08:23 +0000 |
commit | 012c53688f45b1f6adcfe36b4ce5ec01b7f95944 (patch) | |
tree | 528c604c4234ce45889c8180077ec5e944d5ea0f /gcc/builtins.c | |
parent | cd07aa11f91bcd8b0eb89d0f60412b3008a0ca6a (diff) | |
download | gcc-012c53688f45b1f6adcfe36b4ce5ec01b7f95944.zip gcc-012c53688f45b1f6adcfe36b4ce5ec01b7f95944.tar.gz gcc-012c53688f45b1f6adcfe36b4ce5ec01b7f95944.tar.bz2 |
builtins.c (fold_builtin_hypot): Rearrange recursive transformation before others, and also do ABS_EXPR.
* builtins.c (fold_builtin_hypot): Rearrange recursive
transformation before others, and also do ABS_EXPR. When
necessary, check flag_unsafe_math_optimizations. When necessary,
add fabs.
testsuite:
* gcc.dg/builtins-20.c: Add more hypot tests.
From-SVN: r118160
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index 5375c5c..3af86cc 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -7677,35 +7677,40 @@ fold_builtin_hypot (tree fndecl, tree arglist, tree type) if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot))) return res; + /* 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)); + return build_function_call_expr (fndecl, narglist); + } + /* If either argument is zero, hypot is fabs of the other. */ if (real_zerop (arg0)) return fold_build1 (ABS_EXPR, type, arg1); else if (real_zerop (arg1)) return fold_build1 (ABS_EXPR, type, arg0); - /* hypot(x,x) -> x*sqrt(2). */ - if (operand_equal_p (arg0, arg1, OEP_PURE_SAME)) + /* hypot(x,x) -> fabs(x)*sqrt(2). */ + if (flag_unsafe_math_optimizations + && operand_equal_p (arg0, arg1, OEP_PURE_SAME)) { REAL_VALUE_TYPE sqrt2; real_sqrt (&sqrt2, TYPE_MODE (type), &dconst2); - return fold_build2 (MULT_EXPR, type, arg0, + return fold_build2 (MULT_EXPR, type, + fold_build1 (ABS_EXPR, type, arg0), build_real (type, sqrt2)); } - /* Transform hypot(-x,y) or hypot(x,-y) or hypot(-x,-y) into - hypot(x,y). */ - if (TREE_CODE (arg0) == NEGATE_EXPR || TREE_CODE (arg1) == NEGATE_EXPR) - { - tree narg0 = (TREE_CODE (arg0) == NEGATE_EXPR) - ? TREE_OPERAND (arg0, 0) : arg0; - tree narg1 = (TREE_CODE (arg1) == NEGATE_EXPR) - ? TREE_OPERAND (arg1, 0) : arg1; - tree narglist = tree_cons (NULL_TREE, narg0, - build_tree_list (NULL_TREE, narg1)); - return build_function_call_expr (fndecl, narglist); - } - return NULL_TREE; } |