summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2002-07-28 02:11:05 +0000
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2002-07-28 02:11:05 +0000
commit0a8176f36ec372a4571f006c8262b5aa8a29b65c (patch)
tree811f8a9808cc8a4ff4fa003afa503d9d758bdcc8
parent525ef9f93fe5003b747daddb0962d8847332123c (diff)
downloadgcc-0a8176f36ec372a4571f006c8262b5aa8a29b65c.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@55804 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog30
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/c-common.c2
-rw-r--r--gcc/doc/invoke.texi27
-rw-r--r--gcc/flags.h6
-rw-r--r--gcc/fold-const.c19
-rw-r--r--gcc/rtlanal.c19
-rw-r--r--gcc/simplify-rtx.c2
-rw-r--r--gcc/toplev.c18
9 files changed, 103 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 984b94167bd..cc9307ec797 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 912635cf209..e87a1ea0626 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -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)
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 88c3ef5534d..f7bbc1b5f44 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -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__");
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 5240304795f..8d5687b8a01 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -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
diff --git a/gcc/flags.h b/gcc/flags.h
index 012b63c8d45..06ebd20a59d 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -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) \
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 3dafe0afb31..49c53cc0857 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 35cc5130caa..6d391eaf374 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -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;
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 59f9aa6d37b..0565dcd32b8 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -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;
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 0022fcb289c..e4aeca03875 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -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;
}
/* Language-independent initialization, before language-dependent