Brad's -ffast-math breakup.

From-SVN: r40300
This commit is contained in:
Brad Lucier 2001-03-07 11:29:41 -08:00 committed by Richard Henderson
parent 6822468a69
commit de6c597958
25 changed files with 280 additions and 114 deletions

View file

@ -1,3 +1,51 @@
2001-03-07 Brad Lucier <lucier@math.purdue.edu>
* builtins.c (expand_builtin_mathfn): Check
flag_unsafe_math_optimizations, not flag_fast_math.
(expand_builtin): Likewise
* combine.c (combine_simplify_rtx): Likewise.
(simplify_if_then_else): Likewise.
* cse.c (fold_rtx): Likewise.
* flags.h: Remove flag_fast_math. Add
flag_unsafe_math_optimizations and flag_trapping_math.
* fold-const.c (negate_expr): Check
flag_unsafe_math_optimizations, not flag_fast_math.
(invert_truthvalue): Likewise.
(fold): Likewise. Before associating operands, check that
code == MULT_EXPR, not code != MULT_EXPR.
* ifcvt.c (noce_try_minmax): Check
flag_unsafe_math_optimizations, not flag_fast_math.
(noce_operand_ok): Check flag_trapping_math, not flag_fast_math.
* invoke.texi: Document -funsafe-math-optimizations and
-fno-trapping-math. Change documentation for -ffast-math.
* jump.c (reversed_comparison_code_parts): Likewise.
(rtx_equal_for_thread_p): Likewise.
* optabs.c (emit_conditional_move): Likewise.
* simplify-rtx.c (simplify_binary_operation): Likewise.
(simplify_relational_operation): Likewise.
(simplify_ternary_operation): Likewise.
* toplev.c: Remove flag_fast_math. Add flag_trapping_math and
flag_unsafe_math_optimizations. Remove fast-math entry from f_options.
Add trapping-math and unsafe-math-optimizations entries to f_options.
(set_fast_math_flags): New, sets flags for -ffast-math.
(set_no_fast_math_flags): New, sets flags for -fno-fast-math.
(decode_f_option): Add code to handle -ffast-math and -fno-fast-math.
* toplev.h: Declare set_fast_math_flags and set_no_fast_math_flags.
* config/alpha/alpha.c (alpha_emit_conditional_branch): Likewise.
(alpha_emit_conditional_move): Initialize local_fast_math to
flag_unsafe_math_optimizations, not flat_fast_math.
* config/c4x/c4x.c (c4x_override_options): Call set_fast_math_flags
instead of setting flag_fast_math to 1.
* config/convex/convex.md: Check flag_unsafe_math_optimizations,
not flag_fast_math.
* config/i386/i386.c (override_options): Likewise
* config/i386/i386.md: Likewise.
* config/m68k/m68k.md: Likewise.
* config/mips/mips.md: Likewise.
* config/rs6000/rs6000.c (validate_condition_mode): Likewise.
(rs6000_generate_compare): Likewise.
2001-03-07 Laurynas Biveinis <lauras@softhome.net>
* Makefile.in: Set RANLIB to @RANLIB@.

View file

@ -1430,10 +1430,10 @@ expand_builtin_mathfn (exp, target, subtarget)
return 0;
}
/* Check the results by default. But if flag_fast_math is turned on,
then assume sqrt will always be called with valid arguments. */
/* If errno must be maintained and if we are not allowing unsafe
math optimizations, check the result. */
if (flag_errno_math && ! flag_fast_math)
if (flag_errno_math && ! flag_unsafe_math_optimizations)
{
rtx lab1;
@ -3329,8 +3329,9 @@ expand_builtin (exp, target, subtarget, mode, ignore)
case BUILT_IN_SIN:
case BUILT_IN_COS:
/* Treat these like sqrt, but only if the user asks for them. */
if (! flag_fast_math)
/* Treat these like sqrt only if unsafe math optimizations are allowed,
because of possible accuracy problems. */
if (! flag_unsafe_math_optimizations)
break;
case BUILT_IN_FSQRT:
target = expand_builtin_mathfn (exp, target, subtarget);

View file

@ -4021,7 +4021,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
&& (! FLOAT_MODE_P (mode)
/* x-y != -(y-x) with IEEE floating point. */
|| TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
|| flag_fast_math))
|| flag_unsafe_math_optimizations))
return gen_binary (MINUS, mode, XEXP (XEXP (x, 0), 1),
XEXP (XEXP (x, 0), 0));
@ -4189,7 +4189,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
/* In IEEE floating point, x-0 is not the same as x. */
if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
|| ! FLOAT_MODE_P (GET_MODE (XEXP (x, 0)))
|| flag_fast_math)
|| flag_unsafe_math_optimizations)
&& XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 0))))
return XEXP (x, 0);
break;
@ -4777,12 +4777,12 @@ simplify_if_then_else (x)
/* Convert a == b ? b : a to "a". */
if (true_code == EQ && ! side_effects_p (cond)
&& (! FLOAT_MODE_P (mode) || flag_fast_math)
&& (! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
&& rtx_equal_p (XEXP (cond, 0), false_rtx)
&& rtx_equal_p (XEXP (cond, 1), true_rtx))
return false_rtx;
else if (true_code == NE && ! side_effects_p (cond)
&& (! FLOAT_MODE_P (mode) || flag_fast_math)
&& (! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
&& rtx_equal_p (XEXP (cond, 0), true_rtx)
&& rtx_equal_p (XEXP (cond, 1), false_rtx))
return true_rtx;
@ -4810,7 +4810,7 @@ simplify_if_then_else (x)
/* Look for MIN or MAX. */
if ((! FLOAT_MODE_P (mode) || flag_fast_math)
if ((! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
&& comparison_p
&& rtx_equal_p (XEXP (cond, 0), true_rtx)
&& rtx_equal_p (XEXP (cond, 1), false_rtx)

View file

@ -1678,7 +1678,7 @@ alpha_emit_conditional_branch (code)
if (alpha_compare.fp_p)
{
cmp_mode = DFmode;
if (flag_fast_math)
if (flag_unsafe_math_optimizations)
{
/* When we are not as concerned about non-finite values, and we
are comparing against zero, we can branch directly. */
@ -1879,7 +1879,7 @@ alpha_emit_conditional_move (cmp, mode)
= (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
enum machine_mode cmov_mode = VOIDmode;
int local_fast_math = flag_fast_math;
int local_fast_math = flag_unsafe_math_optimizations;
rtx tem;
/* Zero the operands. */

View file

@ -278,7 +278,7 @@ c4x_override_options ()
target_flags &= ~C3X_FLAG;
/* Convert foo / 8.0 into foo * 0.125, etc. */
flag_fast_math = 1;
set_fast_math_flags();
/* We should phase out the following at some stage.
This provides compatibility with the old -mno-aliases option. */

View file

@ -1309,39 +1309,39 @@
(define_insn "sqrtdf2"
[(set (match_operand:DF 0 "register_operand" "=d")
(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
"! TARGET_C1 && flag_fast_math"
"! TARGET_C1 && flag_unsafe_math_optimizations"
"sqrt.d %0"
[(set_attr "type" "divd")])
(define_insn "sqrtsf2"
[(set (match_operand:SF 0 "register_operand" "=d")
(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
"! TARGET_C1 && flag_fast_math"
"! TARGET_C1 && flag_unsafe_math_optimizations"
"sqrt.s %0"
[(set_attr "type" "divs")])
(define_insn "sindf2"
[(set (match_operand:DF 0 "register_operand" "=d")
(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
"! TARGET_C1 && flag_fast_math"
"! TARGET_C1 && flag_unsafe_math_optimizations"
"sin.d %0")
(define_insn "sinsf2"
[(set (match_operand:SF 0 "register_operand" "=d")
(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
"! TARGET_C1 && flag_fast_math"
"! TARGET_C1 && flag_unsafe_math_optimizations"
"sin.s %0")
(define_insn "cosdf2"
[(set (match_operand:DF 0 "register_operand" "=d")
(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
"! TARGET_C1 && flag_fast_math"
"! TARGET_C1 && flag_unsafe_math_optimizations"
"cos.d %0")
(define_insn "cossf2"
[(set (match_operand:SF 0 "register_operand" "=d")
(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
"! TARGET_C1 && flag_fast_math"
"! TARGET_C1 && flag_unsafe_math_optimizations"
"cos.s %0")
(define_insn "ftruncdf2"

View file

@ -748,7 +748,7 @@ override_options ()
/* If we're doing fast math, we don't care about comparison order
wrt NaNs. This lets us use a shorter comparison sequence. */
if (flag_fast_math)
if (flag_unsafe_math_optimizations)
target_flags &= ~MASK_IEEE_FP;
/* It makes no sense to ask for just SSE builtins, so MMX is also turned

View file

@ -10991,7 +10991,7 @@
[(set (match_operand:XF 0 "register_operand" "=f")
(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& (TARGET_IEEE_FP || flag_fast_math) "
&& (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
"fsqrt"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")
@ -11001,7 +11001,7 @@
[(set (match_operand:TF 0 "register_operand" "=f")
(sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& (TARGET_IEEE_FP || flag_fast_math) "
&& (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
"fsqrt"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")
@ -11050,7 +11050,8 @@
(define_insn "sindf2"
[(set (match_operand:DF 0 "register_operand" "=f")
(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
"fsin"
[(set_attr "type" "fpspc")
(set_attr "mode" "DF")])
@ -11058,7 +11059,8 @@
(define_insn "sinsf2"
[(set (match_operand:SF 0 "register_operand" "=f")
(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
"fsin"
[(set_attr "type" "fpspc")
(set_attr "mode" "SF")])
@ -11067,7 +11069,8 @@
[(set (match_operand:DF 0 "register_operand" "=f")
(unspec:DF [(float_extend:DF
(match_operand:SF 1 "register_operand" "0"))] 1))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
"fsin"
[(set_attr "type" "fpspc")
(set_attr "mode" "DF")])
@ -11075,7 +11078,8 @@
(define_insn "sinxf2"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
"fsin"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")])
@ -11083,7 +11087,8 @@
(define_insn "sintf2"
[(set (match_operand:TF 0 "register_operand" "=f")
(unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
"fsin"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")])
@ -11091,7 +11096,8 @@
(define_insn "cosdf2"
[(set (match_operand:DF 0 "register_operand" "=f")
(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
"fcos"
[(set_attr "type" "fpspc")
(set_attr "mode" "DF")])
@ -11099,7 +11105,8 @@
(define_insn "cossf2"
[(set (match_operand:SF 0 "register_operand" "=f")
(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
"fcos"
[(set_attr "type" "fpspc")
(set_attr "mode" "SF")])
@ -11108,7 +11115,8 @@
[(set (match_operand:DF 0 "register_operand" "=f")
(unspec:DF [(float_extend:DF
(match_operand:SF 1 "register_operand" "0"))] 2))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
"fcos"
[(set_attr "type" "fpspc")
(set_attr "mode" "DF")])
@ -11116,7 +11124,8 @@
(define_insn "cosxf2"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
"fcos"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")])
@ -11124,7 +11133,8 @@
(define_insn "costf2"
[(set (match_operand:TF 0 "register_operand" "=f")
(unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
"fcos"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")])

View file

@ -7840,7 +7840,7 @@
(define_insn "sinsf2"
[(set (match_operand:SF 0 "general_operand" "=f")
(unspec:SF [(match_operand:SF 1 "general_operand" "fm")] 1))]
"TARGET_68881 && flag_fast_math"
"TARGET_68881 && flag_unsafe_math_optimizations"
"*
{
if (FP_REG_P (operands[1]))
@ -7852,7 +7852,7 @@
(define_insn "sindf2"
[(set (match_operand:DF 0 "general_operand" "=f")
(unspec:DF [(match_operand:DF 1 "general_operand" "fm")] 1))]
"TARGET_68881 && flag_fast_math"
"TARGET_68881 && flag_unsafe_math_optimizations"
"*
{
if (FP_REG_P (operands[1]))
@ -7864,13 +7864,13 @@
(define_insn "sinxf2"
[(set (match_operand:XF 0 "general_operand" "=f")
(unspec:XF [(match_operand:XF 1 "nonimmediate_operand" "fm")] 1))]
"TARGET_68881 && flag_fast_math"
"TARGET_68881 && flag_unsafe_math_optimizations"
"fsin%.x %1,%0")
(define_insn "cossf2"
[(set (match_operand:SF 0 "general_operand" "=f")
(unspec:SF [(match_operand:SF 1 "general_operand" "fm")] 2))]
"TARGET_68881 && flag_fast_math"
"TARGET_68881 && flag_unsafe_math_optimizations"
"*
{
if (FP_REG_P (operands[1]))
@ -7882,7 +7882,7 @@
(define_insn "cosdf2"
[(set (match_operand:DF 0 "general_operand" "=f")
(unspec:DF [(match_operand:DF 1 "general_operand" "fm")] 2))]
"TARGET_68881 && flag_fast_math"
"TARGET_68881 && flag_unsafe_math_optimizations"
"*
{
if (FP_REG_P (operands[1]))
@ -7894,7 +7894,7 @@
(define_insn "cosxf2"
[(set (match_operand:XF 0 "general_operand" "=f")
(unspec:XF [(match_operand:XF 1 "nonimmediate_operand" "fm")] 2))]
"TARGET_68881 && flag_fast_math"
"TARGET_68881 && flag_unsafe_math_optimizations"
"fcos%.x %1,%0")
(define_insn "trap"

View file

@ -2223,7 +2223,7 @@
[(set (match_operand:DF 0 "register_operand" "=f")
(div:DF (match_operand:DF 1 "const_float_1_operand" "")
(match_operand:DF 2 "register_operand" "f")))]
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
"recip.d\\t%0,%2"
[(set_attr "type" "fdiv")
(set_attr "mode" "DF")])
@ -2232,7 +2232,7 @@
[(set (match_operand:SF 0 "register_operand" "=f")
(div:SF (match_operand:SF 1 "const_float_1_operand" "")
(match_operand:SF 2 "register_operand" "f")))]
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_fast_math"
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
"recip.s\\t%0,%2"
[(set_attr "type" "fdiv")
(set_attr "mode" "SF")])
@ -2824,7 +2824,7 @@
[(set (match_operand:DF 0 "register_operand" "=f")
(div:DF (match_operand:DF 1 "const_float_1_operand" "")
(sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
"rsqrt.d\\t%0,%2"
[(set_attr "type" "fsqrt")
(set_attr "mode" "DF")])
@ -2833,7 +2833,7 @@
[(set (match_operand:SF 0 "register_operand" "=f")
(div:SF (match_operand:SF 1 "const_float_1_operand" "")
(sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_fast_math"
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
"rsqrt.s\\t%0,%2"
[(set_attr "type" "fsqrt")
(set_attr "mode" "SF")])

View file

@ -3238,9 +3238,10 @@ validate_condition_mode (code, mode)
|| code == UNGE || code == UNLE))
abort();
/* These should never be generated except for fast_math. */
/* These should never be generated except for
flag_unsafe_math_optimizations. */
if (mode == CCFPmode
&& ! flag_fast_math
&& ! flag_unsafe_math_optimizations
&& (code == LE || code == GE
|| code == UNEQ || code == LTGT
|| code == UNGT || code == UNLT))
@ -4454,9 +4455,9 @@ rs6000_generate_compare (code)
rs6000_compare_op1)));
/* Some kinds of FP comparisons need an OR operation;
except that for fast_math we don't bother. */
except for flag_unsafe_math_optimizations we don't bother. */
if (rs6000_compare_fp_p
&& ! flag_fast_math
&& ! flag_unsafe_math_optimizations
&& (code == LE || code == GE
|| code == UNEQ || code == LTGT
|| code == UNGT || code == UNLT))

View file

@ -3977,7 +3977,8 @@ fold_rtx (x, insn)
{
/* Sadly two equal NaNs are not equivalent. */
if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
|| ! FLOAT_MODE_P (mode_arg0) || flag_fast_math)
|| ! FLOAT_MODE_P (mode_arg0)
|| flag_unsafe_math_optimizations)
return ((code == EQ || code == LE || code == GE
|| code == LEU || code == GEU || code == UNEQ
|| code == UNLE || code == UNGE || code == ORDERED)

View file

@ -1,8 +1,13 @@
2001-03-07 Brad Lucier <lucier@math.purdue.edu>
* g77.texi: Document new options -funsafe-math-optimizations
and -fno-trapping-math. Revise documentation for -ffast-math.
2001-03-01 Zack Weinberg <zackw@stanford.edu>
* f/proj.h: Delete 'bool' type. Don't include stddef.h here.
* f/com.c: Rename variables named 'true' and/or 'false'.
* f/intdoc.c: Delete 'bool' type.
* proj.h: Delete 'bool' type. Don't include stddef.h here.
* com.c: Rename variables named 'true' and/or 'false'.
* intdoc.c: Delete 'bool' type.
2001-03-01 Zack Weinberg <zackw@stanford.edu>

View file

@ -1446,6 +1446,7 @@ by type. Explanations are in the following sections.
-malign-double
-ffloat-store -fforce-mem -fforce-addr -fno-inline
-ffast-math -fstrength-reduce -frerun-cse-after-loop
-funsafe-math-optimizations -fno-trapping-math
-fexpensive-optimizations -fdelayed-branch
-fschedule-insns -fschedule-insn2 -fcaller-saves
-funroll-loops -funroll-all-loops
@ -2779,6 +2780,22 @@ Note that if you are not optimizing, no functions can be expanded inline.
@cindex conformance, IEEE 754
Might allow some programs designed to not be too dependent
on IEEE behavior for floating-point to run faster, or die trying.
Sets @samp{-funsafe-math-optimizations}, and
@samp{-fno-trapping-math}.
@cindex -funsafe-math-optimizations option
@cindex options, -funsafe-math-optimizations
@item -funsafe-math-optimizations
Allow optimizations that may be give incorrect results
for certain IEEE inputs.
@cindex -fno-trapping-math option
@cindex options, -fno-trapping-math
@item -fno-trapping-math
Allow the compiler to assume that floating-point arithmetic
will not generate traps on any inputs. This is useful, for
example, when running a program using IEEE "non-stop"
floating-point arithmetic.
@cindex -fstrength-reduce option
@cindex options, -fstrength-reduce

View file

@ -327,22 +327,28 @@ extern int flag_volatile_global;
extern int flag_volatile_static;
/* Nonzero allows GCC to violate some IEEE or ANSI rules regarding math
operations in the interest of optimization. For example it allows
GCC to assume arguments to sqrt are nonnegative numbers, allowing
faster code for sqrt to be generated. */
extern int flag_fast_math;
/* Nonzero allows GCC to optimize sibling and tail recursive calls. */
extern int flag_optimize_sibling_calls;
/* Nonzero means the front end generally wants `errno' maintained by math
operations, like built-in SQRT, unless overridden by flag_fast_math. */
operations, like built-in SQRT. */
extern int flag_errno_math;
/* Nonzero means that unsafe floating-point math optimizations are allowed
for the sake of speed. IEEE compliance is not guaranteed, and operations
are allowed to assume that their arguments and results are "normal"
(e.g., nonnegative for SQRT). */
extern int flag_unsafe_math_optimizations;
/* Zero means that floating-point math operations cannot generate a
(user-visible) trap. This is the case, for example, in nonstop
IEEE 754 arithmetic. */
extern int flag_trapping_math;
/* 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). */

View file

@ -1311,7 +1311,7 @@ negate_expr (t)
case MINUS_EXPR:
/* - (A - B) -> B - A */
if (! FLOAT_TYPE_P (type) || flag_fast_math)
if (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
return convert (type,
fold (build (MINUS_EXPR, TREE_TYPE (t),
TREE_OPERAND (t, 1),
@ -2719,7 +2719,9 @@ invert_truthvalue (arg)
if (TREE_CODE_CLASS (code) == '<')
{
if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
&& !flag_fast_math && code != NE_EXPR && code != EQ_EXPR)
&& !flag_unsafe_math_optimizations
&& code != NE_EXPR
&& code != EQ_EXPR)
return build1 (TRUTH_NOT_EXPR, type, arg);
else
return build (invert_tree_comparison (code), type,
@ -5262,7 +5264,7 @@ fold (expr)
/* Convert - (a - b) to (b - a) for non-floating-point. */
else if (TREE_CODE (arg0) == MINUS_EXPR
&& (! FLOAT_TYPE_P (type) || flag_fast_math))
&& (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations))
return build (MINUS_EXPR, type, TREE_OPERAND (arg0, 1),
TREE_OPERAND (arg0, 0));
@ -5457,7 +5459,7 @@ fold (expr)
}
/* In IEEE floating point, x+0 may not equal x. */
else if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
|| flag_fast_math)
|| flag_unsafe_math_optimizations)
&& real_zerop (arg1))
return non_lvalue (convert (type, arg0));
/* x+(-0) equals x, even for IEEE. */
@ -5541,11 +5543,11 @@ fold (expr)
parentheses. Rather than remember where the parentheses were, we
don't associate floats at all. It shouldn't matter much. However,
associating multiplications is only very slightly inaccurate, so do
that if -ffast-math is specified. */
that if -funsafe-math-optimizations is specified. */
if (! wins
&& (! FLOAT_TYPE_P (type)
|| (flag_fast_math && code != MULT_EXPR)))
|| (flag_unsafe_math_optimizations && code == MULT_EXPR)))
{
tree var0, con0, lit0, var1, con1, lit1;
@ -5622,7 +5624,7 @@ fold (expr)
}
else if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
|| flag_fast_math)
|| flag_unsafe_math_optimizations)
{
/* Except with IEEE floating point, 0-x equals -x. */
if (! wins && real_zerop (arg0))
@ -5638,7 +5640,7 @@ fold (expr)
Also note that operand_equal_p is always false if an operand
is volatile. */
if ((! FLOAT_TYPE_P (type) || flag_fast_math)
if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
&& operand_equal_p (arg0, arg1, 0))
return convert (type, integer_zero_node);
@ -5677,7 +5679,7 @@ fold (expr)
{
/* x*0 is 0, except for IEEE floating point. */
if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
|| flag_fast_math)
|| flag_unsafe_math_optimizations)
&& real_zerop (arg1))
return omit_one_operand (type, arg1, arg0);
/* In IEEE floating point, x*1 is not equivalent to x for snans.
@ -5834,12 +5836,12 @@ fold (expr)
/* If ARG1 is a constant, we can convert this to a multiply by the
reciprocal. This does not have the same rounding properties,
so only do this if -ffast-math. We can actually always safely
do it if ARG1 is a power of two, but it's hard to tell if it is
or not in a portable manner. */
so only do this if -funsafe-math-optimizations. We can actually
always safely do it if ARG1 is a power of two, but it's hard to
tell if it is or not in a portable manner. */
if (TREE_CODE (arg1) == REAL_CST)
{
if (flag_fast_math
if (flag_unsafe_math_optimizations
&& 0 != (tem = const_binop (code, build_real (type, dconst1),
arg1, 0)))
return fold (build (MULT_EXPR, type, arg0, tem));
@ -6899,7 +6901,7 @@ fold (expr)
if (TREE_CODE_CLASS (TREE_CODE (arg0)) == '<'
&& (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
|| ! FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0)))
|| flag_fast_math)
|| flag_unsafe_math_optimizations)
&& operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
arg1, TREE_OPERAND (arg0, 1)))
{

View file

@ -1143,7 +1143,7 @@ noce_try_minmax (if_info)
to get the target to tell us... */
if (FLOAT_MODE_P (GET_MODE (if_info->x))
&& TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
&& ! flag_fast_math)
&& ! flag_unsafe_math_optimizations)
return FALSE;
cond = noce_get_alt_condition (if_info, if_info->a, &earliest);
@ -1397,10 +1397,10 @@ noce_operand_ok (op)
if (side_effects_p (op))
return FALSE;
/* ??? Unfortuantely may_trap_p can't look at flag_fast_math, due to
/* ??? Unfortuantely may_trap_p can't look at flag_trapping_math, due to
being linked into the genfoo programs. This is probably a mistake.
With finite operands, most fp operations don't trap. */
if (flag_fast_math && FLOAT_MODE_P (GET_MODE (op)))
if (!flag_trapping_math && FLOAT_MODE_P (GET_MODE (op)))
switch (GET_CODE (op))
{
case DIV:

View file

@ -245,8 +245,9 @@ in the following sections.
-finline-functions -finline-limit=@var{n} -fkeep-inline-functions @gol
-fkeep-static-consts -fmove-all-movables @gol
-fno-default-inline -fno-defer-pop @gol
-fno-function-cse -fno-guess-branch-probability
-fno-function-cse -fno-guess-branch-probability @gol
-fno-inline -fno-math-errno -fno-peephole @gol
-funsafe-math-optimizations -fno-trapping-math @gol
-fomit-frame-pointer -foptimize-register-move @gol
-foptimize-sibling-calls -freduce-all-givs @gol
-fregmove -frename-registers @gol
@ -2934,11 +2935,10 @@ that alter the assembler output may be confused by the optimizations
performed when this option is not used.
@item -ffast-math
This option allows GCC to violate some ISO or IEEE rules and/or
specifications in the interest of optimizing code for speed. For
example, it allows the compiler to assume arguments to the @code{sqrt}
function are non-negative numbers and that no floating-point values
are NaNs.
Sets @samp{-fno-math-errno}, @samp{-funsafe-math-optimizations},
and @samp{-fno-trapping-math}.
This option causes the preprocessor macro __FAST_MATH__ to be defined.
This option causes the preprocessor macro __FAST_MATH__ to be defined.
@ -2953,8 +2953,39 @@ with a single instruction, e.g., sqrt. A program that relies on
IEEE exceptions for math error handling may want to use this flag
for speed while maintaining IEEE arithmetic compatibility.
This option should never be turned on by any @samp{-O} option since
it can result in incorrect output for programs which depend on
an exact implementation of IEEE or ISO rules/specifications for
math functions.
The default is @samp{-fmath-errno}. The @samp{-ffast-math} option
sets @samp{-fno-math-errno}.
@item -funsafe-math-optimizations
Allow optimizations for floating-point arithmetic that (a) assume
that arguments and results are valid and (b) may violate IEEE or
ANSI standards.
This option should never be turned on by any @samp{-O} option since
it can result in incorrect output for programs which depend on
an exact implementation of IEEE or ISO rules/specifications for
math functions.
The default is @samp{-fno-unsafe-math-optimizations}. The
@samp{-ffast-math} option sets @samp{-funsafe-math-optimizations}.
@item -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 @samp{-O} option since
it can result in incorrect output for programs which depend on
an exact implementation of IEEE or ISO rules/specifications for
math functions.
The default is @samp{-ftrapping-math}. The @samp{-ffast-math}
option sets @samp{-fno-trapping-math}.
@end table
@c following causes underfulls.. they don't look great, but we deal.
@ -6594,7 +6625,7 @@ Some 387 emulators do not support the @code{sin}, @code{cos} and
@code{sqrt} instructions for the 387. Specify this option to avoid
generating those instructions. This option is the default on FreeBSD.
As of revision 2.6.1, these instructions are not generated unless you
also use the @samp{-ffast-math} switch.
also use the @samp{-funsafe-math-optimizations} switch.
@item -malign-double
@itemx -mno-align-double

View file

@ -1,3 +1,8 @@
2001-03-07 Brad Lucier <lucier@math.purdue.edu>
* typeck.c (convert): Check flag_unsafe_math_optimizations,
not flag_fast_math.
2001-03-05 Per Bothner <per@bothner.com>
Fix a problem where rest_of_decl_compilation applied to

View file

@ -132,7 +132,7 @@ convert (type, expr)
return fold (convert_to_boolean (type, expr));
if (code == INTEGER_TYPE)
{
if (! flag_fast_math
if (! flag_unsafe_math_optimizations
&& ! flag_emit_class_files
&& TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
&& TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)

View file

@ -1785,7 +1785,7 @@ reversed_comparison_code_parts (code, arg0, arg1, insn)
/* We don't have safe way to reverse these yet - we would need
ordered compares that may not trap. */
if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
|| flag_fast_math)
|| flag_unsafe_math_optimizations)
return reverse_condition_maybe_unordered (code);
return UNKNOWN;
default:
@ -1794,7 +1794,7 @@ reversed_comparison_code_parts (code, arg0, arg1, insn)
/* In case we give up IEEE compatibility, all comparisons are reversible. */
if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
|| flag_fast_math)
|| flag_unsafe_math_optimizations)
return reverse_condition (code);
if (GET_MODE_CLASS (mode) == MODE_CC
@ -4061,7 +4061,7 @@ rtx_equal_for_thread_p (x, y, yinsn)
pessimistic, but this pass would only rarely do anything for FP
anyway. */
if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
&& FLOAT_MODE_P (GET_MODE (x)) && ! flag_fast_math)
&& FLOAT_MODE_P (GET_MODE (x)) && ! flag_unsafe_math_optimizations)
return 0;
/* For commutative operations, the RTX match if the operand match in any

View file

@ -3620,7 +3620,8 @@ emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
|| (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
&& (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
|| TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT || flag_fast_math))
|| TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
|| flag_unsafe_math_optimizations))
{
tem = op2;
op2 = op3;

View file

@ -903,7 +903,7 @@ simplify_binary_operation (code, mode, op0, op1)
/* In IEEE floating point, x+0 is not the same as x. Similarly
for the other optimizations below. */
if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
&& FLOAT_MODE_P (mode) && ! flag_fast_math)
&& FLOAT_MODE_P (mode) && ! flag_unsafe_math_optimizations)
break;
if (op1 == CONST0_RTX (mode))
@ -1004,7 +1004,7 @@ simplify_binary_operation (code, mode, op0, op1)
In IEEE floating point, x-0 is not the same as x. */
if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
|| ! FLOAT_MODE_P (mode) || flag_fast_math)
|| ! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
&& op1 == CONST0_RTX (mode))
return op0;
#endif
@ -1034,15 +1034,15 @@ simplify_binary_operation (code, mode, op0, op1)
/* None of these optimizations can be done for IEEE
floating point. */
if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
&& FLOAT_MODE_P (mode) && ! flag_fast_math)
&& FLOAT_MODE_P (mode) && ! flag_unsafe_math_optimizations)
break;
/* We can't assume x-x is 0 even with non-IEEE floating point,
but since it is zero except in very strange circumstances, we
will treat it as zero with -ffast-math. */
will treat it as zero with -funsafe-math-optimizations. */
if (rtx_equal_p (op0, op1)
&& ! side_effects_p (op0)
&& (! FLOAT_MODE_P (mode) || flag_fast_math))
&& (! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations))
return CONST0_RTX (mode);
/* Change subtraction from zero into negation. */
@ -1153,7 +1153,7 @@ simplify_binary_operation (code, mode, op0, op1)
/* In IEEE floating point, x*0 is not always 0. */
if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
|| ! FLOAT_MODE_P (mode) || flag_fast_math)
|| ! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
&& op1 == CONST0_RTX (mode)
&& ! side_effects_p (op0))
return op1;
@ -1260,19 +1260,18 @@ simplify_binary_operation (code, mode, op0, op1)
/* In IEEE floating point, 0/x is not always 0. */
if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
|| ! FLOAT_MODE_P (mode) || flag_fast_math)
|| ! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
&& op0 == CONST0_RTX (mode)
&& ! side_effects_p (op1))
return op0;
#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
/* Change division by a constant into multiplication. Only do
this with -ffast-math until an expert says it is safe in
general. */
this with -funsafe-math-optimizations. */
else if (GET_CODE (op1) == CONST_DOUBLE
&& GET_MODE_CLASS (GET_MODE (op1)) == MODE_FLOAT
&& op1 != CONST0_RTX (mode)
&& flag_fast_math)
&& flag_unsafe_math_optimizations)
{
REAL_VALUE_TYPE d;
REAL_VALUE_FROM_CONST_DOUBLE (d, op1);
@ -1803,17 +1802,18 @@ simplify_relational_operation (code, mode, op0, op1)
return simplify_relational_operation (signed_condition (code),
mode, tem, const0_rtx);
if (flag_fast_math && code == ORDERED)
if (flag_unsafe_math_optimizations && code == ORDERED)
return const_true_rtx;
if (flag_fast_math && code == UNORDERED)
if (flag_unsafe_math_optimizations && code == UNORDERED)
return const0_rtx;
/* For non-IEEE floating-point, if the two operands are equal, we know the
result. */
if (rtx_equal_p (op0, op1)
&& (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
|| ! FLOAT_MODE_P (GET_MODE (op0)) || flag_fast_math))
|| ! FLOAT_MODE_P (GET_MODE (op0))
|| flag_unsafe_math_optimizations))
equal = 1, op0lt = 0, op0ltu = 0, op1lt = 0, op1ltu = 0;
/* If the operands are floating-point constants, see if we can fold
@ -2082,12 +2082,12 @@ simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2)
/* Convert a == b ? b : a to "a". */
if (GET_CODE (op0) == NE && ! side_effects_p (op0)
&& (! FLOAT_MODE_P (mode) || flag_fast_math)
&& (! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
&& rtx_equal_p (XEXP (op0, 0), op1)
&& rtx_equal_p (XEXP (op0, 1), op2))
return op1;
else if (GET_CODE (op0) == EQ && ! side_effects_p (op0)
&& (! FLOAT_MODE_P (mode) || flag_fast_math)
&& (! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
&& rtx_equal_p (XEXP (op0, 1), op1)
&& rtx_equal_p (XEXP (op0, 0), op2))
return op2;

View file

@ -618,22 +618,28 @@ int flag_data_sections = 0;
int flag_no_peephole = 0;
/* Nonzero allows GCC to violate some IEEE or ANSI rules regarding math
operations in the interest of optimization. For example it allows
GCC to assume arguments to sqrt are nonnegative numbers, allowing
faster code for sqrt to be generated. */
int flag_fast_math = 0;
/* Nonzero allows GCC to optimize sibling and tail recursive calls. */
int flag_optimize_sibling_calls = 0;
/* Nonzero means the front end generally wants `errno' maintained by math
operations, like built-in SQRT, unless overridden by flag_fast_math. */
operations, like built-in SQRT. */
int flag_errno_math = 1;
/* Nonzero means that unsafe floating-point math optimizations are allowed
for the sake of speed. IEEE compliance is not guaranteed, and operations
are allowed to assume that their arguments and results are "normal"
(e.g., nonnegative for SQRT). */
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. */
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). */
@ -1094,8 +1100,6 @@ lang_independent_options f_options[] =
"Reorder basic blocks to improve code placement" },
{"rename-registers", &flag_rename_registers, 1,
"Do the register renaming optimization pass"},
{"fast-math", &flag_fast_math, 1,
"Improve FP speed by violating ANSI & IEEE rules" },
{"common", &flag_no_common, 0,
"Do not put unitialised globals in the common section" },
{"inhibit-size-directive", &flag_inhibit_size_directive, 1,
@ -1154,6 +1158,10 @@ lang_independent_options f_options[] =
"Enables guessing of branch probabilities" },
{"math-errno", &flag_errno_math, 1,
"Set errno after built-in math functions"},
{"trapping-math", &flag_trapping_math, 1,
"Floating-point operations can trap"},
{"unsafe-math-optimizations", &flag_unsafe_math_optimizations, 1,
"Allow math optimizations that may violate IEEE or ANSI standards"},
{"bounded-pointers", &flag_bounded_pointers, 1,
"Compile pointers as triples: value, base & end" },
{"bounds-check", &flag_bounds_check, 1,
@ -1479,6 +1487,26 @@ lang_independent_options W_options[] =
{"missing-noreturn", &warn_missing_noreturn, 1,
"Warn about functions which might be candidates for attribute noreturn"}
};
/* The following routines are useful in setting all the flags that
-ffast-math and -fno-fast-math imply. */
void
set_fast_math_flags ()
{
flag_trapping_math = 0;
flag_unsafe_math_optimizations = 1;
flag_errno_math = 0;
}
void
set_no_fast_math_flags ()
{
flag_trapping_math = 1;
flag_unsafe_math_optimizations = 0;
flag_errno_math = 1;
}
/* Output files for assembler code (real compiler output)
and debugging dumps. */
@ -4092,8 +4120,12 @@ decode_f_option (arg)
}
}
if ((option_value = skip_leading_substring (arg, "inline-limit-"))
|| (option_value = skip_leading_substring (arg, "inline-limit=")))
if (!strcmp (arg, "fast-math"))
set_fast_math_flags();
else if (!strcmp (arg, "no-fast-math"))
set_no_fast_math_flags();
else if ((option_value = skip_leading_substring (arg, "inline-limit-"))
|| (option_value = skip_leading_substring (arg, "inline-limit=")))
{
int val =
read_integral_parameter (option_value, arg - 2,

View file

@ -164,4 +164,10 @@ struct lang_hooks
/* Each front end provides its own. */
extern struct lang_hooks lang_hooks;
/* These functions can be used by targets to set the flags originally
implied by -ffast-math and -fno-fast-math. */
extern void set_fast_math_flags PARAMS ((void));
extern void set_no_fast_math_flags PARAMS ((void));
#endif /* __GCC_TOPLEV_H */