public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-5177] Enable pure-const discovery in modref.
@ 2021-11-11 17:15 Jan Hubicka
0 siblings, 0 replies; only message in thread
From: Jan Hubicka @ 2021-11-11 17:15 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:494bdadf28d0fb3505ff8dce5afa587e0ff46544
commit r12-5177-g494bdadf28d0fb3505ff8dce5afa587e0ff46544
Author: Jan Hubicka <jh@suse.cz>
Date: Thu Nov 11 18:14:45 2021 +0100
Enable pure-const discovery in modref.
We newly can handle some extra cases, for example:
struct a {int a,b,c;};
__attribute__ ((noinline))
int init (struct a *a)
{
a->a=1;
a->b=2;
a->c=3;
}
int const_fn ()
{
struct a a;
init (&a);
return a.a + a.b + a.c;
}
Here pure/const stops on the fact that const_fn calls non-const init, while
modref knows that the memory it initializes is local to const_fn.
I ended up reordering passes so early modref is done after early pure-const
mostly to avoid need to change testsuite which greps for const functions
being detects in pure-const. Stil some testuiste compensation is needed.
gcc/ChangeLog:
2021-11-11 Jan Hubicka <hubicka@ucw.cz>
* ipa-modref.c (analyze_function): Do pure/const discovery, return
true on success.
(pass_modref::execute): If pure/const is discovered fixup cfg.
(ignore_edge): Do not ignore pure/const edges.
(modref_propagate_in_scc): Do pure/const discovery, return true if
cdtor was promoted pure/const.
(pass_ipa_modref::execute): If needed remove unreachable functions.
* ipa-pure-const.c (warn_function_noreturn): Fix whitespace.
(warn_function_cold): Likewise.
(skip_function_for_local_pure_const): Move earlier.
(ipa_make_function_const): Break out from ...
(ipa_make_function_pure): Break out from ...
(propagate_pure_const): ... here.
(pass_local_pure_const::execute): Use it.
* ipa-utils.h (ipa_make_function_const): Declare.
(ipa_make_function_pure): Declare.
* passes.def: Move early modref after pure-const.
gcc/testsuite/ChangeLog:
2021-11-11 Jan Hubicka <hubicka@ucw.cz>
* c-c++-common/tm/inline-asm.c: Disable pure-const.
* g++.dg/ipa/modref-1.C: Update template.
* gcc.dg/tree-ssa/modref-11.c: Disable pure-const.
* gcc.dg/tree-ssa/modref-14.c: New test.
* gcc.dg/tree-ssa/modref-8.c: Do not optimize sibling calls.
* gfortran.dg/do_subscript_3.f90: Add -O0.
Diff:
---
gcc/ipa-modref.c | 85 ++++++++--
gcc/ipa-pure-const.c | 233 +++++++++++++--------------
gcc/ipa-utils.h | 2 +
gcc/passes.def | 2 +-
gcc/testsuite/c-c++-common/tm/inline-asm.c | 2 +-
gcc/testsuite/g++.dg/ipa/modref-1.C | 4 +-
gcc/testsuite/gcc.dg/tree-ssa/modref-11.c | 2 +-
gcc/testsuite/gcc.dg/tree-ssa/modref-14.c | 16 ++
gcc/testsuite/gcc.dg/tree-ssa/modref-8.c | 2 +-
gcc/testsuite/gfortran.dg/do_subscript_3.f90 | 1 +
10 files changed, 204 insertions(+), 145 deletions(-)
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index 45b391a565e..72006251f29 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -2603,11 +2603,13 @@ analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto,
}
/* Analyze function F. IPA indicates whether we're running in local mode
- (false) or the IPA mode (true). */
+ (false) or the IPA mode (true).
+ Return true if fixup cfg is needed after the pass. */
-static void
+static bool
analyze_function (function *f, bool ipa)
{
+ bool fixup_cfg = false;
if (dump_file)
fprintf (dump_file, "modref analyzing '%s' (ipa=%i)%s%s\n",
function_name (f), ipa,
@@ -2617,7 +2619,7 @@ analyze_function (function *f, bool ipa)
/* Don't analyze this function if it's compiled with -fno-strict-aliasing. */
if (!flag_ipa_modref
|| lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl)))
- return;
+ return false;
/* Compute no-LTO summaries when local optimization is going to happen. */
bool nolto = (!ipa || ((!flag_lto || flag_fat_lto_objects) && !in_lto_p)
@@ -2774,12 +2776,32 @@ analyze_function (function *f, bool ipa)
if (!summary->useful_p (ecf_flags, false))
{
remove_summary (lto, nolto, ipa);
- return;
+ return false;
}
}
first = false;
}
}
+ if (summary && !summary->global_memory_written_p () && !summary->side_effects
+ && !finite_function_p ())
+ summary->side_effects = true;
+ if (summary_lto && !summary_lto->side_effects && !finite_function_p ())
+ summary_lto->side_effects = true;
+
+ if (!ipa && flag_ipa_pure_const)
+ {
+ if (!summary->stores->every_base && !summary->stores->bases)
+ {
+ if (!summary->loads->every_base && !summary->loads->bases)
+ fixup_cfg = ipa_make_function_const
+ (cgraph_node::get (current_function_decl),
+ summary->side_effects, true);
+ else
+ fixup_cfg = ipa_make_function_pure
+ (cgraph_node::get (current_function_decl),
+ summary->side_effects, true);
+ }
+ }
if (summary && !summary->useful_p (ecf_flags))
{
if (!ipa)
@@ -2793,11 +2815,6 @@ analyze_function (function *f, bool ipa)
summaries_lto->remove (fnode);
summary_lto = NULL;
}
- if (summary && !summary->global_memory_written_p () && !summary->side_effects
- && !finite_function_p ())
- summary->side_effects = true;
- if (summary_lto && !summary_lto->side_effects && !finite_function_p ())
- summary_lto->side_effects = true;
if (ipa && !summary && !summary_lto)
remove_modref_edge_summaries (fnode);
@@ -2907,6 +2924,7 @@ analyze_function (function *f, bool ipa)
}
}
}
+ return fixup_cfg;
}
/* Callback for generate_summary. */
@@ -3714,7 +3732,8 @@ public:
unsigned int pass_modref::execute (function *f)
{
- analyze_function (f, false);
+ if (analyze_function (f, false))
+ return execute_fixup_cfg ();
return 0;
}
@@ -3749,9 +3768,7 @@ ignore_edge (struct cgraph_edge *e)
return (avail <= AVAIL_INTERPOSABLE
|| ((!optimization_summaries || !optimization_summaries->get (callee))
- && (!summaries_lto || !summaries_lto->get (callee)))
- || flags_from_decl_or_type (e->callee->decl)
- & (ECF_CONST | ECF_NOVOPS));
+ && (!summaries_lto || !summaries_lto->get (callee))));
}
/* Compute parm_map for CALLEE_EDGE. */
@@ -4130,7 +4147,7 @@ remove_useless_summaries (cgraph_node *node,
/* Perform iterative dataflow on SCC component starting in COMPONENT_NODE
and propagate loads/stores. */
-static void
+static bool
modref_propagate_in_scc (cgraph_node *component_node)
{
bool changed = true;
@@ -4352,6 +4369,38 @@ modref_propagate_in_scc (cgraph_node *component_node)
if (dump_file)
fprintf (dump_file,
"Propagation finished in %i iterations\n", iteration);
+ bool pureconst = false;
+ for (struct cgraph_node *cur = component_node; cur;
+ cur = ((struct ipa_dfs_info *) cur->aux)->next_cycle)
+ if (!cur->inlined_to && opt_for_fn (cur->decl, flag_ipa_pure_const))
+ {
+ modref_summary *summary = optimization_summaries
+ ? optimization_summaries->get (cur)
+ : NULL;
+ modref_summary_lto *summary_lto = summaries_lto
+ ? summaries_lto->get (cur)
+ : NULL;
+ if (summary && !summary->stores->every_base && !summary->stores->bases)
+ {
+ if (!summary->loads->every_base && !summary->loads->bases)
+ pureconst |= ipa_make_function_const
+ (cur, summary->side_effects, false);
+ else
+ pureconst |= ipa_make_function_pure
+ (cur, summary->side_effects, false);
+ }
+ if (summary_lto && !summary_lto->stores->every_base
+ && !summary_lto->stores->bases)
+ {
+ if (!summary_lto->loads->every_base && !summary_lto->loads->bases)
+ pureconst |= ipa_make_function_const
+ (cur, summary_lto->side_effects, false);
+ else
+ pureconst |= ipa_make_function_pure
+ (cur, summary_lto->side_effects, false);
+ }
+ }
+ return pureconst;
}
/* Dump results of propagation in SCC rooted in COMPONENT_NODE. */
@@ -4831,6 +4880,7 @@ pass_ipa_modref::execute (function *)
{
if (!summaries && !summaries_lto)
return 0;
+ bool pureconst = false;
if (optimization_summaries)
ggc_delete (optimization_summaries);
@@ -4853,7 +4903,7 @@ pass_ipa_modref::execute (function *)
if (dump_file)
fprintf (dump_file, "\n\nStart of SCC component\n");
- modref_propagate_in_scc (component_node);
+ pureconst |= modref_propagate_in_scc (component_node);
modref_propagate_flags_in_scc (component_node);
if (dump_file)
modref_propagate_dump_scc (component_node);
@@ -4869,7 +4919,10 @@ pass_ipa_modref::execute (function *)
fnspec_summaries = NULL;
delete escape_summaries;
escape_summaries = NULL;
- return 0;
+
+ /* If we posibly made constructors const/pure we may need to remove
+ them. */
+ return pureconst ? TODO_remove_functions : 0;
}
/* Summaries must stay alive until end of compilation. */
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index 422b52fba4b..550bdeded16 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -275,7 +275,7 @@ warn_function_noreturn (tree decl)
static hash_set<tree> *warned_about;
if (!lang_hooks.missing_noreturn_ok_p (decl)
&& targetm.warn_func_return (decl))
- warned_about
+ warned_about
= suggest_attribute (OPT_Wsuggest_attribute_noreturn, original_decl,
true, warned_about, "noreturn");
}
@@ -286,7 +286,7 @@ warn_function_cold (tree decl)
tree original_decl = decl;
static hash_set<tree> *warned_about;
- warned_about
+ warned_about
= suggest_attribute (OPT_Wsuggest_attribute_cold, original_decl,
true, warned_about, "cold");
}
@@ -1428,6 +1428,105 @@ ignore_edge_for_pure_const (struct cgraph_edge *e)
flag_ipa_pure_const));
}
+/* Return true if function should be skipped for local pure const analysis. */
+
+static bool
+skip_function_for_local_pure_const (struct cgraph_node *node)
+{
+ /* Because we do not schedule pass_fixup_cfg over whole program after early
+ optimizations we must not promote functions that are called by already
+ processed functions. */
+
+ if (function_called_by_processed_nodes_p ())
+ {
+ if (dump_file)
+ fprintf (dump_file, "Function called in recursive cycle; ignoring\n");
+ return true;
+ }
+ /* Save some work and do not analyze functions which are interposable and
+ do not have any non-interposable aliases. */
+ if (node->get_availability () <= AVAIL_INTERPOSABLE
+ && !flag_lto
+ && !node->has_aliases_p ())
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Function is interposable; not analyzing.\n");
+ return true;
+ }
+ return false;
+}
+
+/* Make function const and output warning. If LOCAL is true,
+ return true if anything changed. Otherwise return true if
+ we may have introduced removale ctors. */
+
+bool
+ipa_make_function_const (struct cgraph_node *node, bool looping, bool local)
+{
+ bool cdtor = false;
+
+ if (TREE_READONLY (node->decl)
+ && (looping || !DECL_LOOPING_CONST_OR_PURE_P (node->decl)))
+ return false;
+ warn_function_const (node->decl, !looping);
+ if (local && skip_function_for_local_pure_const (node))
+ return false;
+ if (dump_file)
+ fprintf (dump_file, "Function found to be %sconst: %s\n",
+ looping ? "looping " : "",
+ node->dump_name ());
+ if (!local)
+ cdtor = node->call_for_symbol_and_aliases (cdtor_p, NULL, true);
+ if (node->set_const_flag (true, looping))
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Declaration updated to be %sconst: %s\n",
+ looping ? "looping " : "",
+ node->dump_name ());
+ if (local)
+ return true;
+ return cdtor;
+ }
+ return false;
+}
+
+/* Make function const and output warning. If LOCAL is true,
+ return true if anything changed. Otherwise return true if
+ we may have introduced removale ctors. */
+
+bool
+ipa_make_function_pure (struct cgraph_node *node, bool looping, bool local)
+{
+ bool cdtor = false;
+
+ if (DECL_PURE_P (node->decl)
+ && (looping || DECL_LOOPING_CONST_OR_PURE_P (node->decl)))
+ return false;
+ warn_function_pure (node->decl, !looping);
+ if (local && skip_function_for_local_pure_const (node))
+ return false;
+ if (dump_file)
+ fprintf (dump_file, "Function found to be %spure: %s\n",
+ looping ? "looping " : "",
+ node->dump_name ());
+ if (!local)
+ cdtor = node->call_for_symbol_and_aliases (cdtor_p, NULL, true);
+ if (node->set_pure_flag (true, looping))
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Declaration updated to be %spure: %s\n",
+ looping ? "looping " : "",
+ node->dump_name ());
+ if (local)
+ return true;
+ return cdtor;
+ }
+ return false;
+}
+
/* Produce transitive closure over the callgraph and compute pure/const
attributes. */
@@ -1442,7 +1541,6 @@ propagate_pure_const (void)
int i;
struct ipa_dfs_info * w_info;
bool remove_p = false;
- bool has_cdtor;
order_pos = ipa_reduced_postorder (order, true,
ignore_edge_for_pure_const);
@@ -1513,6 +1611,9 @@ propagate_pure_const (void)
enum pure_const_state_e edge_state = IPA_CONST;
bool edge_looping = false;
+ if (e->recursive_p ())
+ looping = true;
+
if (e->recursive_p ())
looping = true;
@@ -1699,55 +1800,11 @@ propagate_pure_const (void)
switch (this_state)
{
case IPA_CONST:
- if (!TREE_READONLY (w->decl))
- {
- warn_function_const (w->decl, !this_looping);
- if (dump_file)
- fprintf (dump_file, "Function found to be %sconst: %s\n",
- this_looping ? "looping " : "",
- w->dump_name ());
- }
- /* Turning constructor or destructor to non-looping const/pure
- enables us to possibly remove the function completely. */
- if (this_looping)
- has_cdtor = false;
- else
- has_cdtor = w->call_for_symbol_and_aliases (cdtor_p,
- NULL, true);
- if (w->set_const_flag (true, this_looping))
- {
- if (dump_file)
- fprintf (dump_file,
- "Declaration updated to be %sconst: %s\n",
- this_looping ? "looping " : "",
- w->dump_name ());
- remove_p |= has_cdtor;
- }
+ remove_p |= ipa_make_function_const (node, looping, false);
break;
case IPA_PURE:
- if (!DECL_PURE_P (w->decl))
- {
- warn_function_pure (w->decl, !this_looping);
- if (dump_file)
- fprintf (dump_file, "Function found to be %spure: %s\n",
- this_looping ? "looping " : "",
- w->dump_name ());
- }
- if (this_looping)
- has_cdtor = false;
- else
- has_cdtor = w->call_for_symbol_and_aliases (cdtor_p,
- NULL, true);
- if (w->set_pure_flag (true, this_looping))
- {
- if (dump_file)
- fprintf (dump_file,
- "Declaration updated to be %spure: %s\n",
- this_looping ? "looping " : "",
- w->dump_name ());
- remove_p |= has_cdtor;
- }
+ remove_p |= ipa_make_function_pure (node, looping, false);
break;
default:
@@ -2046,34 +2103,6 @@ make_pass_ipa_pure_const (gcc::context *ctxt)
return new pass_ipa_pure_const (ctxt);
}
-/* Return true if function should be skipped for local pure const analysis. */
-
-static bool
-skip_function_for_local_pure_const (struct cgraph_node *node)
-{
- /* Because we do not schedule pass_fixup_cfg over whole program after early
- optimizations we must not promote functions that are called by already
- processed functions. */
-
- if (function_called_by_processed_nodes_p ())
- {
- if (dump_file)
- fprintf (dump_file, "Function called in recursive cycle; ignoring\n");
- return true;
- }
- /* Save some work and do not analyze functions which are interposable and
- do not have any non-interposable aliases. */
- if (node->get_availability () <= AVAIL_INTERPOSABLE
- && !node->has_aliases_p ())
- {
- if (dump_file)
- fprintf (dump_file,
- "Function is interposable; not analyzing.\n");
- return true;
- }
- return false;
-}
-
/* Simple local pass for pure const discovery reusing the analysis from
ipa_pure_const. This pass is effective when executed together with
other optimization passes in early optimization pass queue. */
@@ -2144,55 +2173,13 @@ pass_local_pure_const::execute (function *fun)
switch (l->pure_const_state)
{
case IPA_CONST:
- if (!TREE_READONLY (current_function_decl))
- {
- warn_function_const (current_function_decl, !l->looping);
- if (dump_file)
- fprintf (dump_file, "Function found to be %sconst: %s\n",
- l->looping ? "looping " : "",
- current_function_name ());
- }
- else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
- && !l->looping)
- {
- if (dump_file)
- fprintf (dump_file, "Function found to be non-looping: %s\n",
- current_function_name ());
- }
- if (!skip && node->set_const_flag (true, l->looping))
- {
- if (dump_file)
- fprintf (dump_file, "Declaration updated to be %sconst: %s\n",
- l->looping ? "looping " : "",
- current_function_name ());
- changed = true;
- }
+ changed |= ipa_make_function_const
+ (cgraph_node::get (current_function_decl), l->looping, true);
break;
case IPA_PURE:
- if (!DECL_PURE_P (current_function_decl))
- {
- warn_function_pure (current_function_decl, !l->looping);
- if (dump_file)
- fprintf (dump_file, "Function found to be %spure: %s\n",
- l->looping ? "looping " : "",
- current_function_name ());
- }
- else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
- && !l->looping)
- {
- if (dump_file)
- fprintf (dump_file, "Function found to be non-looping: %s\n",
- current_function_name ());
- }
- if (!skip && node->set_pure_flag (true, l->looping))
- {
- if (dump_file)
- fprintf (dump_file, "Declaration updated to be %spure: %s\n",
- l->looping ? "looping " : "",
- current_function_name ());
- changed = true;
- }
+ changed |= ipa_make_function_pure
+ (cgraph_node::get (current_function_decl), l->looping, true);
break;
default:
diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h
index 824780f562a..e2440a1f893 100644
--- a/gcc/ipa-utils.h
+++ b/gcc/ipa-utils.h
@@ -50,6 +50,8 @@ bool recursive_call_p (tree, tree);
/* In ipa-pure-const.c */
bool finite_function_p ();
bool builtin_safe_for_const_function_p (bool *, tree);
+bool ipa_make_function_const (cgraph_node *, bool, bool);
+bool ipa_make_function_pure (cgraph_node *, bool, bool);
/* In ipa-profile.c */
bool ipa_propagate_frequency (struct cgraph_node *node);
diff --git a/gcc/passes.def b/gcc/passes.def
index 56dab80a029..b583d17c86f 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -92,13 +92,13 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_dse);
NEXT_PASS (pass_cd_dce, false /* update_address_taken_p */);
NEXT_PASS (pass_phiopt, true /* early_p */);
- NEXT_PASS (pass_modref);
NEXT_PASS (pass_tail_recursion);
NEXT_PASS (pass_if_to_switch);
NEXT_PASS (pass_convert_switch);
NEXT_PASS (pass_cleanup_eh);
NEXT_PASS (pass_profile);
NEXT_PASS (pass_local_pure_const);
+ NEXT_PASS (pass_modref);
/* Split functions creates parts that are not run through
early optimizations again. It is thus good idea to do this
late. */
diff --git a/gcc/testsuite/c-c++-common/tm/inline-asm.c b/gcc/testsuite/c-c++-common/tm/inline-asm.c
index 73892601897..176266893e9 100644
--- a/gcc/testsuite/c-c++-common/tm/inline-asm.c
+++ b/gcc/testsuite/c-c++-common/tm/inline-asm.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-fgnu-tm -O1" } */
+/* { dg-options "-fgnu-tm -O1 -fno-ipa-modref -fno-ipa-pure-const" } */
static inline void
inline_death ()
diff --git a/gcc/testsuite/g++.dg/ipa/modref-1.C b/gcc/testsuite/g++.dg/ipa/modref-1.C
index c57aaca0230..b49238162fe 100644
--- a/gcc/testsuite/g++.dg/ipa/modref-1.C
+++ b/gcc/testsuite/g++.dg/ipa/modref-1.C
@@ -30,6 +30,6 @@ int main()
linker_error ();
return 0;
}
-/* { dg-final { scan-tree-dump "Function found to be const: {anonymous}::B::genB" "local-pure-const1" } } */
-/* { dg-final { scan-tree-dump "Retslot flags: no_indirect_clobber no_direct_escape no_indirect_escape not_returned_directly not_returned_indirectly no_direct_read no_indirect_read" "modref1" } } */
+/* { dg-final { scan-tree-dump "Function found to be const: static {anonymous}::B {anonymous}::B::genB" "local-pure-const1" } } */
+/* { dg-final { scan-tree-dump "Retslot flags: not_returned_directly" "modref1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-11.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-11.c
index cafb4f34894..10ebe1ff474 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/modref-11.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-11.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-modref1" } */
+/* { dg-options "-O2 -fdump-tree-modref1 -fno-ipa-pure-const" } */
struct linkedlist {
struct linkedlist *next;
};
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-14.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-14.c
new file mode 100644
index 00000000000..986248f37a2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-14.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wsuggest-attribute=const" } */
+struct a {int a,b,c;};
+__attribute__ ((noinline))
+int init (struct a *a)
+{
+ a->a=1;
+ a->b=2;
+ a->c=3;
+}
+int const_fn () /* { dg-warning "function might be candidate for attribute 'const" } */
+{
+ struct a a;
+ init (&a);
+ return a.a + a.b + a.c;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-8.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-8.c
index 15ae4acc03f..4a18e34cd16 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/modref-8.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-8.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 --param modref-max-adjustments=8 -fdump-tree-modref1" } */
+/* { dg-options "-O2 --param modref-max-adjustments=8 -fdump-tree-modref1 -fno-optimize-sibling-calls" } */
/* { dg-do compile } */
void
set (char *p)
diff --git a/gcc/testsuite/gfortran.dg/do_subscript_3.f90 b/gcc/testsuite/gfortran.dg/do_subscript_3.f90
index 2f62f58142b..8f7183eb9b6 100644
--- a/gcc/testsuite/gfortran.dg/do_subscript_3.f90
+++ b/gcc/testsuite/gfortran.dg/do_subscript_3.f90
@@ -1,4 +1,5 @@
! { dg-do compile }
+! { dg-options "-O0" }
! PR fortran/91424
! Check that only one warning is issued inside blocks, and that
! warnings are also issued for contained subroutines.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-11-11 17:15 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-11 17:15 [gcc r12-5177] Enable pure-const discovery in modref Jan Hubicka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).