This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix up -fexcess-precision handling in LTO (was Re: [GCC][middle-end] Add rules to strip away unneeded type casts in expressions (2nd patch))


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?

2019-07-30  Jakub Jelinek  <jakub@redhat.com>

	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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]