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]

[PATCH] Fix PR60319, mixing -f[no-]strict-overflow units with LTO


This addresses miscompilations caused by improperly mixing
-f[no-]strict-overflow units (and thus optimize <= 1 and optimize >= 2
units!).  It does so by merging -f[no-]strict-overflow and the
related -f[no-]wrapv and -f[no-]trapv conservatively, that is,
if any unit uses (implicitely) -fno-strict-overflow, -fwrapv
or -fno-trapv then force that upon the compilation in and after
WPA stage.

I know honza wants to eventually handle this via optimize attributes
but currently at least -fstrict-overflow is not suitable for that
(it's not marked 'Optimization').  Nor do we even check for
-f[no-]wrapv mismatch in can_inline_edge_p.

LTO bootstrap & test ongoing on x86_64-unknown-linux-gnu, ok for trunk?

Any other "obvious" candidates for conservative merging?

Note that this makes it quite harmful (well - maybe?) if your
LTO compile contains a single non-optimized TU ... but you
at least know if you inspect the lto_opts section of one of the
ltrans files.

Eventually this asks for a diagnostic by lto-wrapper (but that
gets delayed until very late ...).

Thanks,
Richard.

2014-02-24  Richard Biener  <rguenther@suse.de>

	PR lto/60319
	* lto-opts.c (lto_write_options): Output non-explicit conservative
	-fwrapv, -fno-trapv and -fno-strict-overflow.
	* lto-wrapper.c (merge_and_complain): Handle merging those options.
	(run_gcc): And pass them through.

Index: gcc/lto-opts.c
===================================================================
*** gcc/lto-opts.c	(revision 208077)
--- gcc/lto-opts.c	(working copy)
*************** lto_write_options (void)
*** 117,122 ****
--- 117,134 ----
        default:
  	gcc_unreachable ();
        }
+   /* We need to merge -f[no-]strict-overflow, -f[no-]wrapv and -f[no-]trapv
+      conservatively, so stream out their defaults.  */
+   if (!global_options_set.x_flag_wrapv
+       && global_options.x_flag_wrapv)
+     append_to_collect_gcc_options (&temporary_obstack, &first_p, "-fwrapv");
+   if (!global_options_set.x_flag_trapv
+       && !global_options.x_flag_trapv)
+     append_to_collect_gcc_options (&temporary_obstack, &first_p, "-fno-trapv");
+   if (!global_options_set.x_flag_strict_overflow
+       && !global_options.x_flag_strict_overflow)
+     append_to_collect_gcc_options (&temporary_obstack, &first_p,
+ 			       "-fno-strict-overflow");
  
    /* Output explicitly passed options.  */
    for (i = 1; i < save_decoded_options_count; ++i)
Index: gcc/lto-wrapper.c
===================================================================
*** gcc/lto-wrapper.c	(revision 208077)
--- gcc/lto-wrapper.c	(working copy)
*************** merge_and_complain (struct cl_decoded_op
*** 422,427 ****
--- 422,429 ----
  	    append_option (decoded_options, decoded_options_count, foption);
  	  break;
  
+ 	case OPT_ftrapv:
+ 	case OPT_fstrict_overflow:
  	case OPT_ffp_contract_:
  	  /* For selected options we can merge conservatively.  */
  	  for (j = 0; j < *decoded_options_count; ++j)
*************** merge_and_complain (struct cl_decoded_op
*** 429,439 ****
  	      break;
  	  if (j == *decoded_options_count)
  	    append_option (decoded_options, decoded_options_count, foption);
! 	  /* FP_CONTRACT_OFF < FP_CONTRACT_ON < FP_CONTRACT_FAST.  */
  	  else if (foption->value < (*decoded_options)[j].value)
  	    (*decoded_options)[j] = *foption;
  	  break;
  
  	case OPT_freg_struct_return:
  	case OPT_fpcc_struct_return:
  	  for (j = 0; j < *decoded_options_count; ++j)
--- 431,455 ----
  	      break;
  	  if (j == *decoded_options_count)
  	    append_option (decoded_options, decoded_options_count, foption);
! 	  /* FP_CONTRACT_OFF < FP_CONTRACT_ON < FP_CONTRACT_FAST,
! 	     -fno-trapv < -ftrapv,
! 	     -fno-strict-overflow < -fstrict-overflow  */
  	  else if (foption->value < (*decoded_options)[j].value)
  	    (*decoded_options)[j] = *foption;
  	  break;
  
+ 	case OPT_fwrapv:
+ 	  /* For selected options we can merge conservatively.  */
+ 	  for (j = 0; j < *decoded_options_count; ++j)
+ 	    if ((*decoded_options)[j].opt_index == foption->opt_index)
+ 	      break;
+ 	  if (j == *decoded_options_count)
+ 	    append_option (decoded_options, decoded_options_count, foption);
+ 	  /* -fwrapv > -fno-wrapv.  */
+ 	  else if (foption->value > (*decoded_options)[j].value)
+ 	    (*decoded_options)[j] = *foption;
+ 	  break;
+ 
  	case OPT_freg_struct_return:
  	case OPT_fpcc_struct_return:
  	  for (j = 0; j < *decoded_options_count; ++j)
*************** run_gcc (unsigned argc, char *argv[])
*** 591,596 ****
--- 607,615 ----
  	case OPT_freg_struct_return:
  	case OPT_fpcc_struct_return:
  	case OPT_ffp_contract_:
+ 	case OPT_fwrapv:
+ 	case OPT_ftrapv:
+ 	case OPT_fstrict_overflow:
  	  break;
  
  	default:


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