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 <rguent...@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: