diff options
author | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2020-11-24 10:32:20 +0100 |
---|---|---|
committer | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2020-11-24 11:50:10 +0100 |
commit | c4fa3728ab4f78984a549894e0e8c4d6a253e540 (patch) | |
tree | 94d3ddbc78651d5b3d7032d558bf359737c21cfc /gcc/opts.c | |
parent | 607695354a57bce732b027828614bceda0e393eb (diff) | |
download | gcc-c4fa3728ab4f78984a549894e0e8c4d6a253e540.zip gcc-c4fa3728ab4f78984a549894e0e8c4d6a253e540.tar.gz gcc-c4fa3728ab4f78984a549894e0e8c4d6a253e540.tar.bz2 |
Fix -ffast-math flags handling inconsistencies
This patch implements the following set of changes:
1. If a component flag of -ffast-math (or -funsafe-math-optimizations)
is explicitly set (or reset) on the command line, this should override
any implicit change due to -f(no-)fast-math, no matter in which order
the flags come on the command line. This change affects all flags.
2. Any component flag modified from its default by -ffast-math should
be reset to the default by -fno-fast-math. This was previously
not done for the following flags:
-fcx-limited-range
-fexcess-precision=
3. Once -ffinite-math-only is true, the -f(no-)signaling-nans flag has
no meaning (if we have no NaNs at all, it does not matter whether
there is a difference between quiet and signaling NaNs). Therefore,
it does not make sense for -ffast-math to imply -fno-signaling-nans.
(This is also a documentation change.)
4. -ffast-math is documented to imply -fno-rounding-math, however the
latter setting is the default anyway; therefore it does not make
sense to try to modify it from its default setting.
5. The __FAST_MATH__ preprocessor macro should be defined if and only
if all the component flags of -ffast-math are set to the value that
is documented as the effect of -ffast-math. The following flags
were currently *not* so tested:
-fcx-limited-range
-fassociative-math
-freciprocal-math
-frounding-math
(Note that we should still *test* for -fno-rounding-math here even
though it is not set as to 4. -ffast-math -frounding-math should
not set the __FAST_MATH__ macro.)
This is also a documentation change.
2020-11-24 Ulrich Weigand <uweigand@de.ibm.com>
gcc/
* doc/invoke.texi (-ffast-math): Remove mention of -fno-signaling-nans.
Clarify conditions when __FAST_MATH__ preprocessor macro is defined.
* opts.c (common_handle_option): Pass OPTS_SET to set_fast_math_flags
and set_unsafe_math_optimizations_flags.
(set_fast_math_flags): Add OPTS_SET argument, and use it to avoid
setting flags already explicitly set on the command line. In the !set
case, also reset x_flag_cx_limited_range and x_flag_excess_precision.
Never reset x_flag_signaling_nans or x_flag_rounding_math.
(set_unsafe_math_optimizations_flags): Add OPTS_SET argument, and use
it to avoid setting flags already explicitly set on the command line.
(fast_math_flags_set_p): Also test x_flag_cx_limited_range,
x_flag_associative_math, x_flag_reciprocal_math, and
x_flag_rounding_math.
Diffstat (limited to 'gcc/opts.c')
-rw-r--r-- | gcc/opts.c | 58 |
1 files changed, 32 insertions, 26 deletions
@@ -193,10 +193,12 @@ static void set_debug_level (enum debug_info_type type, int extended, const char *arg, struct gcc_options *opts, struct gcc_options *opts_set, location_t loc); -static void set_fast_math_flags (struct gcc_options *opts, int set); +static void set_fast_math_flags (struct gcc_options *opts, + struct gcc_options *opts_set, int set); static void decode_d_option (const char *arg, struct gcc_options *opts, location_t loc, diagnostic_context *dc); static void set_unsafe_math_optimizations_flags (struct gcc_options *opts, + struct gcc_options *opts_set, int set); static void enable_warning_as_error (const char *arg, int value, unsigned int lang_mask, @@ -2491,11 +2493,11 @@ common_handle_option (struct gcc_options *opts, break; case OPT_ffast_math: - set_fast_math_flags (opts, value); + set_fast_math_flags (opts, opts_set, value); break; case OPT_funsafe_math_optimizations: - set_unsafe_math_optimizations_flags (opts, value); + set_unsafe_math_optimizations_flags (opts, opts_set, value); break; case OPT_ffixed_: @@ -2876,44 +2878,44 @@ set_Wstrict_aliasing (struct gcc_options *opts, int onoff) /* The following routines are useful in setting all the flags that -ffast-math and -fno-fast-math imply. */ static void -set_fast_math_flags (struct gcc_options *opts, int set) +set_fast_math_flags (struct gcc_options *opts, + struct gcc_options *opts_set, int set) { - if (!opts->frontend_set_flag_unsafe_math_optimizations) + if (!opts->frontend_set_flag_unsafe_math_optimizations + && !opts_set->x_flag_unsafe_math_optimizations) { opts->x_flag_unsafe_math_optimizations = set; - set_unsafe_math_optimizations_flags (opts, set); + set_unsafe_math_optimizations_flags (opts, opts_set, set); } if (!opts->frontend_set_flag_finite_math_only) - opts->x_flag_finite_math_only = set; + SET_OPTION_IF_UNSET (opts, opts_set, flag_finite_math_only, set); if (!opts->frontend_set_flag_errno_math) - opts->x_flag_errno_math = !set; - if (set) - { - if (opts->frontend_set_flag_excess_precision == EXCESS_PRECISION_DEFAULT) - opts->x_flag_excess_precision - = set ? EXCESS_PRECISION_FAST : EXCESS_PRECISION_DEFAULT; - if (!opts->frontend_set_flag_signaling_nans) - opts->x_flag_signaling_nans = 0; - if (!opts->frontend_set_flag_rounding_math) - opts->x_flag_rounding_math = 0; - if (!opts->frontend_set_flag_cx_limited_range) - opts->x_flag_cx_limited_range = 1; - } + SET_OPTION_IF_UNSET (opts, opts_set, flag_errno_math, !set); + if (!opts->frontend_set_flag_cx_limited_range) + SET_OPTION_IF_UNSET (opts, opts_set, flag_cx_limited_range, set); + if (!opts->frontend_set_flag_excess_precision) + SET_OPTION_IF_UNSET (opts, opts_set, flag_excess_precision, + set ? EXCESS_PRECISION_FAST + : EXCESS_PRECISION_DEFAULT); + + // -ffast-math should also reset -frounding-math, but since this + // is off by default, there's nothing to do for now. } /* When -funsafe-math-optimizations is set the following flags are set as well. */ static void -set_unsafe_math_optimizations_flags (struct gcc_options *opts, int set) +set_unsafe_math_optimizations_flags (struct gcc_options *opts, + struct gcc_options *opts_set, int set) { if (!opts->frontend_set_flag_trapping_math) - opts->x_flag_trapping_math = !set; + SET_OPTION_IF_UNSET (opts, opts_set, flag_trapping_math, !set); if (!opts->frontend_set_flag_signed_zeros) - opts->x_flag_signed_zeros = !set; + SET_OPTION_IF_UNSET (opts, opts_set, flag_signed_zeros, !set); if (!opts->frontend_set_flag_associative_math) - opts->x_flag_associative_math = set; + SET_OPTION_IF_UNSET (opts, opts_set, flag_associative_math, set); if (!opts->frontend_set_flag_reciprocal_math) - opts->x_flag_reciprocal_math = set; + SET_OPTION_IF_UNSET (opts, opts_set, flag_reciprocal_math, set); } /* Return true iff flags in OPTS are set as if -ffast-math. */ @@ -2921,10 +2923,14 @@ bool fast_math_flags_set_p (const struct gcc_options *opts) { return (!opts->x_flag_trapping_math + && !opts->x_flag_signed_zeros + && opts->x_flag_associative_math + && opts->x_flag_reciprocal_math && opts->x_flag_unsafe_math_optimizations && opts->x_flag_finite_math_only - && !opts->x_flag_signed_zeros && !opts->x_flag_errno_math + && !opts->x_flag_rounding_math + && opts->x_flag_cx_limited_range && opts->x_flag_excess_precision == EXCESS_PRECISION_FAST); } |