This does away with enabling -ffinite-loops at -O2+ for all languages and instead enables it selectively for C++ only.
Jason, I didn't find a reference as to when the forward progress guarantee was introduced to C++ so I randomly chose C++11, is that correct? Joseph, this simply never enables -ffinite-loops for C by default also based on the fact this was added in the first place for C++ standard library abstraction removal thus without any real-world C testcases. Bootstrap / regtest in progress - I expect I need to add explicit -ffinite-loops to a few testcases (and fixup the changelog). I did not look whether other languages guarantee forward progress but the feature is new in GCC 10 and restricting it to C++ is sensible I think. Any further comments? Writing a runtime testcase is hard since by definition it would not finish. I'll construct a scan-tree-dump one. Thanks, Richard. 2020-04-01 Richard Biener <rguent...@suse.de> PR c/94392 * c-opts.c (): Enable -ffinite-loops for -O2 and C++11. * common.opt (ffinite-loops): Initialize to zero. * opts.c (default_options_table): Remove OPT_ffinite_loops entry. * ipa-inline.c (): Match up -ffinite-loops. * doc/invoke.texi (ffinite-loops): Adjust documentation of default setting. --- gcc/c-family/c-opts.c | 4 ++++ gcc/common.opt | 2 +- gcc/doc/invoke.texi | 3 ++- gcc/ipa-inline.c | 5 ++++- gcc/opts.c | 1 - 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index 6b6c754ad86..58ba0948e79 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -989,6 +989,10 @@ c_common_post_options (const char **pfilename) SET_OPTION_IF_UNSET (&global_options, &global_options_set, flag_new_ttp, cxx_dialect >= cxx17); + /* C++11 guarantees forward progress. */ + SET_OPTION_IF_UNSET (&global_options, &global_options_set, flag_finite_loops, + optimize >= 2 && cxx_dialect >= cxx11); + if (cxx_dialect >= cxx11) { /* If we're allowing C++0x constructs, don't warn about C++98 diff --git a/gcc/common.opt b/gcc/common.opt index 4368910cb54..bb2ea4c905d 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1490,7 +1490,7 @@ Common Report Var(flag_finite_math_only) Optimization SetByCombined Assume no NaNs or infinities are generated. ffinite-loops -Common Report Var(flag_finite_loops) Optimization +Common Report Var(flag_finite_loops) Optimization Init(0) Assume that loops with an exit will terminate and not loop indefinitely. ffixed- diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 412750c1fc9..142bfeacead 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -10432,7 +10432,8 @@ Assume that a loop with an exit will eventually take the exit and not loop indefinitely. This allows the compiler to remove loops that otherwise have no side-effects, not considering eventual endless looping as such. -This option is enabled by default at @option{-O2}. +This option is enabled by default at @option{-O2} for C++ with -std=c++11 +or higher. @item -ftree-dominator-opts @opindex ftree-dominator-opts diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 302ce16a646..d0e59d431ca 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -512,7 +512,10 @@ can_inline_edge_by_limits_p (struct cgraph_edge *e, bool report, /* When devirtualization is disabled for callee, it is not safe to inline it as we possibly mangled the type info. Allow early inlining of always inlines. */ - || (!early && check_maybe_down (flag_devirtualize))) + || (!early && check_maybe_down (flag_devirtualize)) + /* It's not safe to inline a function where loops maybe + infinite into a function where we assume the reverse. */ + || check_maybe_down (flag_finite_loops)) { e->inline_failed = CIF_OPTIMIZATION_MISMATCH; inlinable = false; diff --git a/gcc/opts.c b/gcc/opts.c index 5dc7d65dedd..d4df8627bf7 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -478,7 +478,6 @@ static const struct default_options default_options_table[] = { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 }, { OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 }, { OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 }, - { OPT_LEVELS_2_PLUS, OPT_ffinite_loops, NULL, 1 }, { OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 }, { OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 }, { OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 }, -- 2.25.1