Brad's -ffast-math breakup.
authorBrad Lucier <lucier@math.purdue.edu>
Wed, 7 Mar 2001 19:29:41 +0000 (11:29 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 7 Mar 2001 19:29:41 +0000 (11:29 -0800)
From-SVN: r40300

25 files changed:
gcc/ChangeLog
gcc/builtins.c
gcc/combine.c
gcc/config/alpha/alpha.c
gcc/config/c4x/c4x.c
gcc/config/convex/convex.md
gcc/config/i386/i386.c
gcc/config/i386/i386.md
gcc/config/m68k/m68k.md
gcc/config/mips/mips.md
gcc/config/rs6000/rs6000.c
gcc/cse.c
gcc/f/ChangeLog
gcc/f/g77.texi
gcc/flags.h
gcc/fold-const.c
gcc/ifcvt.c
gcc/invoke.texi
gcc/java/ChangeLog
gcc/java/typeck.c
gcc/jump.c
gcc/optabs.c
gcc/simplify-rtx.c
gcc/toplev.c
gcc/toplev.h

index df78a57f883ffc950cd0bbafde1b45ebdf218f95..c24116eeaf7d2b642715788782d7802300b9fef3 100644 (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@.
index 3dedc5b336aa7361cb62d5040271c11a27e5f4fb..8ccd0922f62bf0e448eae1b9f746216f0bffb6be 100644 (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);
index bf6a1eec5d843edac4e88939f00fa9b9e9e944a9..ca698707e77edb723698c7e9c37ea0334d2e0d32 100644 (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)
index 25d7d3b503f8d28a1177bcdf19361153d8701637..a9c2e85faca6b1369f5d13be1b6f472addbc83b4 100644 (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.  */
index 48f4451ad69059c328b01f0debabdd4ef9bad3fd..b8f3d2ad1529787c561faa5383f26256de9c8aef 100644 (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.  */
index c82169823bccbdc5b985f55d56a482905acf6fe1..31ee5eec4c055865143752da2c13a65e56461f0d 100644 (file)
 (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"
index 380f6af1ec42066317f75867e7e9eeb783587a05..0f531ea3091dd8386cc3bfa346820afea1fc2fd8 100644 (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
index fc341af8d33ec4b0c24bb22f8cbee375c6eb668f..43b007d27f927f70285be5979f72285dde771785 100644 (file)
   [(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")
   [(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")
 (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")])
 (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")])
   [(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")])
 (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")])
 (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")])
 (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")])
 (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")])
   [(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")])
 (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")])
 (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")])
index 75c552535c9381477c0405c86e0e66cf1cda6513..1eff7f437234a88f0f317459610ea65fa3bb4a81 100644 (file)
 (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]))
 (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]))
 (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]))
 (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]))
 (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"
index a37464e569ff2eda162bef55fc3a95676c087da9..1f343f54229af20d2902e61d5a83e62df067605b 100644 (file)
   [(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")])
   [(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")])
   [(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")])
   [(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")])
index 52e951f97eef2ec7718e6b89fb40307f47cbba59..557dc196b389a522299fad2de13dd7868a7a4d83 100644 (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))
index bf6d57529266de71d7df97ebb825bcdf72bc76c0..38ba919f115abe387795afd8099739e5f2752478 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -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)
index 5da49e52e5614c911d972ba5ff491cec70213676..5dbe031c8552be011bc88aaf73224e4e67db1714 100644 (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>
 
index 93d1eab077136616887b202b8dbe5a0106747ee1..5709f54877de7626b360303ddf0de2d09cdf4d88 100644 (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
index 3ef556eb42b3904dc71076e815e2ed61d6ab9be1..d0e2b27bf0e69ca8a80e6271f853038f0ebd5166 100644 (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).  */
index e7cee978bfe820ce17fab2d0ff986d4fbb8a456a..dda3102cfae34d534b1ecd13af8654eb36f4512d 100644 (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)))
        {
index 06c25fd321ca3682ecef07f3d712fa73950371aa..ceb7d49db2dd4dd00ae660a16c747c25c3517a84 100644 (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:
index 660e8732c40919c15e4dee1c5aca786400657fec..0f3be5b1db677e02d9d3e6f7d137f483d219a39a 100644 (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
index 7a436e5de9dae9f7f812b2dd0ccbfc0e2b9142fc..f88bdc2a5692bfb4e48c5b076836323174e245eb 100644 (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
index 5193ef2aa568dd423ca2a26a37e0845013485a22..c6bbd7ae086b694cf4d4002fa68f1719518953f4 100644 (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)
index 544c16bb75d7a8c002834cd9a1be09da069ea781..f6f524e5e33d3563aa9259a515c0edac931afa91 100644 (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
index aa7108add4b58ee0a15a117603b730a6e2955e8b..bde10d4cde4e8a3ee84d9fcd45e124cf6eaac019 100644 (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;
index 43d650c387db78fb0f9e897087c2c8cdbbe3fdab..dd7d2e1e6b5ef6d156acdee618cc653fda4f7f90 100644 (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;
index 680820c2a31eed39b22f14415bc8028fd0bdff6f..6bddc9c3690013feda83e2bd774f1bbcdbebe908 100644 (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;
+}
+
 \f
 /* 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,
index 08c6112d6b9f7d536ccd47a3a78321deacb681cf..0e9e10bdad4af61111f1ed929c2f693349c32cc3 100644 (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 */