aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>2006-10-29 23:08:23 +0000
committerKaveh Ghazi <ghazi@gcc.gnu.org>2006-10-29 23:08:23 +0000
commit012c53688f45b1f6adcfe36b4ce5ec01b7f95944 (patch)
tree528c604c4234ce45889c8180077ec5e944d5ea0f /gcc/builtins.c
parentcd07aa11f91bcd8b0eb89d0f60412b3008a0ca6a (diff)
downloadgcc-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.c37
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;
}