* 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
+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.
$(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)
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__");
-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
@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.
@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
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
/* 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
#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) \
&& !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));
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
#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 *));
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))
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;
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;
/* 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). */
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,
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. */
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