* Makefile.in: rtlanal.o now depends upon real.h.
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 28 Jul 2002 02:11:05 +0000 (02:11 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 28 Jul 2002 02:11:05 +0000 (02:11 +0000)
* 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.
(process_options): flag_signaling_nans implies flag_trapping_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 !HONOR_SNANS.
[RDIV_EXPR]: Conditionalize x/1.0 into x on !HONOR_SNANS.

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

* 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 (i.e. HONOR_SNANS but not HONOR_NANS).

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

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@55804 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/Makefile.in
gcc/c-common.c
gcc/doc/invoke.texi
gcc/flags.h
gcc/fold-const.c
gcc/rtlanal.c
gcc/simplify-rtx.c
gcc/toplev.c

index 984b941..cc9307e 100644 (file)
@@ -1,3 +1,33 @@
+2002-07-27  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.
+       (process_options): flag_signaling_nans implies flag_trapping_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 !HONOR_SNANS.
+       [RDIV_EXPR]: Conditionalize x/1.0 into x on !HONOR_SNANS.
+
+       * simplify-rtx.c (simplify_relational_operation): Conditionalize
+       transforming abs(x) < 0.0 into false on !HONOR_SNANS.
+
+       * 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 (i.e. HONOR_SNANS but not HONOR_NANS).
+
+       * doc/invoke.texi: Document new -fsignaling-nans compiler option.
+
 2002-07-27  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * Makefile.in (gengtype-lex.c): Work around a bug in flex.
index 912635c..e87a1ea 100644 (file)
@@ -1403,7 +1403,7 @@ print-rtl.o : print-rtl.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
        $(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
+   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 88c3ef5..f7bbc1b 100644 (file)
@@ -4383,6 +4383,8 @@ cb_register_builtins (pfile)
     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 5240304..8d5687b 100644 (file)
@@ -280,7 +280,7 @@ in the following sections.
 -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
+-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
@@ -3407,8 +3407,8 @@ performed when this option is not used.
 
 @item -ffast-math
 @opindex ffast-math
-Sets @option{-fno-math-errno}, @option{-funsafe-math-optimizations}, and @*
-@option{-fno-trapping-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.
 
@@ -3449,8 +3449,10 @@ The default is @option{-fno-unsafe-math-optimizations}.
 @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.
+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
@@ -3459,6 +3461,21 @@ 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
 If the target supports a BSS section, GCC by default puts variables that
index 012b63c..06ebd20 100644 (file)
@@ -663,6 +663,9 @@ extern int flag_non_call_exceptions;
 /* 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
@@ -671,6 +674,9 @@ extern int flag_zero_initialized_in_bss;
 #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.  */
 #define HONOR_INFINITIES(MODE) \
index 3dafe0a..49c53cc 100644 (file)
@@ -5476,16 +5476,13 @@ fold (expr)
              && !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))
+         /* 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.  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
+         /* 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));
 
@@ -5620,9 +5617,9 @@ fold (expr)
        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))
+      /* 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 35cc513..6d391ea 100644 (file)
@@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #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 *));
@@ -2369,6 +2370,8 @@ may_trap_p (x)
     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))
@@ -2396,12 +2399,22 @@ may_trap_p (x)
         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)
+      if (HONOR_NANS (GET_MODE (x)))
        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)
+      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;
 
index 59f9aa6..0565dcd 100644 (file)
@@ -2063,7 +2063,7 @@ simplify_relational_operation (code, mode, op0, op1)
 
        case LT:
          /* Optimize abs(x) < 0.0.  */
-         if (trueop1 == CONST0_RTX (mode))
+         if (trueop1 == CONST0_RTX (mode) && !HONOR_SNANS (mode))
            {
              tem = GET_CODE (trueop0) == FLOAT_EXTEND ? XEXP (trueop0, 0)
                                                       : trueop0;
index 0022fcb..e4aeca0 100644 (file)
@@ -577,10 +577,18 @@ int flag_unsafe_math_optimizations = 0;
 
 /* Zero means that floating-point math operations cannot generate a
    (user-visible) trap.  This is the case, for example, in nonstop
-   IEEE 754 arithmetic.  */
+   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).  */
@@ -1170,6 +1178,8 @@ static const lang_independent_options f_options[] =
    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,
@@ -1566,6 +1576,8 @@ set_fast_math_flags (set)
   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.  */
@@ -5086,6 +5098,10 @@ process_options ()
   if (flag_function_sections && write_symbols != NO_DEBUG)
     warning ("-ffunction-sections may affect debugging on some targets");
 #endif
+
+    /* The presence of IEEE signaling NaNs, implies all math can trap.  */
+    if (flag_signaling_nans)
+      flag_trapping_math = 1;
 }
 \f
 /* Language-independent initialization, before language-dependent