This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]