mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-21 13:39:39 +08:00
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
This commit is contained in:
parent
cd07aa11f9
commit
012c53688f
@ -1,3 +1,10 @@
|
||||
2006-10-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* 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.
|
||||
|
||||
2006-10-29 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* fold-const.c (fold_comparison): Fold ~X op ~Y as Y op X.
|
||||
|
@ -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 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))
|
||||
/* 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)
|
||||
{
|
||||
REAL_VALUE_TYPE sqrt2;
|
||||
|
||||
real_sqrt (&sqrt2, TYPE_MODE (type), &dconst2);
|
||||
return fold_build2 (MULT_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 narg0 = (TREE_CODE (arg0) == NEGATE_EXPR
|
||||
|| TREE_CODE (arg0) == ABS_EXPR)
|
||||
? TREE_OPERAND (arg0, 0) : arg0;
|
||||
tree narg1 = (TREE_CODE (arg1) == NEGATE_EXPR)
|
||||
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) -> 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,
|
||||
fold_build1 (ABS_EXPR, type, arg0),
|
||||
build_real (type, sqrt2));
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
2006-10-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* gcc.dg/builtins-20.c: Add more hypot tests.
|
||||
|
||||
2006-10-29 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* gcc.dg/fold-compare-1.c: New test case.
|
||||
|
@ -16,14 +16,17 @@ extern double cos (double);
|
||||
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);
|
||||
|
||||
@ -65,7 +68,7 @@ void test2(double x, double y)
|
||||
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))
|
||||
@ -76,6 +79,29 @@ void test2(double x, double 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)
|
||||
@ -118,7 +144,7 @@ void test2f(float x, float y)
|
||||
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))
|
||||
@ -129,6 +155,29 @@ void test2f(float x, float 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 ();
|
||||
}
|
||||
|
||||
|
||||
@ -172,7 +221,7 @@ void test2l(long double x, long double y)
|
||||
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))
|
||||
@ -183,6 +232,29 @@ void test2l(long double x, long double 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()
|
||||
|
Loading…
Reference in New Issue
Block a user