Brad's -ffast-math breakup.
From-SVN: r40300
This commit is contained in:
parent
6822468a69
commit
de6c597958
25 changed files with 280 additions and 114 deletions
|
@ -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@.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")])
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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")])
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
22
gcc/flags.h
22
gcc/flags.h
|
@ -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). */
|
||||
|
|
|
@ -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)))
|
||||
{
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
56
gcc/toplev.c
56
gcc/toplev.c
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue