diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d531d976f36..398f2417980 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2007-06-12 Kaveh R. Ghazi + + * real.c (real_isfinite): New. + (real_sqrt): Use it. + * real.h (real_isfinite): New. + * builtins.c: Use it. + 2007-06-12 Ian Lance Taylor Daniel Berlin diff --git a/gcc/builtins.c b/gcc/builtins.c index 2f3f1a9a435..133aa7c8d11 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -7774,7 +7774,7 @@ fold_builtin_int_roundingfn (tree fndecl, tree arg) { const REAL_VALUE_TYPE x = TREE_REAL_CST (arg); - if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x)) + if (real_isfinite (&x)) { tree itype = TREE_TYPE (TREE_TYPE (fndecl)); tree ftype = TREE_TYPE (arg); @@ -9335,8 +9335,7 @@ fold_builtin_load_exponent (tree arg0, tree arg1, tree type, bool ldexp) /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0. */ if (real_zerop (arg0) || integer_zerop (arg1) || (TREE_CODE (arg0) == REAL_CST - && (real_isnan (&TREE_REAL_CST (arg0)) - || real_isinf (&TREE_REAL_CST (arg0))))) + && !real_isfinite (&TREE_REAL_CST (arg0)))) return omit_one_operand (type, arg0, arg1); /* If both arguments are constant, then try to evaluate it. */ @@ -9479,8 +9478,7 @@ fold_builtin_classify (tree fndecl, tree arg, int builtin_index) if (TREE_CODE (arg) == REAL_CST) { r = TREE_REAL_CST (arg); - return real_isinf (&r) || real_isnan (&r) - ? integer_zero_node : integer_one_node; + return real_isfinite (&r) ? integer_one_node : integer_zero_node; } return NULL_TREE; @@ -12361,7 +12359,7 @@ do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact) check for overflow/underflow. If the REAL_VALUE_TYPE is zero but the mpft_t is not, then we underflowed in the conversion. */ - if (!real_isnan (&rr) && !real_isinf (&rr) + if (real_isfinite (&rr) && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0)) { REAL_VALUE_TYPE rmode; @@ -12400,7 +12398,7 @@ do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t), { const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg); - if (!real_isnan (ra) && !real_isinf (ra) + if (real_isfinite (ra) && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)) && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max))) { @@ -12444,8 +12442,7 @@ do_mpfr_arg2 (tree arg1, tree arg2, tree type, const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1); const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2); - if (!real_isnan (ra1) && !real_isinf (ra1) - && !real_isnan (ra2) && !real_isinf (ra2)) + if (real_isfinite (ra1) && real_isfinite (ra2)) { const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p; int inexact; @@ -12491,9 +12488,7 @@ do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type, const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2); const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3); - if (!real_isnan (ra1) && !real_isinf (ra1) - && !real_isnan (ra2) && !real_isinf (ra2) - && !real_isnan (ra3) && !real_isinf (ra3)) + if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3)) { const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p; int inexact; @@ -12536,7 +12531,7 @@ do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp) { const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg); - if (!real_isnan (ra) && !real_isinf (ra)) + if (real_isfinite (ra)) { const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p; tree result_s, result_c; @@ -12608,7 +12603,7 @@ do_mpfr_bessel_n (tree arg1, tree arg2, tree type, const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2); if (n == (long)n - && !real_isnan (ra) && !real_isinf (ra) + && real_isfinite (ra) && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))) { const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p; @@ -12650,8 +12645,7 @@ do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo) const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0); const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1); - if (!real_isnan (ra0) && !real_isinf (ra0) - && !real_isnan (ra1) && !real_isinf (ra1)) + if (real_isfinite (ra0) && real_isfinite (ra1)) { const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p; tree result_rem; @@ -12726,7 +12720,7 @@ do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type) /* In addition to NaN and Inf, the argument cannot be zero or a negative integer. */ - if (!real_isnan (ra) && !real_isinf (ra) + if (real_isfinite (ra) && ra->cl != rvc_zero && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type)))) { diff --git a/gcc/real.c b/gcc/real.c index 9a84329f975..b4d617f94d6 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -1163,6 +1163,14 @@ real_isnan (const REAL_VALUE_TYPE *r) return (r->cl == rvc_nan); } +/* Determine whether a floating-point value X is finite. */ + +bool +real_isfinite (const REAL_VALUE_TYPE *r) +{ + return (r->cl != rvc_nan) && (r->cl != rvc_inf); +} + /* Determine whether a floating-point value X is negative. */ bool @@ -4571,7 +4579,7 @@ real_sqrt (REAL_VALUE_TYPE *r, enum machine_mode mode, } /* Infinity and NaN return themselves. */ - if (real_isinf (x) || real_isnan (x)) + if (!real_isfinite (x)) { *r = *x; return false; diff --git a/gcc/real.h b/gcc/real.h index ec5a207cb9c..09b1e52fb2c 100644 --- a/gcc/real.h +++ b/gcc/real.h @@ -192,6 +192,9 @@ extern bool real_isinf (const REAL_VALUE_TYPE *); /* Determine whether a floating-point value X is a NaN. */ extern bool real_isnan (const REAL_VALUE_TYPE *); +/* Determine whether a floating-point value X is finite. */ +extern bool real_isfinite (const REAL_VALUE_TYPE *); + /* Determine whether a floating-point value X is negative. */ extern bool real_isneg (const REAL_VALUE_TYPE *);