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;
}
extern double sin (double);
extern double tan (double);
extern double hypot (double, double);
+extern double pure (double) __attribute__ ((__pure__));
extern float cosf (float);
extern float sinf (float);
extern float tanf (float);
extern float hypotf (float, float);
+extern float puref (float) __attribute__ ((__pure__));
extern long double cosl (long double);
extern long double sinl (long double);
extern long double tanl (long double);
extern long double hypotl (long double, long double);
+extern long double purel (long double) __attribute__ ((__pure__));
extern void link_error(void);
if (hypot (0, x) != __builtin_fabs(x))
link_error ();
- if (hypot (x, x) != x * __builtin_sqrt(2))
+ if (hypot (x, x) != __builtin_fabs(x) * __builtin_sqrt(2))
link_error ();
if (hypot (-x, y) != hypot (x, y))
if (hypot (-x, -y) != hypot (x, y))
link_error ();
+
+ if (hypot (__builtin_fabs(x), y) != hypot (x, y))
+ link_error ();
+
+ if (hypot (x, __builtin_fabs(y)) != hypot (x, y))
+ link_error ();
+
+ if (hypot (__builtin_fabs(x), __builtin_fabs(y)) != hypot (x, y))
+ link_error ();
+
+ if (hypot (-__builtin_fabs(-x),
+ -__builtin_fabs(__builtin_fabs(__builtin_fabs(-y))))
+ != hypot (x, y))
+ link_error ();
+
+ if (hypot (-x, 0) != __builtin_fabs(x))
+ link_error ();
+
+ if (hypot (-x, x) != __builtin_fabs(x) * __builtin_sqrt(2))
+ link_error ();
+
+ if (hypot (pure(x), -pure(x)) != __builtin_fabs(pure(x)) * __builtin_sqrt(2))
+ link_error ();
}
void test1f(float x)
if (hypotf (0, x) != __builtin_fabsf(x))
link_error ();
- if (hypotf (x, x) != x * __builtin_sqrtf(2))
+ if (hypotf (x, x) != __builtin_fabsf(x) * __builtin_sqrtf(2))
link_error ();
if (hypotf (-x, y) != hypotf (x, y))
if (hypotf (-x, -y) != hypotf (x, y))
link_error ();
+
+ if (hypotf (__builtin_fabsf(x), y) != hypotf (x, y))
+ link_error ();
+
+ if (hypotf (x, __builtin_fabsf(y)) != hypotf (x, y))
+ link_error ();
+
+ if (hypotf (__builtin_fabsf(x), __builtin_fabsf(y)) != hypotf (x, y))
+ link_error ();
+
+ if (hypotf (-__builtin_fabsf(-x),
+ -__builtin_fabsf(__builtin_fabsf(__builtin_fabsf(-y))))
+ != hypotf (x, y))
+ link_error ();
+
+ if (hypotf (-x, 0) != __builtin_fabsf(x))
+ link_error ();
+
+ if (hypotf (-x, x) != __builtin_fabsf(x) * __builtin_sqrtf(2))
+ link_error ();
+
+ if (hypotf (puref(x), -puref(x)) != __builtin_fabsf(puref(x)) * __builtin_sqrtf(2))
+ link_error ();
}
if (hypotl (0, x) != __builtin_fabsl(x))
link_error ();
- if (hypotl (x, x) != x * __builtin_sqrtl(2))
+ if (hypotl (x, x) != __builtin_fabsl(x) * __builtin_sqrtl(2))
link_error ();
if (hypotl (-x, y) != hypotl (x, y))
if (hypotl (-x, -y) != hypotl (x, y))
link_error ();
+
+ if (hypotl (__builtin_fabsl(x), y) != hypotl (x, y))
+ link_error ();
+
+ if (hypotl (x, __builtin_fabsl(y)) != hypotl (x, y))
+ link_error ();
+
+ if (hypotl (__builtin_fabsl(x), __builtin_fabsl(y)) != hypotl (x, y))
+ link_error ();
+
+ if (hypotl (-__builtin_fabsl(-x),
+ -__builtin_fabsl(__builtin_fabsl(__builtin_fabsl(-y))))
+ != hypotl (x, y))
+ link_error ();
+
+ if (hypotl (-x, 0) != __builtin_fabsl(x))
+ link_error ();
+
+ if (hypotl (-x, x) != __builtin_fabsl(x) * __builtin_sqrtl(2))
+ link_error ();
+
+ if (hypotl (purel(x), -purel(x)) != __builtin_fabsl(purel(x)) * __builtin_sqrtl(2))
+ link_error ();
}
int main()