public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Add -fsignaling-nans compiler option
@ 2002-07-22 17:55 Roger Sayle
  2002-07-23 19:33 ` Gabriel Dos Reis
  2002-07-24  7:01 ` Richard Sandiford
  0 siblings, 2 replies; 10+ messages in thread
From: Roger Sayle @ 2002-07-22 17:55 UTC (permalink / raw)
  To: gcc-patches


This patch introduces to "-fsignaling-nans" compiler option to GCC.
This new option, via the flag_signaling_nans global variable disables
optimizations that may produce different observable behaviour in
the presence of IEEE NaNs.  As clarified in the documentation
changes with the patch, this is distinct from flag_trapping_math
which implements the ISO C mandated IEEE exceptions including
division by zero, overflow, underflow, inexact result (2.0/3.0)
and invalid operation (0.0*Inf).  So by default, flag_trapping_math
is true, but flag_signaling_nans is false.

As an example of the distinction "qNaN == qNaN" with does not generate
an IEEE exception with -ftrapping-math, but "sNaN == sNan" does trap
with -fsignaling-nans.

This distinction allows many potentialy unsafe optimizations to
be turned off by -fsignaling-nans, e.g. 1.0*x, and in a few cases
where GCC had err'd on the side of caution enable them outside
of -ffast-math, e.g. -1.0*x into -x.


This patch by no means introduces complete support for signaling
NaNs in GCC, but provides the infrastructure necessary to add new
optimizations to the compiler without (i) being overly conservative
or (ii) making the task of supporting sNaNs at some point in the
future much harder.  Contributors with interest in supporting sNANs
are welcome to conditionalize even more of the exisiting "unsafe"
optimizations.


The patch has been tested with a complete "make bootstrap", all
languages except Ada and treelang, and "make -k check" in the gcc
subdirectory, on i686-pc-linux-gnu with no new regressions.

Ok for mainline?


2002-07-22  Roger Sayle  <roger@eyesopen.com>

	* flags.h [flag_signaling_nans]: New flag.
	* toplev.c [flag_signaling_nans]: Initialize to false.
        (f_options): Add processing for "-fsignaling-nans".
	(set_fast_math_flags): Clear flag_signaling_nans with -ffast-math.

	* c-common.c (cb_register_builtins): Define __SUPPORT_SNAN__
	when -fsignaling-nans.  First step to implementing WG14's N965.

	* fold-const.c (fold) [MULT_EXPR]: Conditionalize transforming
	1.0 * x into x, and -1.0 * x into -x on !flag_signaling_nans.
	[RDIV_EXPR]: Conditionalize x/1.0 into x on !flag_signaling_nans.

	* simplify-rtx.c (simplify_relational_operation): Conditionalize
	transforming abs(x) < 0.0 into false on !flag_signaling_nans.

	* rtlanal.c (may_trap_p): Floating point DIV, MOD, UDIV, UMOD,
	GE, GT, LE, LT and COMPARE may always trap with -fsignaling_nans.
	EQ and NE only trap for flag_signaling_nans not flag_trapping_math.

	* doc/invoke.texi: Document new -fsignaling-nans compiler option.


Index: flags.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flags.h,v
retrieving revision 1.86
diff -c -3 -p -r1.86 flags.h
*** flags.h	25 May 2002 01:56:55 -0000	1.86
--- flags.h	22 Jul 2002 17:10:41 -0000
*************** extern int flag_non_call_exceptions;
*** 663,668 ****
--- 663,671 ----
  /* Nonzero means put zero initialized data in the bss section.  */
  extern int flag_zero_initialized_in_bss;

+ /* Nonzero means disable transformations observable by signaling NaNs.  */
+ extern int flag_signaling_nans;
+
  /* True if the given mode has a NaN representation and the treatment of
     NaN operands is important.  Certain optimizations, such as folding
     x * 0 into x, are not correct for NaN operands, and are normally
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.660
diff -c -3 -p -r1.660 toplev.c
*** toplev.c	22 Jul 2002 00:26:03 -0000	1.660
--- toplev.c	22 Jul 2002 17:10:43 -0000
*************** int flag_unsafe_math_optimizations = 0;
*** 572,581 ****

  /* Zero means that floating-point math operations cannot generate a
     (user-visible) trap.  This is the case, for example, in nonstop
!    IEEE 754 arithmetic.  */

  int flag_trapping_math = 1;

  /* 0 means straightforward implementation of complex divide acceptable.
     1 means wide ranges of inputs must work for complex divide.
     2 means C99-like requirements for complex divide (not yet implemented).  */
--- 572,589 ----

  /* Zero means that floating-point math operations cannot generate a
     (user-visible) trap.  This is the case, for example, in nonstop
!    IEEE 754 arithmetic.  Trapping conditions include division by zero,
!    overflow, underflow, invalid and inexact, but does not include
!    operations on signaling NaNs (see below).  */

  int flag_trapping_math = 1;

+ /* Nonzero means disable transformations observable by signaling NaNs.
+    This option implies that any operation on a IEEE signaling NaN can
+    generate a (user-visible) trap.  */
+
+ int flag_signaling_nans = 0;
+
  /* 0 means straightforward implementation of complex divide acceptable.
     1 means wide ranges of inputs must work for complex divide.
     2 means C99-like requirements for complex divide (not yet implemented).  */
*************** static const lang_independent_options f_
*** 1165,1170 ****
--- 1173,1180 ----
     N_("Floating-point operations can trap") },
    {"unsafe-math-optimizations", &flag_unsafe_math_optimizations, 1,
     N_("Allow math optimizations that may violate IEEE or ANSI standards") },
+   {"signaling-nans", &flag_signaling_nans, 1,
+    N_("Disable optimizations observable by IEEE signaling NaNs") },
    {"bounded-pointers", &flag_bounded_pointers, 1,
     N_("Compile pointers as triples: value, base & end") },
    {"bounds-check", &flag_bounds_check, 1,
*************** set_fast_math_flags (set)
*** 1561,1566 ****
--- 1571,1578 ----
    flag_trapping_math = !set;
    flag_unsafe_math_optimizations = set;
    flag_errno_math = !set;
+   if (set)
+     flag_signaling_nans = 0;
  }

  /* Return true iff flags are set as if -ffast-math.  */
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.348
diff -c -3 -p -r1.348 c-common.c
*** c-common.c	7 Jul 2002 22:10:16 -0000	1.348
--- c-common.c	22 Jul 2002 17:10:44 -0000
*************** cb_register_builtins (pfile)
*** 4353,4358 ****
--- 4353,4360 ----
      cpp_define (pfile, "__FAST_MATH__");
    if (flag_no_inline)
      cpp_define (pfile, "__NO_INLINE__");
+   if (flag_signaling_nans)
+     cpp_define (pfile, "__SUPPORT_SNAN__");

    if (flag_iso)
      cpp_define (pfile, "__STRICT_ANSI__");
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.215
diff -c -3 -p -r1.215 fold-const.c
*** fold-const.c	1 Jul 2002 20:59:00 -0000	1.215
--- fold-const.c	22 Jul 2002 17:10:46 -0000
*************** fold (expr)
*** 5476,5492 ****
  	      && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
  	      && real_zerop (arg1))
  	    return omit_one_operand (type, arg1, arg0);
! 	  /* In IEEE floating point, x*1 is not equivalent to x for snans.
! 	     However, ANSI says we can drop signals,
! 	     so we can do this anyway.  */
! 	  if (real_onep (arg1))
  	    return non_lvalue (convert (type, arg0));

! 	  /* Transform x * -1.0 into -x.  This should be safe for NaNs,
! 	     signed zeros and signed infinities, but is currently
! 	     restricted to "unsafe math optimizations" just in case.  */
! 	  if (flag_unsafe_math_optimizations
! 	      && real_minus_onep (arg1))
  	    return fold (build1 (NEGATE_EXPR, type, arg0));

  	  /* x*2 is x+x */
--- 5476,5487 ----
  	      && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
  	      && real_zerop (arg1))
  	    return omit_one_operand (type, arg1, arg0);
! 	  /* In IEEE floating point, x*1 is not equivalent to x for snans.  */
! 	  if (!flag_signaling_nans && real_onep (arg1))
  	    return non_lvalue (convert (type, arg0));

! 	  /* Transform x * -1.0 into -x.  */
! 	  if (!flag_signaling_nans && real_minus_onep (arg1))
  	    return fold (build1 (NEGATE_EXPR, type, arg0));

  	  /* x*2 is x+x */
*************** fold (expr)
*** 5620,5628 ****
  	return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
  			    TREE_OPERAND (arg1, 0)));

!       /* In IEEE floating point, x/1 is not equivalent to x for snans.
! 	 However, ANSI says we can drop signals, so we can do this anyway.  */
!       if (real_onep (arg1))
  	return non_lvalue (convert (type, arg0));

        /* If ARG1 is a constant, we can convert this to a multiply by the
--- 5615,5622 ----
  	return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
  			    TREE_OPERAND (arg1, 0)));

!       /* In IEEE floating point, x/1 is not equivalent to x for snans.  */
!       if (!flag_signaling_nans && real_onep (arg1))
  	return non_lvalue (convert (type, arg0));

        /* If ARG1 is a constant, we can convert this to a multiply by the
Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.112
diff -c -3 -p -r1.112 simplify-rtx.c
*** simplify-rtx.c	21 Jul 2002 22:01:58 -0000	1.112
--- simplify-rtx.c	22 Jul 2002 17:10:46 -0000
*************** simplify_relational_operation (code, mod
*** 2063,2069 ****

  	case LT:
  	  /* Optimize abs(x) < 0.0.  */
! 	  if (trueop1 == CONST0_RTX (mode))
  	    {
  	      tem = GET_CODE (trueop0) == FLOAT_EXTEND ? XEXP (trueop0, 0)
  						       : trueop0;
--- 2063,2070 ----

  	case LT:
  	  /* Optimize abs(x) < 0.0.  */
! 	  if ((!HONOR_NANS(mode) || !flag_signaling_nans)
! 	      && trueop1 == CONST0_RTX (mode))
  	    {
  	      tem = GET_CODE (trueop0) == FLOAT_EXTEND ? XEXP (trueop0, 0)
  						       : trueop0;
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtlanal.c,v
retrieving revision 1.136
diff -c -3 -p -r1.136 rtlanal.c
*** rtlanal.c	22 Jul 2002 14:29:28 -0000	1.136
--- rtlanal.c	22 Jul 2002 17:10:47 -0000
*************** may_trap_p (x)
*** 2369,2374 ****
--- 2369,2377 ----
      case MOD:
      case UDIV:
      case UMOD:
+       if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
+ 	  && flag_signaling_nans)
+ 	return 1;
        if (! CONSTANT_P (XEXP (x, 1))
  	  || (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
  	      && flag_trapping_math))
*************** may_trap_p (x)
*** 2390,2396 ****
      case LT:
      case COMPARE:
        /* Some floating point comparisons may trap.  */
!       if (!flag_trapping_math)
  	break;
        /* ??? There is no machine independent way to check for tests that trap
  	 when COMPARE is used, though many targets do make this distinction.
--- 2393,2399 ----
      case LT:
      case COMPARE:
        /* Some floating point comparisons may trap.  */
!       if (!flag_trapping_math && !flag_signaling_nans)
  	break;
        /* ??? There is no machine independent way to check for tests that trap
  	 when COMPARE is used, though many targets do make this distinction.
*************** may_trap_p (x)
*** 2405,2410 ****
--- 2408,2420 ----
  	return 1;
        break;

+     case EQ:
+     case NE:
+       if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
+ 	  && flag_signaling_nans)
+ 	return 1;
+       break;
+
      case NEG:
      case ABS:
        /* These operations don't trap even with floating point.  */
*************** may_trap_p (x)
*** 2413,2419 ****
      default:
        /* Any floating arithmetic may trap.  */
        if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
! 	  && flag_trapping_math)
  	return 1;
      }

--- 2423,2429 ----
      default:
        /* Any floating arithmetic may trap.  */
        if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
! 	  && (flag_trapping_math || flag_signaling_nans))
  	return 1;
      }

Index: doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.158
diff -c -3 -p -r1.158 invoke.texi
*** doc/invoke.texi	16 Jul 2002 17:46:33 -0000	1.158
--- doc/invoke.texi	22 Jul 2002 17:10:49 -0000
*************** in the following sections.
*** 280,286 ****
  -freduce-all-givs -fregmove  -frename-registers @gol
  -freorder-blocks -freorder-functions @gol
  -frerun-cse-after-loop  -frerun-loop-opt @gol
! -fschedule-insns  -fschedule-insns2 @gol
  -fsingle-precision-constant  -fssa -fssa-ccp -fssa-dce @gol
  -fstrength-reduce  -fstrict-aliasing  -ftracer -fthread-jumps  -ftrapv @gol
  -funroll-all-loops  -funroll-loops  @gol
--- 280,286 ----
  -freduce-all-givs -fregmove  -frename-registers @gol
  -freorder-blocks -freorder-functions @gol
  -frerun-cse-after-loop  -frerun-loop-opt @gol
! -fschedule-insns  -fschedule-insns2 -fsignaling-nans @gol
  -fsingle-precision-constant  -fssa -fssa-ccp -fssa-dce @gol
  -fstrength-reduce  -fstrict-aliasing  -ftracer -fthread-jumps  -ftrapv @gol
  -funroll-all-loops  -funroll-loops  @gol
*************** performed when this option is not used.
*** 3412,3419 ****

  @item -ffast-math
  @opindex ffast-math
! Sets @option{-fno-math-errno}, @option{-funsafe-math-optimizations}, and @*
! @option{-fno-trapping-math}.

  This option causes the preprocessor macro @code{__FAST_MATH__} to be defined.

--- 3412,3419 ----

  @item -ffast-math
  @opindex ffast-math
! Sets @option{-fno-math-errno}, @option{-funsafe-math-optimizations}, @*
! @option{-fno-trapping-math} and @option{-fno-signaling-nans}.

  This option causes the preprocessor macro @code{__FAST_MATH__} to be defined.

*************** The default is @option{-fno-unsafe-math-
*** 3454,3461 ****
  @item -fno-trapping-math
  @opindex fno-trapping-math
  Compile code assuming that floating-point operations cannot generate
! user-visible traps.  Setting this option may allow faster code
! if one relies on ``non-stop'' IEEE arithmetic, for example.

  This option should never be turned on by any @option{-O} option since
  it can result in incorrect output for programs which depend on
--- 3454,3463 ----
  @item -fno-trapping-math
  @opindex fno-trapping-math
  Compile code assuming that floating-point operations cannot generate
! user-visible traps.  These traps include division by zero, overflow,
! underflow, inexact result and invalid operation.  This option implies
! @option{-fno-signaling-nans}.  Setting this option may allow faster
! code if one relies on ``non-stop'' IEEE arithmetic, for example.

  This option should never be turned on by any @option{-O} option since
  it can result in incorrect output for programs which depend on
*************** an exact implementation of IEEE or ISO r
*** 3463,3468 ****
--- 3465,3482 ----
  math functions.

  The default is @option{-ftrapping-math}.
+
+ @item -fsignaling-nans
+ @opindex fsignaling-nans
+ Compile code assuming that IEEE signaling NaNs may generate user-visible
+ traps during floating-point operations.  Setting this option disables
+ optimizations that may change the number of exceptions visible with
+ signaling NaNs.  This option implies @option{-ftrapping-math}.
+
+ This option causes the preprocessor macro @code{__SUPPORT_SNAN__} to
+ be defined.
+
+ The default is @option{-fno-signaling-nans}.

  @item -fno-zero-initialized-in-bss
  @opindex fno-zero-initialized-in-bss


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Add -fsignaling-nans compiler option
  2002-07-22 17:55 [PATCH] Add -fsignaling-nans compiler option Roger Sayle
@ 2002-07-23 19:33 ` Gabriel Dos Reis
  2002-07-24  7:01 ` Richard Sandiford
  1 sibling, 0 replies; 10+ messages in thread
From: Gabriel Dos Reis @ 2002-07-23 19:33 UTC (permalink / raw)
  To: Roger Sayle; +Cc: gcc-patches, rth

Roger Sayle <roger@eyesopen.com> writes:

[...]

| This patch by no means introduces complete support for signaling
| NaNs in GCC, but provides the infrastructure necessary to add new
| optimizations to the compiler without (i) being overly conservative
| or (ii) making the task of supporting sNaNs at some point in the
| future much harder.  Contributors with interest in supporting sNANs
| are welcome to conditionalize even more of the exisiting "unsafe"
| optimizations.
| 
| 
| The patch has been tested with a complete "make bootstrap", all
| languages except Ada and treelang, and "make -k check" in the gcc
| subdirectory, on i686-pc-linux-gnu with no new regressions.
| 
| Ok for mainline?

This looks good to me. rth?

Thanks,

-- Gaby

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Add -fsignaling-nans compiler option
  2002-07-22 17:55 [PATCH] Add -fsignaling-nans compiler option Roger Sayle
  2002-07-23 19:33 ` Gabriel Dos Reis
@ 2002-07-24  7:01 ` Richard Sandiford
  2002-07-24 18:58   ` [PATCH] Add -fsignaling-nans compiler option (take 2) Roger Sayle
  1 sibling, 1 reply; 10+ messages in thread
From: Richard Sandiford @ 2002-07-24  7:01 UTC (permalink / raw)
  To: Roger Sayle; +Cc: gcc-patches

Roger Sayle <roger@eyesopen.com> writes:
> *** simplify-rtx.c	21 Jul 2002 22:01:58 -0000	1.112
> --- simplify-rtx.c	22 Jul 2002 17:10:46 -0000
> *************** simplify_relational_operation (code, mod
> *** 2063,2069 ****
> 
>   	case LT:
>   	  /* Optimize abs(x) < 0.0.  */
> ! 	  if (trueop1 == CONST0_RTX (mode))
>   	    {
>   	      tem = GET_CODE (trueop0) == FLOAT_EXTEND ? XEXP (trueop0, 0)
>   						       : trueop0;
> --- 2063,2070 ----
> 
>   	case LT:
>   	  /* Optimize abs(x) < 0.0.  */
> ! 	  if ((!HONOR_NANS(mode) || !flag_signaling_nans)
> ! 	      && trueop1 == CONST0_RTX (mode))
>   	    {
>   	      tem = GET_CODE (trueop0) == FLOAT_EXTEND ? XEXP (trueop0, 0)
>   						       : trueop0;

I can see this kind of condition being needed pretty often as people
apply the flag in future.  Maybe worth having a HONOR_SNANS (MODE) macro?

> *************** an exact implementation of IEEE or ISO r
> *** 3463,3468 ****
> --- 3465,3482 ----
>   math functions.
> 
>   The default is @option{-ftrapping-math}.
> +
> + @item -fsignaling-nans
> + @opindex fsignaling-nans
> + Compile code assuming that IEEE signaling NaNs may generate user-visible
> + traps during floating-point operations.  Setting this option disables
> + optimizations that may change the number of exceptions visible with
> + signaling NaNs.  This option implies @option{-ftrapping-math}.
> +
> + This option causes the preprocessor macro @code{__SUPPORT_SNAN__} to
> + be defined.
> +
> + The default is @option{-fno-signaling-nans}.

If I understood correctly, you're not claiming to have caught all
optimisations that are unsafe wrt signalling NaNs.  Might be
worth emphasising that if so.

Richard

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH] Add -fsignaling-nans compiler option (take 2)
  2002-07-24  7:01 ` Richard Sandiford
@ 2002-07-24 18:58   ` Roger Sayle
  2002-07-25 11:43     ` Toon Moene
  2002-07-25 18:32     ` Richard Henderson
  0 siblings, 2 replies; 10+ messages in thread
From: Roger Sayle @ 2002-07-24 18:58 UTC (permalink / raw)
  To: gcc-patches; +Cc: Richard Sandiford


Richard Sandiford wrote:
> I can see this kind of condition being needed pretty often as people
> apply the flag in future.  Maybe worth having a HONOR_SNANS (MODE)
> macro?

That sounds like an excellent idea.  I like the symmetry of using
HONOR_SNANS for "abs(x) < 0.0" and HONOR_NANS for "abs(x) >= 0.0".

> If I understood correctly, you're not claiming to have caught
> all optimisations that are unsafe wrt signalling NaNs.  Might be
> worth emphasising that if so.

And again, another good idea.


The following patch is just a revision of the original against
current mainline sources, introducing and using an HONOR_SNANS
macro, and documents the experimental nature of the new compiler
option.

This revised patch has been retested by a complete bootstrap
of the compiler, all languages except Ada and treelang, and
"make -k check" in the gcc directory, on i686-pc-linux-gnu
with no new regressions.


Ok for mainline?


2002-07-24  Roger Sayle  <roger@eyesopen.com>

	* flags.h [flag_signaling_nans]: New flag.
	[HONOR_SNANS]: New macro.

	* toplev.c [flag_signaling_nans]: Initialize to false.
        (f_options): Add processing for "-fsignaling-nans".
	(set_fast_math_flags): Clear flag_signaling_nans with -ffast-math.

	* c-common.c (cb_register_builtins): Define __SUPPORT_SNAN__
	when -fsignaling-nans.  First step to implementing WG14's N965.

	* fold-const.c (fold) [MULT_EXPR]: Conditionalize transforming
	1.0 * x into x, and -1.0 * x into -x on !flag_signaling_nans.
	[RDIV_EXPR]: Conditionalize x/1.0 into x on !flag_signaling_nans.

	* simplify-rtx.c (simplify_relational_operation): Conditionalize
	transforming abs(x) < 0.0 into false on !flag_signaling_nans.

	* rtlanal.c (may_trap_p): Floating point DIV, MOD, UDIV, UMOD,
	GE, GT, LE, LT and COMPARE may always trap with -fsignaling_nans.
	EQ and NE only trap for flag_signaling_nans not flag_trapping_math.

	* doc/invoke.texi: Document new -fsignaling-nans compiler option.


Index: flags.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flags.h,v
retrieving revision 1.86
diff -c -3 -p -r1.86 flags.h
*** flags.h	25 May 2002 01:56:55 -0000	1.86
--- flags.h	24 Jul 2002 14:51:33 -0000
*************** extern int flag_non_call_exceptions;
*** 663,668 ****
--- 663,671 ----
  /* Nonzero means put zero initialized data in the bss section.  */
  extern int flag_zero_initialized_in_bss;

+ /* Nonzero means disable transformations observable by signaling NaNs.  */
+ extern int flag_signaling_nans;
+
  /* True if the given mode has a NaN representation and the treatment of
     NaN operands is important.  Certain optimizations, such as folding
     x * 0 into x, are not correct for NaN operands, and are normally
*************** extern int flag_zero_initialized_in_bss;
*** 670,675 ****
--- 673,681 ----
     done anyway using the -funsafe-math-optimizations switch.  */
  #define HONOR_NANS(MODE) \
    (MODE_HAS_NANS (MODE) && !flag_unsafe_math_optimizations)
+
+ /* Like HONOR_NANs, but true if we honor signaling NaNs (or sNaNs).  */
+ #define HONOR_SNANS(MODE) (flag_signaling_nans && HONOR_NANS (mode))

  /* As for HONOR_NANS, but true if the mode can represent infinity and
     the treatment of infinite values is important.  */
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.660
diff -c -3 -p -r1.660 toplev.c
*** toplev.c	22 Jul 2002 00:26:03 -0000	1.660
--- toplev.c	24 Jul 2002 14:51:34 -0000
*************** int flag_unsafe_math_optimizations = 0;
*** 572,581 ****

  /* Zero means that floating-point math operations cannot generate a
     (user-visible) trap.  This is the case, for example, in nonstop
!    IEEE 754 arithmetic.  */

  int flag_trapping_math = 1;

  /* 0 means straightforward implementation of complex divide acceptable.
     1 means wide ranges of inputs must work for complex divide.
     2 means C99-like requirements for complex divide (not yet implemented).  */
--- 572,589 ----

  /* Zero means that floating-point math operations cannot generate a
     (user-visible) trap.  This is the case, for example, in nonstop
!    IEEE 754 arithmetic.  Trapping conditions include division by zero,
!    overflow, underflow, invalid and inexact, but does not include
!    operations on signaling NaNs (see below).  */

  int flag_trapping_math = 1;

+ /* Nonzero means disable transformations observable by signaling NaNs.
+    This option implies that any operation on a IEEE signaling NaN can
+    generate a (user-visible) trap.  */
+
+ int flag_signaling_nans = 0;
+
  /* 0 means straightforward implementation of complex divide acceptable.
     1 means wide ranges of inputs must work for complex divide.
     2 means C99-like requirements for complex divide (not yet implemented).  */
*************** static const lang_independent_options f_
*** 1165,1170 ****
--- 1173,1180 ----
     N_("Floating-point operations can trap") },
    {"unsafe-math-optimizations", &flag_unsafe_math_optimizations, 1,
     N_("Allow math optimizations that may violate IEEE or ANSI standards") },
+   {"signaling-nans", &flag_signaling_nans, 1,
+    N_("Disable optimizations observable by IEEE signaling NaNs") },
    {"bounded-pointers", &flag_bounded_pointers, 1,
     N_("Compile pointers as triples: value, base & end") },
    {"bounds-check", &flag_bounds_check, 1,
*************** set_fast_math_flags (set)
*** 1561,1566 ****
--- 1571,1578 ----
    flag_trapping_math = !set;
    flag_unsafe_math_optimizations = set;
    flag_errno_math = !set;
+   if (set)
+     flag_signaling_nans = 0;
  }

  /* Return true iff flags are set as if -ffast-math.  */
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.349
diff -c -3 -p -r1.349 c-common.c
*** c-common.c	23 Jul 2002 13:54:02 -0000	1.349
--- c-common.c	24 Jul 2002 14:51:35 -0000
*************** cb_register_builtins (pfile)
*** 4378,4383 ****
--- 4378,4385 ----
      cpp_define (pfile, "__FAST_MATH__");
    if (flag_no_inline)
      cpp_define (pfile, "__NO_INLINE__");
+   if (flag_signaling_nans)
+     cpp_define (pfile, "__SUPPORT_SNAN__");

    if (flag_iso)
      cpp_define (pfile, "__STRICT_ANSI__");
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.215
diff -c -3 -p -r1.215 fold-const.c
*** fold-const.c	1 Jul 2002 20:59:00 -0000	1.215
--- fold-const.c	24 Jul 2002 14:51:37 -0000
*************** fold (expr)
*** 5476,5492 ****
  	      && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
  	      && real_zerop (arg1))
  	    return omit_one_operand (type, arg1, arg0);
! 	  /* In IEEE floating point, x*1 is not equivalent to x for snans.
! 	     However, ANSI says we can drop signals,
! 	     so we can do this anyway.  */
! 	  if (real_onep (arg1))
  	    return non_lvalue (convert (type, arg0));

! 	  /* Transform x * -1.0 into -x.  This should be safe for NaNs,
! 	     signed zeros and signed infinities, but is currently
! 	     restricted to "unsafe math optimizations" just in case.  */
! 	  if (flag_unsafe_math_optimizations
! 	      && real_minus_onep (arg1))
  	    return fold (build1 (NEGATE_EXPR, type, arg0));

  	  /* x*2 is x+x */
--- 5476,5487 ----
  	      && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
  	      && real_zerop (arg1))
  	    return omit_one_operand (type, arg1, arg0);
! 	  /* In IEEE floating point, x*1 is not equivalent to x for snans.  */
! 	  if (!flag_signaling_nans && real_onep (arg1))
  	    return non_lvalue (convert (type, arg0));

! 	  /* Transform x * -1.0 into -x.  */
! 	  if (!flag_signaling_nans && real_minus_onep (arg1))
  	    return fold (build1 (NEGATE_EXPR, type, arg0));

  	  /* x*2 is x+x */
*************** fold (expr)
*** 5620,5628 ****
  	return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
  			    TREE_OPERAND (arg1, 0)));

!       /* In IEEE floating point, x/1 is not equivalent to x for snans.
! 	 However, ANSI says we can drop signals, so we can do this anyway.  */
!       if (real_onep (arg1))
  	return non_lvalue (convert (type, arg0));

        /* If ARG1 is a constant, we can convert this to a multiply by the
--- 5615,5622 ----
  	return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
  			    TREE_OPERAND (arg1, 0)));

!       /* In IEEE floating point, x/1 is not equivalent to x for snans.  */
!       if (!flag_signaling_nans && real_onep (arg1))
  	return non_lvalue (convert (type, arg0));

        /* If ARG1 is a constant, we can convert this to a multiply by the
Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.114
diff -c -3 -p -r1.114 simplify-rtx.c
*** simplify-rtx.c	23 Jul 2002 20:06:44 -0000	1.114
--- simplify-rtx.c	24 Jul 2002 14:51:38 -0000
*************** simplify_relational_operation (code, mod
*** 2063,2069 ****

  	case LT:
  	  /* Optimize abs(x) < 0.0.  */
! 	  if (trueop1 == CONST0_RTX (mode))
  	    {
  	      tem = GET_CODE (trueop0) == FLOAT_EXTEND ? XEXP (trueop0, 0)
  						       : trueop0;
--- 2063,2069 ----

  	case LT:
  	  /* Optimize abs(x) < 0.0.  */
! 	  if (trueop1 == CONST0_RTX (mode) && !HONOR_SNANS (mode))
  	    {
  	      tem = GET_CODE (trueop0) == FLOAT_EXTEND ? XEXP (trueop0, 0)
  						       : trueop0;
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtlanal.c,v
retrieving revision 1.136
diff -c -3 -p -r1.136 rtlanal.c
*** rtlanal.c	22 Jul 2002 14:29:28 -0000	1.136
--- rtlanal.c	24 Jul 2002 14:51:38 -0000
*************** may_trap_p (x)
*** 2369,2374 ****
--- 2369,2377 ----
      case MOD:
      case UDIV:
      case UMOD:
+       if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
+ 	  && flag_signaling_nans)
+ 	return 1;
        if (! CONSTANT_P (XEXP (x, 1))
  	  || (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
  	      && flag_trapping_math))
*************** may_trap_p (x)
*** 2390,2396 ****
      case LT:
      case COMPARE:
        /* Some floating point comparisons may trap.  */
!       if (!flag_trapping_math)
  	break;
        /* ??? There is no machine independent way to check for tests that trap
  	 when COMPARE is used, though many targets do make this distinction.
--- 2393,2399 ----
      case LT:
      case COMPARE:
        /* Some floating point comparisons may trap.  */
!       if (!flag_trapping_math && !flag_signaling_nans)
  	break;
        /* ??? There is no machine independent way to check for tests that trap
  	 when COMPARE is used, though many targets do make this distinction.
*************** may_trap_p (x)
*** 2405,2410 ****
--- 2408,2420 ----
  	return 1;
        break;

+     case EQ:
+     case NE:
+       if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
+ 	  && flag_signaling_nans)
+ 	return 1;
+       break;
+
      case NEG:
      case ABS:
        /* These operations don't trap even with floating point.  */
*************** may_trap_p (x)
*** 2413,2419 ****
      default:
        /* Any floating arithmetic may trap.  */
        if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
! 	  && flag_trapping_math)
  	return 1;
      }

--- 2423,2429 ----
      default:
        /* Any floating arithmetic may trap.  */
        if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
! 	  && (flag_trapping_math || flag_signaling_nans))
  	return 1;
      }

Index: doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.159
diff -c -3 -p -r1.159 invoke.texi
*** doc/invoke.texi	23 Jul 2002 15:52:02 -0000	1.159
--- doc/invoke.texi	24 Jul 2002 14:51:42 -0000
*************** in the following sections.
*** 280,286 ****
  -freduce-all-givs -fregmove  -frename-registers @gol
  -freorder-blocks -freorder-functions @gol
  -frerun-cse-after-loop  -frerun-loop-opt @gol
! -fschedule-insns  -fschedule-insns2 @gol
  -fsingle-precision-constant  -fssa -fssa-ccp -fssa-dce @gol
  -fstrength-reduce  -fstrict-aliasing  -ftracer -fthread-jumps  -ftrapv @gol
  -funroll-all-loops  -funroll-loops  @gol
--- 280,286 ----
  -freduce-all-givs -fregmove  -frename-registers @gol
  -freorder-blocks -freorder-functions @gol
  -frerun-cse-after-loop  -frerun-loop-opt @gol
! -fschedule-insns  -fschedule-insns2 -fsignaling-nans @gol
  -fsingle-precision-constant  -fssa -fssa-ccp -fssa-dce @gol
  -fstrength-reduce  -fstrict-aliasing  -ftracer -fthread-jumps  -ftrapv @gol
  -funroll-all-loops  -funroll-loops  @gol
*************** performed when this option is not used.
*** 3412,3419 ****

  @item -ffast-math
  @opindex ffast-math
! Sets @option{-fno-math-errno}, @option{-funsafe-math-optimizations}, and @*
! @option{-fno-trapping-math}.

  This option causes the preprocessor macro @code{__FAST_MATH__} to be defined.

--- 3412,3419 ----

  @item -ffast-math
  @opindex ffast-math
! Sets @option{-fno-math-errno}, @option{-funsafe-math-optimizations}, @*
! @option{-fno-trapping-math} and @option{-fno-signaling-nans}.

  This option causes the preprocessor macro @code{__FAST_MATH__} to be defined.

*************** The default is @option{-fno-unsafe-math-
*** 3454,3461 ****
  @item -fno-trapping-math
  @opindex fno-trapping-math
  Compile code assuming that floating-point operations cannot generate
! user-visible traps.  Setting this option may allow faster code
! if one relies on ``non-stop'' IEEE arithmetic, for example.

  This option should never be turned on by any @option{-O} option since
  it can result in incorrect output for programs which depend on
--- 3454,3463 ----
  @item -fno-trapping-math
  @opindex fno-trapping-math
  Compile code assuming that floating-point operations cannot generate
! user-visible traps.  These traps include division by zero, overflow,
! underflow, inexact result and invalid operation.  This option implies
! @option{-fno-signaling-nans}.  Setting this option may allow faster
! code if one relies on ``non-stop'' IEEE arithmetic, for example.

  This option should never be turned on by any @option{-O} option since
  it can result in incorrect output for programs which depend on
*************** an exact implementation of IEEE or ISO r
*** 3463,3468 ****
--- 3465,3485 ----
  math functions.

  The default is @option{-ftrapping-math}.
+
+ @item -fsignaling-nans
+ @opindex fsignaling-nans
+ Compile code assuming that IEEE signaling NaNs may generate user-visible
+ traps during floating-point operations.  Setting this option disables
+ optimizations that may change the number of exceptions visible with
+ signaling NaNs.  This option implies @option{-ftrapping-math}.
+
+ This option causes the preprocessor macro @code{__SUPPORT_SNAN__} to
+ be defined.
+
+ The default is @option{-fno-signaling-nans}.
+
+ This option is experimental and does not currently guarantee to
+ disable all GCC optimizations that affect signaling NaN behavior.

  @item -fno-zero-initialized-in-bss
  @opindex fno-zero-initialized-in-bss

Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Add -fsignaling-nans compiler option (take 2)
  2002-07-24 18:58   ` [PATCH] Add -fsignaling-nans compiler option (take 2) Roger Sayle
@ 2002-07-25 11:43     ` Toon Moene
  2002-07-25 12:03       ` Gabriel Dos Reis
  2002-07-25 18:32     ` Richard Henderson
  1 sibling, 1 reply; 10+ messages in thread
From: Toon Moene @ 2002-07-25 11:43 UTC (permalink / raw)
  To: Roger Sayle; +Cc: gcc-patches, Richard Sandiford

Roger Sayle wrote:

> Richard Sandiford wrote:

> > If I understood correctly, you're not claiming to have caught
> > all optimisations that are unsafe wrt signalling NaNs.  Might be
> > worth emphasising that if so.

> And again, another good idea.
> 
> The following patch is just a revision of the original against
> current mainline sources, introducing and using an HONOR_SNANS
> macro, and documents the experimental nature of the new compiler
> option.

May I endorse this patch, especially because I want to build upon it and as
Mark Mitchell has indicated, the day of judgement is soon at hand :-)

Thanks,

-- 
Toon Moene - mailto:toon@moene.indiv.nluug.nl - phoneto: +31 346 214290
Saturnushof 14, 3738 XG  Maartensdijk, The Netherlands
Maintainer, GNU Fortran 77: http://gcc.gnu.org/onlinedocs/g77_news.html
Join GNU Fortran 95: http://g95.sourceforge.net/ (under construction)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Add -fsignaling-nans compiler option (take 2)
  2002-07-25 11:43     ` Toon Moene
@ 2002-07-25 12:03       ` Gabriel Dos Reis
  0 siblings, 0 replies; 10+ messages in thread
From: Gabriel Dos Reis @ 2002-07-25 12:03 UTC (permalink / raw)
  To: Toon Moene; +Cc: Roger Sayle, gcc-patches, Richard Sandiford, rth

Toon Moene <toon@moene.indiv.nluug.nl> writes:

| Roger Sayle wrote:
| 
| > Richard Sandiford wrote:
| 
| > > If I understood correctly, you're not claiming to have caught
| > > all optimisations that are unsafe wrt signalling NaNs.  Might be
| > > worth emphasising that if so.
| 
| > And again, another good idea.
| > 
| > The following patch is just a revision of the original against
| > current mainline sources, introducing and using an HONOR_SNANS
| > macro, and documents the experimental nature of the new compiler
| > option.
| 
| May I endorse this patch, especially because I want to build upon it and as
| Mark Mitchell has indicated, the day of judgement is soon at hand :-)

I think, we're at least three persons interested in this patch.  I
would like it to be approved for mainline.  rth, Mark?

-- Gaby

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Add -fsignaling-nans compiler option (take 2)
  2002-07-24 18:58   ` [PATCH] Add -fsignaling-nans compiler option (take 2) Roger Sayle
  2002-07-25 11:43     ` Toon Moene
@ 2002-07-25 18:32     ` Richard Henderson
  2002-07-25 20:13       ` [PATCH] Add -fsignaling-nans compiler option (take 3) Roger Sayle
  1 sibling, 1 reply; 10+ messages in thread
From: Richard Henderson @ 2002-07-25 18:32 UTC (permalink / raw)
  To: Roger Sayle; +Cc: gcc-patches, Richard Sandiford

On Wed, Jul 24, 2002 at 06:30:35PM -0600, Roger Sayle wrote:
> ! 	  /* In IEEE floating point, x*1 is not equivalent to x for snans.  */
> ! 	  if (!flag_signaling_nans && real_onep (arg1))
>   	    return non_lvalue (convert (type, arg0));

Probably every place you currently check flag_signalling_nans,
you should be using HONOR_SNANS.

> -       if (!flag_trapping_math)
> +       if (!flag_trapping_math && !flag_signaling_nans)

If flag_signaling_nans implies flag_trapping_math, as
documented, these changes aren't needed.


r~

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH] Add -fsignaling-nans compiler option (take 3)
  2002-07-25 18:32     ` Richard Henderson
@ 2002-07-25 20:13       ` Roger Sayle
  2002-07-27 13:11         ` Richard Henderson
  0 siblings, 1 reply; 10+ messages in thread
From: Roger Sayle @ 2002-07-25 20:13 UTC (permalink / raw)
  To: Richard Henderson; +Cc: gcc-patches, Richard Sandiford


On Thu, 25 Jul 2002, Richard Henderson wrote:
> On Wed, Jul 24, 2002 at 06:30:35PM -0600, Roger Sayle wrote:
> > ! 	  /* In IEEE floating point, x*1 is not equivalent to x for snans.  */
> > ! 	  if (!flag_signaling_nans && real_onep (arg1))
> >   	    return non_lvalue (convert (type, arg0));
>
> Probably every place you currently check flag_signalling_nans,
> you should be using HONOR_SNANS.

Interestingly, Richard Sandiford suggested exactly this in a private
e-mail this morning.  The bootstrap and make check completed just as
I was reading your message.

The HONOR_NANS and HONOR_SNANS in flags.h are actually defined
in terms of the TARGET_FLOAT_* macros, and therefore also require
real.h.  Changing the usage of flag_signaling_nans in rtlanal.c
therefore required #include "real.h", and a change to Makefile.in
to add the new dependency.

It also uncovered a typo in the previous version of this patch
where HONOR_SNANS used "mode" instead of its argument "MODE".


> > -       if (!flag_trapping_math)
> > +       if (!flag_trapping_math && !flag_signaling_nans)
>
> If flag_signaling_nans implies flag_trapping_math, as
> documented, these changes aren't needed.

The documentation actually says that "-fsignaling-nans" implies
"-ftrapping-math".  I wasn't sure where the appropriate place to
enforce flag_signaling_math implying flag_trapping_math was in
toplev.c, which is why the documented semantics are actually
implemented by also testing flag_signaling_nans everywhere we
currently test flag_trapping_math (as the quoted line above).


The following patch has been tested by a complete bootstrap, all
languages except Ada and treelang, and "make -k check" in the gcc
subdirectory on i686-pc-linux-gnu with no new regressions.


Is this revision OK for mainline?


2002-07-25  Roger Sayle  <roger@eyesopen.com>

	* Makefile.in: rtlanal.o now depends upon real.h.

	* flags.h [flag_signaling_nans]: New flag.
	[HONOR_SNANS]: New macro.

	* toplev.c [flag_signaling_nans]: Initialize to false.
        (f_options): Add processing for "-fsignaling-nans".
	(set_fast_math_flags): Clear flag_signaling_nans with -ffast-math.

	* c-common.c (cb_register_builtins): Define __SUPPORT_SNAN__
	when -fsignaling-nans.  First step to implementing WG14's N965.

	* fold-const.c (fold) [MULT_EXPR]: Conditionalize transforming
	1.0 * x into x, and -1.0 * x into -x on !flag_signaling_nans.
	[RDIV_EXPR]: Conditionalize x/1.0 into x on !flag_signaling_nans.

	* simplify-rtx.c (simplify_relational_operation): Conditionalize
	transforming abs(x) < 0.0 into false on !flag_signaling_nans.

	* rtlanal.c: #include real.c for TARGET_FLOAT_FORMAT definitions
	required by HONOR_SNANS.  (may_trap_p): Floating point DIV, MOD,
	UDIV, UMOD, GE, GT, LE, LT and COMPARE may always trap with
	-fsignaling_nans.  EQ and NE only trap for flag_signaling_nans
	not flag_trapping_math.

	* doc/invoke.texi: Document new -fsignaling-nans compiler option.


Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.912
diff -c -3 -p -r1.912 Makefile.in
*** Makefile.in	17 Jul 2002 00:09:10 -0000	1.912
--- Makefile.in	26 Jul 2002 01:57:46 -0000
*************** print-rtl.o : print-rtl.c $(GCONFIG_H) $
*** 1401,1407 ****
  	$(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)

  rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) toplev.h $(RTL_H) \
!    hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) flags.h

  errors.o : errors.c $(GCONFIG_H) $(SYSTEM_H) errors.h
  	$(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
--- 1401,1407 ----
  	$(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)

  rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) toplev.h $(RTL_H) \
!    hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) real.h flags.h

  errors.o : errors.c $(GCONFIG_H) $(SYSTEM_H) errors.h
  	$(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
Index: flags.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flags.h,v
retrieving revision 1.86
diff -c -3 -p -r1.86 flags.h
*** flags.h	25 May 2002 01:56:55 -0000	1.86
--- flags.h	26 Jul 2002 01:57:46 -0000
*************** extern int flag_non_call_exceptions;
*** 663,668 ****
--- 663,671 ----
  /* Nonzero means put zero initialized data in the bss section.  */
  extern int flag_zero_initialized_in_bss;

+ /* Nonzero means disable transformations observable by signaling NaNs.  */
+ extern int flag_signaling_nans;
+
  /* True if the given mode has a NaN representation and the treatment of
     NaN operands is important.  Certain optimizations, such as folding
     x * 0 into x, are not correct for NaN operands, and are normally
*************** extern int flag_zero_initialized_in_bss;
*** 670,675 ****
--- 673,681 ----
     done anyway using the -funsafe-math-optimizations switch.  */
  #define HONOR_NANS(MODE) \
    (MODE_HAS_NANS (MODE) && !flag_unsafe_math_optimizations)
+
+ /* Like HONOR_NANs, but true if we honor signaling NaNs (or sNaNs).  */
+ #define HONOR_SNANS(MODE) (flag_signaling_nans && HONOR_NANS (MODE))

  /* As for HONOR_NANS, but true if the mode can represent infinity and
     the treatment of infinite values is important.  */
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.662
diff -c -3 -p -r1.662 toplev.c
*** toplev.c	25 Jul 2002 10:15:56 -0000	1.662
--- toplev.c	26 Jul 2002 01:57:47 -0000
*************** int flag_unsafe_math_optimizations = 0;
*** 577,586 ****

  /* Zero means that floating-point math operations cannot generate a
     (user-visible) trap.  This is the case, for example, in nonstop
!    IEEE 754 arithmetic.  */

  int flag_trapping_math = 1;

  /* 0 means straightforward implementation of complex divide acceptable.
     1 means wide ranges of inputs must work for complex divide.
     2 means C99-like requirements for complex divide (not yet implemented).  */
--- 577,594 ----

  /* Zero means that floating-point math operations cannot generate a
     (user-visible) trap.  This is the case, for example, in nonstop
!    IEEE 754 arithmetic.  Trapping conditions include division by zero,
!    overflow, underflow, invalid and inexact, but does not include
!    operations on signaling NaNs (see below).  */

  int flag_trapping_math = 1;

+ /* Nonzero means disable transformations observable by signaling NaNs.
+    This option implies that any operation on a IEEE signaling NaN can
+    generate a (user-visible) trap.  */
+
+ int flag_signaling_nans = 0;
+
  /* 0 means straightforward implementation of complex divide acceptable.
     1 means wide ranges of inputs must work for complex divide.
     2 means C99-like requirements for complex divide (not yet implemented).  */
*************** static const lang_independent_options f_
*** 1170,1175 ****
--- 1178,1185 ----
     N_("Floating-point operations can trap") },
    {"unsafe-math-optimizations", &flag_unsafe_math_optimizations, 1,
     N_("Allow math optimizations that may violate IEEE or ANSI standards") },
+   {"signaling-nans", &flag_signaling_nans, 1,
+    N_("Disable optimizations observable by IEEE signaling NaNs") },
    {"bounded-pointers", &flag_bounded_pointers, 1,
     N_("Compile pointers as triples: value, base & end") },
    {"bounds-check", &flag_bounds_check, 1,
*************** set_fast_math_flags (set)
*** 1566,1571 ****
--- 1576,1583 ----
    flag_trapping_math = !set;
    flag_unsafe_math_optimizations = set;
    flag_errno_math = !set;
+   if (set)
+     flag_signaling_nans = 0;
  }

  /* Return true iff flags are set as if -ffast-math.  */
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.350
diff -c -3 -p -r1.350 c-common.c
*** c-common.c	25 Jul 2002 08:58:01 -0000	1.350
--- c-common.c	26 Jul 2002 01:57:48 -0000
*************** cb_register_builtins (pfile)
*** 4383,4388 ****
--- 4383,4390 ----
      cpp_define (pfile, "__FAST_MATH__");
    if (flag_no_inline)
      cpp_define (pfile, "__NO_INLINE__");
+   if (flag_signaling_nans)
+     cpp_define (pfile, "__SUPPORT_SNAN__");

    if (flag_iso)
      cpp_define (pfile, "__STRICT_ANSI__");
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.215
diff -c -3 -p -r1.215 fold-const.c
*** fold-const.c	1 Jul 2002 20:59:00 -0000	1.215
--- fold-const.c	26 Jul 2002 01:57:50 -0000
*************** fold (expr)
*** 5476,5491 ****
  	      && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
  	      && real_zerop (arg1))
  	    return omit_one_operand (type, arg1, arg0);
! 	  /* In IEEE floating point, x*1 is not equivalent to x for snans.
! 	     However, ANSI says we can drop signals,
! 	     so we can do this anyway.  */
! 	  if (real_onep (arg1))
  	    return non_lvalue (convert (type, arg0));

! 	  /* Transform x * -1.0 into -x.  This should be safe for NaNs,
! 	     signed zeros and signed infinities, but is currently
! 	     restricted to "unsafe math optimizations" just in case.  */
! 	  if (flag_unsafe_math_optimizations
  	      && real_minus_onep (arg1))
  	    return fold (build1 (NEGATE_EXPR, type, arg0));

--- 5476,5488 ----
  	      && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
  	      && real_zerop (arg1))
  	    return omit_one_operand (type, arg1, arg0);
! 	  /* In IEEE floating point, x*1 is not equivalent to x for snans.  */
! 	  if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
! 	      && real_onep (arg1))
  	    return non_lvalue (convert (type, arg0));

! 	  /* Transform x * -1.0 into -x.  */
! 	  if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
  	      && real_minus_onep (arg1))
  	    return fold (build1 (NEGATE_EXPR, type, arg0));

*************** fold (expr)
*** 5620,5628 ****
  	return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
  			    TREE_OPERAND (arg1, 0)));

!       /* In IEEE floating point, x/1 is not equivalent to x for snans.
! 	 However, ANSI says we can drop signals, so we can do this anyway.  */
!       if (real_onep (arg1))
  	return non_lvalue (convert (type, arg0));

        /* If ARG1 is a constant, we can convert this to a multiply by the
--- 5617,5625 ----
  	return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
  			    TREE_OPERAND (arg1, 0)));

!       /* In IEEE floating point, x/1 is not equivalent to x for snans.  */
!       if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
! 	  && real_onep (arg1))
  	return non_lvalue (convert (type, arg0));

        /* If ARG1 is a constant, we can convert this to a multiply by the
Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.115
diff -c -3 -p -r1.115 simplify-rtx.c
*** simplify-rtx.c	25 Jul 2002 09:25:14 -0000	1.115
--- simplify-rtx.c	26 Jul 2002 01:57:50 -0000
*************** simplify_relational_operation (code, mod
*** 2063,2069 ****

  	case LT:
  	  /* Optimize abs(x) < 0.0.  */
! 	  if (trueop1 == CONST0_RTX (mode))
  	    {
  	      tem = GET_CODE (trueop0) == FLOAT_EXTEND ? XEXP (trueop0, 0)
  						       : trueop0;
--- 2063,2069 ----

  	case LT:
  	  /* Optimize abs(x) < 0.0.  */
! 	  if (trueop1 == CONST0_RTX (mode) && !HONOR_SNANS (mode))
  	    {
  	      tem = GET_CODE (trueop0) == FLOAT_EXTEND ? XEXP (trueop0, 0)
  						       : trueop0;
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtlanal.c,v
retrieving revision 1.137
diff -c -3 -p -r1.137 rtlanal.c
*** rtlanal.c	24 Jul 2002 15:24:34 -0000	1.137
--- rtlanal.c	26 Jul 2002 01:57:50 -0000
*************** Software Foundation, 59 Temple Place - S
*** 30,35 ****
--- 30,36 ----
  #include "tm_p.h"
  #include "flags.h"
  #include "basic-block.h"
+ #include "real.h"

  /* Forward declarations */
  static int global_reg_mentioned_p_1 PARAMS ((rtx *, void *));
*************** may_trap_p (x)
*** 2369,2374 ****
--- 2370,2377 ----
      case MOD:
      case UDIV:
      case UMOD:
+       if (HONOR_SNANS (GET_MODE (x)))
+ 	return 1;
        if (! CONSTANT_P (XEXP (x, 1))
  	  || (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
  	      && flag_trapping_math))
*************** may_trap_p (x)
*** 2390,2407 ****
      case LT:
      case COMPARE:
        /* Some floating point comparisons may trap.  */
!       if (!flag_trapping_math)
  	break;
        /* ??? There is no machine independent way to check for tests that trap
  	 when COMPARE is used, though many targets do make this distinction.
  	 For instance, sparc uses CCFPE for compares which generate exceptions
  	 and CCFP for compares which do not generate exceptions.  */
!       if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
  	return 1;
        /* But often the compare has some CC mode, so check operand
  	 modes as well.  */
!       if (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) == MODE_FLOAT
! 	  || GET_MODE_CLASS (GET_MODE (XEXP (x, 1))) == MODE_FLOAT)
  	return 1;
        break;

--- 2393,2420 ----
      case LT:
      case COMPARE:
        /* Some floating point comparisons may trap.  */
!       if (!flag_trapping_math && !flag_signaling_nans)
  	break;
        /* ??? There is no machine independent way to check for tests that trap
  	 when COMPARE is used, though many targets do make this distinction.
  	 For instance, sparc uses CCFPE for compares which generate exceptions
  	 and CCFP for compares which do not generate exceptions.  */
!       if (HONOR_NANS (GET_MODE (x)))
  	return 1;
        /* But often the compare has some CC mode, so check operand
  	 modes as well.  */
!       if (HONOR_NANS (GET_MODE (XEXP (x, 0)))
! 	  || HONOR_NANS (GET_MODE (XEXP (x, 1))))
! 	return 1;
!       break;
!
!     case EQ:
!     case NE:
!       if (HONOR_SNANS (GET_MODE (x)))
! 	return 1;
!       /* Often comparison is CC mode, so check operand modes.  */
!       if (HONOR_SNANS (GET_MODE (XEXP (x, 0)))
! 	  || HONOR_SNANS (GET_MODE (XEXP (x, 1))))
  	return 1;
        break;

*************** may_trap_p (x)
*** 2413,2419 ****
      default:
        /* Any floating arithmetic may trap.  */
        if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
! 	  && flag_trapping_math)
  	return 1;
      }

--- 2426,2432 ----
      default:
        /* Any floating arithmetic may trap.  */
        if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
! 	  && (flag_trapping_math || flag_signaling_nans))
  	return 1;
      }

Index: doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.161
diff -c -3 -p -r1.161 invoke.texi
*** doc/invoke.texi	25 Jul 2002 10:15:58 -0000	1.161
--- doc/invoke.texi	26 Jul 2002 01:57:53 -0000
*************** in the following sections.
*** 280,286 ****
  -freduce-all-givs -fregmove  -frename-registers @gol
  -freorder-blocks -freorder-functions @gol
  -frerun-cse-after-loop  -frerun-loop-opt @gol
! -fschedule-insns  -fschedule-insns2 @gol
  -fsingle-precision-constant  -fssa -fssa-ccp -fssa-dce @gol
  -fstrength-reduce  -fstrict-aliasing  -ftracer -fthread-jumps  -ftrapv @gol
  -funroll-all-loops  -funroll-loops  @gol
--- 280,286 ----
  -freduce-all-givs -fregmove  -frename-registers @gol
  -freorder-blocks -freorder-functions @gol
  -frerun-cse-after-loop  -frerun-loop-opt @gol
! -fschedule-insns  -fschedule-insns2 -fsignaling-nans @gol
  -fsingle-precision-constant  -fssa -fssa-ccp -fssa-dce @gol
  -fstrength-reduce  -fstrict-aliasing  -ftracer -fthread-jumps  -ftrapv @gol
  -funroll-all-loops  -funroll-loops  @gol
*************** performed when this option is not used.
*** 3414,3421 ****

  @item -ffast-math
  @opindex ffast-math
! Sets @option{-fno-math-errno}, @option{-funsafe-math-optimizations}, and @*
! @option{-fno-trapping-math}.

  This option causes the preprocessor macro @code{__FAST_MATH__} to be defined.

--- 3414,3421 ----

  @item -ffast-math
  @opindex ffast-math
! Sets @option{-fno-math-errno}, @option{-funsafe-math-optimizations}, @*
! @option{-fno-trapping-math} and @option{-fno-signaling-nans}.

  This option causes the preprocessor macro @code{__FAST_MATH__} to be defined.

*************** The default is @option{-fno-unsafe-math-
*** 3456,3463 ****
  @item -fno-trapping-math
  @opindex fno-trapping-math
  Compile code assuming that floating-point operations cannot generate
! user-visible traps.  Setting this option may allow faster code
! if one relies on ``non-stop'' IEEE arithmetic, for example.

  This option should never be turned on by any @option{-O} option since
  it can result in incorrect output for programs which depend on
--- 3456,3465 ----
  @item -fno-trapping-math
  @opindex fno-trapping-math
  Compile code assuming that floating-point operations cannot generate
! user-visible traps.  These traps include division by zero, overflow,
! underflow, inexact result and invalid operation.  This option implies
! @option{-fno-signaling-nans}.  Setting this option may allow faster
! code if one relies on ``non-stop'' IEEE arithmetic, for example.

  This option should never be turned on by any @option{-O} option since
  it can result in incorrect output for programs which depend on
*************** an exact implementation of IEEE or ISO r
*** 3465,3470 ****
--- 3467,3487 ----
  math functions.

  The default is @option{-ftrapping-math}.
+
+ @item -fsignaling-nans
+ @opindex fsignaling-nans
+ Compile code assuming that IEEE signaling NaNs may generate user-visible
+ traps during floating-point operations.  Setting this option disables
+ optimizations that may change the number of exceptions visible with
+ signaling NaNs.  This option implies @option{-ftrapping-math}.
+
+ This option causes the preprocessor macro @code{__SUPPORT_SNAN__} to
+ be defined.
+
+ The default is @option{-fno-signaling-nans}.
+
+ This option is experimental and does not currently guarantee to
+ disable all GCC optimizations that affect signaling NaN behavior.

  @item -fno-zero-initialized-in-bss
  @opindex fno-zero-initialized-in-bss

Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Add -fsignaling-nans compiler option (take 3)
  2002-07-25 20:13       ` [PATCH] Add -fsignaling-nans compiler option (take 3) Roger Sayle
@ 2002-07-27 13:11         ` Richard Henderson
  2002-07-28  1:55           ` Roger Sayle
  0 siblings, 1 reply; 10+ messages in thread
From: Richard Henderson @ 2002-07-27 13:11 UTC (permalink / raw)
  To: Roger Sayle; +Cc: gcc-patches, Richard Sandiford

On Thu, Jul 25, 2002 at 08:16:46PM -0600, Roger Sayle wrote:
> > If flag_signaling_nans implies flag_trapping_math, as
> > documented, these changes aren't needed.
> 
> The documentation actually says that "-fsignaling-nans" implies
> "-ftrapping-math".

A distinction without a difference.

> I wasn't sure where the appropriate place to enforce flag_signaling_math
> implying flag_trapping_math was in toplev.c...

In process_options.  You'll see a lot of that sort of thing there
at the top of that function.

> Is this revision OK for mainline?

With the flag_signaling_math -> flag_trapping_math change, yes.


r~

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Add -fsignaling-nans compiler option (take 3)
  2002-07-27 13:11         ` Richard Henderson
@ 2002-07-28  1:55           ` Roger Sayle
  0 siblings, 0 replies; 10+ messages in thread
From: Roger Sayle @ 2002-07-28  1:55 UTC (permalink / raw)
  To: Richard Henderson; +Cc: gcc-patches, Richard Sandiford


Hi Richard,
> > Is this revision OK for mainline?
>
> With the flag_signaling_math -> flag_trapping_math change, yes.

Many thanks.  I've applied the patch with your suggested changes:
process_options sets flag_trapping_math when flag_signaling_nans
is enabled, and the two places where flag_signaling_nans was tested
in addition to flag_trapping_math have been simplified (checking
just flag_trapping_math).  I bootstrapped and regression tested
on i686-pc-linux-gnu prior to commiting to ensure there were no
unexpected problems.

Many thanks once again.

Roger
--

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2002-07-28  2:44 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-07-22 17:55 [PATCH] Add -fsignaling-nans compiler option Roger Sayle
2002-07-23 19:33 ` Gabriel Dos Reis
2002-07-24  7:01 ` Richard Sandiford
2002-07-24 18:58   ` [PATCH] Add -fsignaling-nans compiler option (take 2) Roger Sayle
2002-07-25 11:43     ` Toon Moene
2002-07-25 12:03       ` Gabriel Dos Reis
2002-07-25 18:32     ` Richard Henderson
2002-07-25 20:13       ` [PATCH] Add -fsignaling-nans compiler option (take 3) Roger Sayle
2002-07-27 13:11         ` Richard Henderson
2002-07-28  1:55           ` Roger Sayle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).