This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR60319, mixing -f[no-]strict-overflow units with LTO
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Jan Hubicka <hubicka at ucw dot cz>
- Date: Mon, 24 Feb 2014 18:14:02 +0100 (CET)
- Subject: [PATCH] Fix PR60319, mixing -f[no-]strict-overflow units with LTO
- Authentication-results: sourceware.org; auth=none
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: