This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Patch to rework IEEE floating point checks
- From: Brad Lucier <lucier at math dot purdue dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Cc: lucier at math dot purdue dot edu (Brad Lucier)
- Date: Thu, 28 Feb 2002 16:21:05 -0500 (EST)
- Subject: Re: Patch to rework IEEE floating point checks
> + #ifndef MODE_HAS_INFINITIES
> + #define MODE_HAS_INFINITIES(MODE) MODE_HAS_NANS (MODE)
> + #endif
I think it would be better to just define this as the others:
+ #ifndef MODE_HAS_INFINITIES
+ #define MODE_HAS_INFINITIES(MODE) \
+ (FLOAT_MODE_P (MODE) && TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)
+ #endif
> + /* Like HONOR_NANS, but true if given mode supports sign-dependent rounding,
> + and the rounding mode is important. If this macro is true for the mode
> + of -(x - y), the expression can't be optimized to (y - x). */
> + #define HONOR_SIGN_DEPENDENT_ROUNDING(MODE) \
> + (MODE_HAS_SIGN_DEPENDENT_ROUNDING (MODE) && !flag_unsafe_math_optimizations)
I don't like the example given here, because you can't optimize
- (x - y) to (y - x) even if HONOR_SIGNED_ZEROS since - (0. - 0.) = -0.,
yet (0. - 0.) = 0 with round-to-nearest.
> *************** expand_builtin_mathfn (exp, target, subt
> *** 1530,1546 ****
> return 0;
> }
>
> ! /* If errno must be maintained and if we are not allowing unsafe
> ! math optimizations, check the result. */
>
> ! if (flag_errno_math && ! flag_unsafe_math_optimizations)
> {
> rtx lab1;
> -
> - /* Don't define the builtin FP instructions
> - if your machine is not IEEE. */
> - if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
> - abort ();
>
> lab1 = gen_label_rtx ();
>
> --- 1531,1541 ----
> return 0;
> }
>
> ! /* If errno must be maintained, we must set it to EDOM for NaN results. */
>
> ! if (flag_errno_math && HONOR_NANS (argmode))
> {
> rtx lab1;
>
> lab1 = gen_label_rtx ();
Ths issue here is not just whether EDOM is set for NaN results, but whether
the hardware sin/cos have similar accuracy to the library routines.
Someone might not care about errno or NaNs but still want full accuracy
for sin/cos.
>
> Index: c-common.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
> retrieving revision 1.294
> diff -c -p -d -r1.294 c-common.c
> *** c-common.c 2002/02/22 00:08:59 1.294
> --- c-common.c 2002/02/28 16:56:18
> *************** truthvalue_conversion (expr)
> *** 2203,2212 ****
> break;
>
> case MINUS_EXPR:
> ! /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
> ! this case. */
> ! if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
> ! && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
> break;
> /* fall through... */
> case BIT_XOR_EXPR:
> --- 2203,2213 ----
> break;
>
> case MINUS_EXPR:
> ! /* Perhaps reduce (x - y) != 0 to (x != y). The expressions
> ! aren't guaranteed to the be same for modes that can represent
> ! infinity, since if x and y are both +infinity, or both
> ! -infinity, then x - y is not a number. */
> ! if (HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (TREE_OPERAND (expr, 0)))))
> break;
> /* fall through... */
> case BIT_XOR_EXPR:
Here you have to check whether we HONOR_NANS, too, I think.
> Index: fold-const.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
> retrieving revision 1.185
> diff -c -p -d -r1.185 fold-const.c
> *** fold-const.c 2002/02/22 11:50:47 1.185
> --- fold-const.c 2002/02/28 16:56:20
> *************** fold (expr)
> *** 5588,5596 ****
> same));
> }
> }
> ! /* In IEEE floating point, x+0 may not equal x. */
> ! else if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
> ! || flag_unsafe_math_optimizations)
> && real_zerop (arg1))
> return non_lvalue (convert (type, arg0));
> /* x+(-0) equals x, even for IEEE. */
> --- 5588,5599 ----
> same));
> }
> }
> ! /* Maybe fold x + 0 to x. The expressions are equivalent when x is
> ! NaN, infinite, or non-zero and finite. They aren't equivalent
> ! when x is zero and its mode has signed zeros, unless the rounding
> ! mode is towards -ve infinity. In other rounding modes, (-0) + 0
> ! is 0. */
> ! else if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
> && real_zerop (arg1))
> return non_lvalue (convert (type, arg0));
> /* x+(-0) equals x, even for IEEE. */
This last comment, not part of the patch, caught my eye; it's a case
you missed, x + (-0) equals x unless you have round down. So
else if (TREE_CODE (arg1) == REAL_CST
&& REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (arg1)))
return non_lvalue (convert (type, arg0));
should be changed to something like
else if (TREE_CODE (arg1) == REAL_CST
&& REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (arg1))
&& !(HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MOD (TREE_TYPE (arg1)))))
return non_lvalue (convert (type, arg0));
Nice patch, I learned some things about IEEE arithmetic looking it over.
I didn't check every line, my eyes glazed over after about 1/2 hour.
Brad