From patchwork Thu Nov 11 16:39:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 47489 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7A8443857C60 for ; Thu, 11 Nov 2021 16:39:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7A8443857C60 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1636648791; bh=wFnhZ9VuaJHq2aiFxKwbaa8tIJUG9lPEI+Kay3q7eL4=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=XyqoHvbpxC/Q9ttJCgAtQKoLqWwydT3UVn7IeHG8H3Whs9q4KxJ5SPcKRbeBWbzee ekRml8Aag7scJOxNwj/rDlIRoYnFG+LEB3Eu42CbFj3LCYAzAn+LZk3Sj4QWFBEVwC C6IWujFtVBDto50AQx3ZPJBJWyNh35oVxhR3kKMA= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from nikam.ms.mff.cuni.cz (nikam.ms.mff.cuni.cz [195.113.20.16]) by sourceware.org (Postfix) with ESMTPS id A1368385840E for ; Thu, 11 Nov 2021 16:39:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A1368385840E Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 5ABFC280F28; Thu, 11 Nov 2021 17:39:18 +0100 (CET) Date: Thu, 11 Nov 2021 17:39:18 +0100 To: gcc-patches@gcc.gnu.org Subject: Enable pure/const discovery in modref Message-ID: <20211111163918.GI17431@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jan Hubicka via Gcc-patches From: Jan Hubicka Reply-To: Jan Hubicka Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" 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 * 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 * 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 *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 *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.