+2020-04-02 Richard Biener <rguenther@suse.de>
+
+ PR c/94392
+ * common.opt (ffinite-loops): Initialize to zero.
+ * opts.c (default_options_table): Remove OPT_ffinite_loops
+ entry.
+ * cfgloop.h (loop::finite_p): New member.
+ * cfgloopmanip.c (copy_loop_info): Copy finite_p.
+ * ipa-icf-gimple.c (func_checker::compare_loops): Compare
+ finite_p.
+ * lto-streamer-in.c (input_cfg): Stream finite_p.
+ * lto-streamer-out.c (output_cfg): Likewise.
+ * tree-cfg.c (replace_loop_annotate): Initialize finite_p
+ from flag_finite_loops at CFG build time.
+ * tree-ssa-loop-niter.c (finite_loop_p): Check the loops
+ finite_p flag instead of flag_finite_loops.
+ * doc/invoke.texi (ffinite-loops): Adjust documentation of
+ default setting.
+
2020-04-02 Richard Biener <rguenther@suse.de>
PR debug/94450
+2020-04-02 Richard Biener <rguenther@suse.de>
+
+ PR c/94392
+ * c-opts.c (c_common_post_options): Enable -ffinite-loops
+ for -O2 and C++11 or newer.
+
2020-03-28 Patrick Palka <ppalka@redhat.com>
* c.opt: Add -fconcepts-diagnostics-depth.
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
/* True if the loop is part of an oacc kernels region. */
unsigned in_oacc_kernels_region : 1;
+ /* True if the loop is known to be finite. This is a localized
+ flag_finite_loops or similar pragmas state. */
+ unsigned finite_p : 1;
+
/* The number of times to unroll the loop. 0 means no information given,
just do what we always do. A value of 1 means do not unroll the loop.
A value of USHRT_MAX means unroll with no specific unrolling factor.
target->dont_vectorize = loop->dont_vectorize;
target->force_vectorize = loop->force_vectorize;
target->in_oacc_kernels_region = loop->in_oacc_kernels_region;
+ target->finite_p = loop->finite_p;
target->unroll = loop->unroll;
target->owned_clique = loop->owned_clique;
}
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-
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
return return_false_with_msg ("dont_vectorize");
if (l1->force_vectorize != l2->force_vectorize)
return return_false_with_msg ("force_vectorize");
+ if (l1->finite_p != l2->finite_p)
+ return return_false_with_msg ("finite_p");
if (l1->unroll != l2->unroll)
return return_false_with_msg ("unroll");
if (!compare_variable_decl (l1->simduid, l2->simduid))
loop->owned_clique = streamer_read_hwi (ib);
loop->dont_vectorize = streamer_read_hwi (ib);
loop->force_vectorize = streamer_read_hwi (ib);
+ loop->finite_p = streamer_read_hwi (ib);
loop->simduid = stream_read_tree (ib, data_in);
place_new_loop (fn, loop);
streamer_write_hwi (ob, loop->owned_clique);
streamer_write_hwi (ob, loop->dont_vectorize);
streamer_write_hwi (ob, loop->force_vectorize);
+ streamer_write_hwi (ob, loop->finite_p);
stream_write_tree (ob, loop->simduid, true);
}
{ 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 },
+2020-04-02 Richard Biener <rguenther@suse.de>
+
+ PR c/94392
+ * gcc.dg/torture/pr94392.c: New testcase.
+
2020-04-02 Jakub Jelinek <jakub@redhat.com>
PR target/94435
--- /dev/null
+/* { dg-do compile } */
+/* { dg-skip-if "finite loops" { *-*-* } { "-ffinite-loops" } } */
+/* { dg-skip-if "LTO optimizes the test" { *-*-* } { "-flto" } } */
+/* { dg-additional-options "-fdump-tree-optimized" } */
+
+int a, b;
+
+int
+main()
+{
+ while (1)
+ {
+ /* Try really hard. */
+ if (a != b)
+ return 1;
+ }
+ return 0;
+}
+
+/* ISO C does not guarantee forward progress like C++ does so we
+ cannot assume the loop is finite and optimize it to return 1. */
+/* { dg-final { scan-tree-dump "if" "optimized" } } */
/* Then look into the latch, if any. */
if (loop->latch)
replace_loop_annotate_in_block (loop->latch, loop);
+
+ /* Push the global flag_finite_loops state down to individual loops. */
+ loop->finite_p = flag_finite_loops;
}
/* Remove IFN_ANNOTATE. Safeguard for the case loop->latch == NULL. */
return true;
}
- if (flag_finite_loops)
+ if (loop->finite_p)
{
unsigned i;
vec<edge> exits = get_loop_exit_edges (loop);