On Tue, 30 Jul 2019, Jakub Jelinek wrote: > On Tue, Jul 02, 2019 at 04:43:54PM +0000, Tamar Christina wrote: > > Here's an updated patch with the changes processed from the previous review. > > > > I've bootstrapped and regtested on aarch64-none-linux-gnu and x86_64-pc-linux-gnu and no issues. > > These changes also broke gcc.dg/torture/c99-contract-1.c with -flto > on i686-linux. > > The problem is that after moving the folding from convert.c to match.pd, > it is now performed not only during FE folding, but also much later on, > including post-IPA optimizations in lto1. The C FE arranges > flag_excess_precision_cmdline and flag_excess_precision to be > EXCESS_PRECISION_STANDARD and thus on i686-linux floating point arithmetics > is performed in long double, but the lto1 FE has both set to > EXCESS_PRECISION_FAST and undoes that widening. > > There seems to be quite complicated distinction between > flag_excess_precision_cmdline and flag_excess_precision, but it seems > that these days it is unnecessary, flag_excess_precision is only ever set > from flag_excess_precision_cmdline, perhaps in the past targets used to > modify flag_excess_precision, but they don't do that anymore. > > Furthermore, some comments claimed that the proper EXCESS_PRECISION_STANDARD > handling requires FE support, but that also doesn't seem to be the case > these days, some FEs even just use EXCESS_PRECISION_STANDARD by default > (go, D). > > So, the following patch gets rid of flag_excess_precision and renames > flag_excess_precision_cmdline to flag_excess_precision, plus adds > Optimization flag to that command line option, so that we remember it during > compilation and e.g. during LTO can then have some functions with standard > excess precision and others with fast excess precision. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Looks OK to me but I'd like Joseph to chime in here. I think for FE support it means adding actual _widening_ casts to the effective compute precision type (thus long double). But once that's done the rest should be indeed FE independent (but I doubt D and go get it correct). Thanks, Richard. > 2019-07-30 Jakub Jelinek > > PR middle-end/91283 > * common.opt (fexcess-precision=): Add Optimization flag. Use > flag_excess_precision variable instead of > flag_excess_precision_cmdline. > * flags.h (class target_flag_state): Remove x_flag_excess_precision > member. > (flag_excess_precision): Don't define. > * langhooks.c (lhd_post_options): Set flag_excess_precision instead of > flag_excess_precision_cmdline. Remove comment. > * opts.c (set_fast_math_flags): Use frontend_set_flag_excess_precision > and x_flag_excess_precision instead of > frontend_set_flag_excess_precision_cmdline and > x_flag_excess_precision_cmdline. > (fast_math_flags_set_p): Use x_flag_excess_precision instead of > x_flag_excess_precision_cmdline. > * toplev.c (init_excess_precision): Remove. > (lang_dependent_init_target): Don't call it. > ada/ > * gcc-interface/misc.c (gnat_post_options): Set flag_excess_precision > instead of flag_excess_precision_cmdline. > brig/ > * brig-lang.c (brig_langhook_post_options): Set flag_excess_precision > instead of flag_excess_precision_cmdline. > c-family/ > * c-common.c (c_ts18661_flt_eval_method): Use flag_excess_precision > instead of flag_excess_precision_cmdline. > * c-cppbuiltin.c (c_cpp_flt_eval_method_iec_559): Likewise. > * c-opts.c (c_common_post_options): Likewise. > d/ > * d-lang.cc (d_post_options): Set flag_excess_precision instead of > flag_excess_precision_cmdline. > fortran/ > * options.c (gfc_post_options): Set flag_excess_precision instead of > flag_excess_precision_cmdline. Remove comment. > go/ > * go-lang.c (go_langhook_post_options): Set flag_excess_precision > instead of flag_excess_precision_cmdline. > lto/ > * lto-lang.c (lto_post_options): Set flag_excess_precision instead of > flag_excess_precision_cmdline. Remove comment. > > --- gcc/common.opt.jj 2019-07-29 12:56:38.968248060 +0200 > +++ gcc/common.opt 2019-07-29 13:01:24.067067583 +0200 > @@ -1399,7 +1399,7 @@ Common Report Var(flag_expensive_optimiz > Perform a number of minor, expensive optimizations. > > fexcess-precision= > -Common Joined RejectNegative Enum(excess_precision) Var(flag_excess_precision_cmdline) Init(EXCESS_PRECISION_DEFAULT) SetByCombined > +Common Joined RejectNegative Enum(excess_precision) Var(flag_excess_precision) Init(EXCESS_PRECISION_DEFAULT) Optimization SetByCombined > -fexcess-precision=[fast|standard] Specify handling of excess floating-point precision. > > Enum > --- gcc/flags.h.jj 2019-07-10 15:52:20.362155642 +0200 > +++ gcc/flags.h 2019-07-29 13:02:05.488460207 +0200 > @@ -51,9 +51,6 @@ public: > align_flags x_align_jumps; > align_flags x_align_labels; > align_flags x_align_functions; > - > - /* The excess precision currently in effect. */ > - enum excess_precision x_flag_excess_precision; > }; > > extern class target_flag_state default_target_flag_state; > @@ -68,12 +65,6 @@ extern class target_flag_state *this_tar > #define align_labels (this_target_flag_state->x_align_labels) > #define align_functions (this_target_flag_state->x_align_functions) > > -/* String representaions of the above options are available in > - const char *str_align_foo. NULL if not set. */ > - > -#define flag_excess_precision \ > - (this_target_flag_state->x_flag_excess_precision) > - > /* Returns TRUE if generated code should match ABI version N or > greater is in use. */ > > --- gcc/langhooks.c.jj 2019-01-01 12:37:19.531936001 +0100 > +++ gcc/langhooks.c 2019-07-29 13:10:35.053988315 +0200 > @@ -95,9 +95,7 @@ lhd_return_null_const_tree (const_tree A > bool > lhd_post_options (const char ** ARG_UNUSED (pfilename)) > { > - /* Excess precision other than "fast" requires front-end > - support. */ > - flag_excess_precision_cmdline = EXCESS_PRECISION_FAST; > + flag_excess_precision = EXCESS_PRECISION_FAST; > return false; > } > > --- gcc/opts.c.jj 2019-07-29 12:56:38.000000000 +0200 > +++ gcc/opts.c 2019-07-29 13:02:40.522946490 +0200 > @@ -2962,9 +2962,8 @@ set_fast_math_flags (struct gcc_options > opts->x_flag_errno_math = !set; > if (set) > { > - if (opts->frontend_set_flag_excess_precision_cmdline > - == EXCESS_PRECISION_DEFAULT) > - opts->x_flag_excess_precision_cmdline > + 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; > @@ -2999,8 +2998,7 @@ fast_math_flags_set_p (const struct gcc_ > && opts->x_flag_finite_math_only > && !opts->x_flag_signed_zeros > && !opts->x_flag_errno_math > - && opts->x_flag_excess_precision_cmdline > - == EXCESS_PRECISION_FAST); > + && opts->x_flag_excess_precision == EXCESS_PRECISION_FAST); > } > > /* Return true iff flags are set as if -ffast-math but using the flags stored > --- gcc/toplev.c.jj 2019-07-28 17:29:31.246291937 +0200 > +++ gcc/toplev.c 2019-07-29 13:08:49.601534597 +0200 > @@ -1849,27 +1849,11 @@ backend_init (void) > init_regs (); > } > > -/* Initialize excess precision settings. > - > - We have no need to modify anything here, just keep track of what the > - user requested. We'll figure out any appropriate relaxations > - later. */ > - > -static void > -init_excess_precision (void) > -{ > - gcc_assert (flag_excess_precision_cmdline != EXCESS_PRECISION_DEFAULT); > - flag_excess_precision = flag_excess_precision_cmdline; > -} > - > /* Initialize things that are both lang-dependent and target-dependent. > This function can be called more than once if target parameters change. */ > static void > lang_dependent_init_target (void) > { > - /* This determines excess precision settings. */ > - init_excess_precision (); > - > /* This creates various _DECL nodes, so needs to be called after the > front end is initialized. It also depends on the HAVE_xxx macros > generated from the target machine description. */ > --- gcc/c-family/c-common.c.jj 2019-07-04 00:18:32.052090626 +0200 > +++ gcc/c-family/c-common.c 2019-07-29 13:12:05.762659524 +0200 > @@ -8342,7 +8342,7 @@ c_ts18661_flt_eval_method (void) > = targetm.c.excess_precision (EXCESS_PRECISION_TYPE_IMPLICIT); > > enum excess_precision_type flag_type > - = (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD > + = (flag_excess_precision == EXCESS_PRECISION_STANDARD > ? EXCESS_PRECISION_TYPE_STANDARD > : EXCESS_PRECISION_TYPE_FAST); > > --- gcc/c-family/c-cppbuiltin.c.jj 2019-01-16 09:35:04.563323106 +0100 > +++ gcc/c-family/c-cppbuiltin.c 2019-07-29 13:11:06.124532722 +0200 > @@ -746,7 +746,7 @@ static bool > c_cpp_flt_eval_method_iec_559 (void) > { > enum excess_precision_type front_end_ept > - = (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD > + = (flag_excess_precision == EXCESS_PRECISION_STANDARD > ? EXCESS_PRECISION_TYPE_STANDARD > : EXCESS_PRECISION_TYPE_FAST); > > --- gcc/c-family/c-opts.c.jj 2019-07-10 15:52:20.364155611 +0200 > +++ gcc/c-family/c-opts.c 2019-07-29 13:11:37.110078371 +0200 > @@ -800,14 +800,13 @@ c_common_post_options (const char **pfil > support. */ > if (c_dialect_cxx ()) > { > - if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD) > + if (flag_excess_precision == EXCESS_PRECISION_STANDARD) > sorry ("%<-fexcess-precision=standard%> for C++"); > - flag_excess_precision_cmdline = EXCESS_PRECISION_FAST; > + flag_excess_precision = EXCESS_PRECISION_FAST; > } > - else if (flag_excess_precision_cmdline == EXCESS_PRECISION_DEFAULT) > - flag_excess_precision_cmdline = (flag_iso > - ? EXCESS_PRECISION_STANDARD > - : EXCESS_PRECISION_FAST); > + else if (flag_excess_precision == EXCESS_PRECISION_DEFAULT) > + flag_excess_precision = (flag_iso ? EXCESS_PRECISION_STANDARD > + : EXCESS_PRECISION_FAST); > > /* ISO C restricts floating-point expression contraction to within > source-language expressions (-ffp-contract=on, currently an alias > --- gcc/ada/gcc-interface/misc.c.jj 2019-03-11 22:56:52.475722730 +0100 > +++ gcc/ada/gcc-interface/misc.c 2019-07-29 13:08:05.768177333 +0200 > @@ -255,9 +255,9 @@ static bool > gnat_post_options (const char **pfilename ATTRIBUTE_UNUSED) > { > /* Excess precision other than "fast" requires front-end support. */ > - if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD) > + if (flag_excess_precision == EXCESS_PRECISION_STANDARD) > sorry ("%<-fexcess-precision=standard%> for Ada"); > - flag_excess_precision_cmdline = EXCESS_PRECISION_FAST; > + flag_excess_precision = EXCESS_PRECISION_FAST; > > /* No psABI change warnings for Ada. */ > warn_psabi = 0; > --- gcc/brig/brig-lang.c.jj 2019-06-25 16:03:28.221358420 +0200 > +++ gcc/brig/brig-lang.c 2019-07-29 13:09:20.341083849 +0200 > @@ -166,8 +166,8 @@ brig_langhook_handle_option > static bool > brig_langhook_post_options (const char **pfilename ATTRIBUTE_UNUSED) > { > - if (flag_excess_precision_cmdline == EXCESS_PRECISION_DEFAULT) > - flag_excess_precision_cmdline = EXCESS_PRECISION_STANDARD; > + if (flag_excess_precision == EXCESS_PRECISION_DEFAULT) > + flag_excess_precision = EXCESS_PRECISION_STANDARD; > > /* gccbrig casts pointers around like crazy, TBAA might produce broken > code if not disabling it by default. Some PRM conformance tests such > --- gcc/d/d-lang.cc.jj 2019-05-20 11:39:15.581117453 +0200 > +++ gcc/d/d-lang.cc 2019-07-29 13:10:05.205425991 +0200 > @@ -772,8 +772,8 @@ d_post_options (const char ** fn) > if (global_options_set.x_flag_max_errors) > global.errorLimit = flag_max_errors; > > - if (flag_excess_precision_cmdline == EXCESS_PRECISION_DEFAULT) > - flag_excess_precision_cmdline = EXCESS_PRECISION_STANDARD; > + if (flag_excess_precision == EXCESS_PRECISION_DEFAULT) > + flag_excess_precision = EXCESS_PRECISION_STANDARD; > > if (global.params.useUnitTests) > global.params.useAssert = true; > --- gcc/fortran/options.c.jj 2019-07-17 09:02:50.211382394 +0200 > +++ gcc/fortran/options.c 2019-07-29 13:07:34.492635929 +0200 > @@ -262,11 +262,9 @@ gfc_post_options (const char **pfilename > /* Finalize DEC flags. */ > post_dec_flags (flag_dec); > > - /* Excess precision other than "fast" requires front-end > - support. */ > - if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD) > + if (flag_excess_precision == EXCESS_PRECISION_STANDARD) > sorry ("%<-fexcess-precision=standard%> for Fortran"); > - flag_excess_precision_cmdline = EXCESS_PRECISION_FAST; > + flag_excess_precision = EXCESS_PRECISION_FAST; > > /* Fortran allows associative math - but we cannot reassociate if > we want traps or signed zeros. Cf. also flag_protect_parens. */ > --- gcc/go/go-lang.c.jj 2019-05-08 09:18:28.516742244 +0200 > +++ gcc/go/go-lang.c 2019-07-29 13:09:41.755769840 +0200 > @@ -293,8 +293,8 @@ go_langhook_post_options (const char **p > go_add_search_path (dir); > go_search_dirs.release (); > > - if (flag_excess_precision_cmdline == EXCESS_PRECISION_DEFAULT) > - flag_excess_precision_cmdline = EXCESS_PRECISION_STANDARD; > + if (flag_excess_precision == EXCESS_PRECISION_DEFAULT) > + flag_excess_precision = EXCESS_PRECISION_STANDARD; > > /* Tail call optimizations can confuse uses of runtime.Callers. */ > if (!global_options_set.x_flag_optimize_sibling_calls) > --- gcc/lto/lto-lang.c.jj 2019-06-25 16:03:29.794334463 +0200 > +++ gcc/lto/lto-lang.c 2019-07-29 13:06:52.453252365 +0200 > @@ -925,9 +925,8 @@ lto_post_options (const char **pfilename > break; > } > > - /* Excess precision other than "fast" requires front-end > - support. */ > - flag_excess_precision_cmdline = EXCESS_PRECISION_FAST; > + if (flag_excess_precision == EXCESS_PRECISION_DEFAULT) > + flag_excess_precision = EXCESS_PRECISION_FAST; > > /* When partitioning, we can tear appart STRING_CSTs uses from the same > TU into multiple partitions. Without constant merging the constants > > > Jakub > -- Richard Biener SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG Nürnberg)