Hi,
this patch enables the pure/const discovery in modref, so 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.

Boostrapped/regtested x86_64-linux. Will commit it shortly.

gcc/ChangeLog:

2021-11-11  Jan Hubicka  <hubi...@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  <hubi...@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 --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..230fafba839
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-14.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+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 a 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.

Reply via email to