From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from nikam.ms.mff.cuni.cz (nikam.ms.mff.cuni.cz [195.113.20.16]) by sourceware.org (Postfix) with ESMTPS id 6DE6E384DDB1 for ; Mon, 12 Dec 2022 21:42:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 6DE6E384DDB1 Authentication-Results: sourceware.org; dmarc=fail (p=none dis=none) header.from=ucw.cz Authentication-Results: sourceware.org; spf=none smtp.mailfrom=kam.mff.cuni.cz Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 224F4280499; Mon, 12 Dec 2022 22:42:06 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ucw.cz; s=gen1; t=1670881326; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=NN04buG0VOYWI0maQ8zeWJvuLhAb/PADwUNNcA3iRaI=; b=r4GmPxrNuINPT206ncKHtFdqqGQi1TdggfAKyBgJAK7cXYW69WQbXAdH0IXVfJGvQ+cAde QEc38dQ14QZsbsYt4bBDIVttMI7dUwJDkOXj8MubkrNTeF0pq629SD6hOuSpwvE2SYFcwn yAgUQHbcBksvzaapaDbor2rjCuHlrqc= Date: Mon, 12 Dec 2022 22:42:06 +0100 From: Jan Hubicka To: Martin Jambor Cc: GCC Patches Subject: Re: [PATCH 2/9] ipa: Better way of applying both IPA-CP and IPA-SRA (PR 103227) Message-ID: References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,GIT_PATCH_0,HEADER_FROM_DIFFERENT_DOMAINS,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: > 2022-11-11 Martin Jambor > > PR ipa/103227 > * ipa-param-manipulation.h (class ipa_param_adjustments): Removed > member function get_updated_index_or_split. > (class ipa_param_body_adjustments): New overload of > register_replacement, new member function append_init_stmts, new > member m_split_agg_csts_inits. > * ipa-param-manipulation.cc: Include ipa-prop.h. > (ipa_param_adjustments::get_updated_index_or_split): Removed. > (ipa_param_body_adjustments::register_replacement): New overload, use > it from the older one. > (ipa_param_body_adjustments::common_initialization): Added the > capability to create replacements for conflicting IPA-CP discovered > constants. > (ipa_param_body_adjustments::ipa_param_body_adjustments): Construct > the new member. > (ipa_param_body_adjustments::append_init_stmts): New function. > * ipa-sra.cc: Include ipa-prop.h. > (push_param_adjustments_for_index): Require IPA-CP transformation > summary as a parameter, do not create replacements which are known to > have constant values. > (process_isra_node_results): Find and pass to the above function the > IPA-CP transformation summary. > * ipa-prop.cc (adjust_agg_replacement_values): Remove the > functionality replacing IPA-SRA created scalar parameters with > constants. Simplify, do not require parameter descriptors, do not > return anything. > (ipcp_transform_function): Simplify now that > adjust_agg_replacement_values does not change cfg. Move definition > and initialization of descriptors lower. > * tree-inline.cc (tree_function_versioning): Call append_init_stmts of > param_body_adjs, if there are any. OK, Honza > > gcc/testsuite/ChangeLog: > > 2022-11-11 Martin Jambor > > PR ipa/103227 > PR ipa/107640 > * gcc.dg/ipa/pr107640-2.c: New test. > --- > gcc/ipa-param-manipulation.cc | 155 ++++++++++++++++---------- > gcc/ipa-param-manipulation.h | 19 ++-- > gcc/ipa-prop.cc | 66 ++++------- > gcc/ipa-sra.cc | 30 ++++- > gcc/testsuite/gcc.dg/ipa/pr107640-2.c | 50 +++++++++ > gcc/tree-inline.cc | 2 + > 6 files changed, 208 insertions(+), 114 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/ipa/pr107640-2.c > > diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc > index cee0e23f946..e92cfc0b6d5 100644 > --- a/gcc/ipa-param-manipulation.cc > +++ b/gcc/ipa-param-manipulation.cc > @@ -46,7 +46,7 @@ along with GCC; see the file COPYING3. If not see > #include "tree-phinodes.h" > #include "cfgexpand.h" > #include "attribs.h" > - > +#include "ipa-prop.h" > > /* Actual prefixes of different newly synthetized parameters. Keep in sync > with IPA_PARAM_PREFIX_* defines. */ > @@ -449,39 +449,6 @@ ipa_param_adjustments::get_updated_indices (vec *new_indices) > } > } > > -/* If a parameter with original INDEX has survived intact, return its new > - index. Otherwise return -1. In that case, if it has been split and there > - is a new parameter representing a portion at unit OFFSET for which a value > - of a TYPE can be substituted, store its new index into SPLIT_INDEX, > - otherwise store -1 there. */ > -int > -ipa_param_adjustments::get_updated_index_or_split (int index, > - unsigned unit_offset, > - tree type, int *split_index) > -{ > - unsigned adj_len = vec_safe_length (m_adj_params); > - for (unsigned i = 0; i < adj_len ; i++) > - { > - ipa_adjusted_param *apm = &(*m_adj_params)[i]; > - if (apm->base_index != index) > - continue; > - if (apm->op == IPA_PARAM_OP_COPY) > - return i; > - if (apm->op == IPA_PARAM_OP_SPLIT > - && apm->unit_offset == unit_offset) > - { > - if (useless_type_conversion_p (apm->type, type)) > - *split_index = i; > - else > - *split_index = -1; > - return -1; > - } > - } > - > - *split_index = -1; > - return -1; > -} > - > /* Return the original index for the given new parameter index. Return a > negative number if not available. */ > > @@ -1020,6 +987,21 @@ ipa_param_adjustments::debug () > dump (stderr); > } > > +/* Register a REPLACEMENT for accesses to BASE at UNIT_OFFSET. */ > + > +void > +ipa_param_body_adjustments::register_replacement (tree base, > + unsigned unit_offset, > + tree replacement) > +{ > + ipa_param_body_replacement psr; > + psr.base = base; > + psr.repl = replacement; > + psr.dummy = NULL_TREE; > + psr.unit_offset = unit_offset; > + m_replacements.safe_push (psr); > +} > + > /* Register that REPLACEMENT should replace parameter described in APM. */ > > void > @@ -1029,12 +1011,8 @@ ipa_param_body_adjustments::register_replacement (ipa_adjusted_param *apm, > gcc_checking_assert (apm->op == IPA_PARAM_OP_SPLIT > || apm->op == IPA_PARAM_OP_NEW); > gcc_checking_assert (!apm->prev_clone_adjustment); > - ipa_param_body_replacement psr; > - psr.base = m_oparms[apm->prev_clone_index]; > - psr.repl = replacement; > - psr.dummy = NULL_TREE; > - psr.unit_offset = apm->unit_offset; > - m_replacements.safe_push (psr); > + register_replacement (m_oparms[apm->prev_clone_index], apm->unit_offset, > + replacement); > } > > /* Copy or not, as appropriate given m_id and decl context, a pre-existing > @@ -1386,23 +1364,73 @@ ipa_param_body_adjustments::common_initialization (tree old_fndecl, > gcc_unreachable (); > } > > + auto_vec index_mapping; > + bool need_remap = false; > + if (m_id) > + { > + clone_info *cinfo = clone_info::get (m_id->src_node); > + if (cinfo && cinfo->param_adjustments) > + { > + cinfo->param_adjustments->get_updated_indices (&index_mapping); > + need_remap = true; > + } > + > + if (ipcp_transformation *ipcp_ts > + = ipcp_get_transformation_summary (m_id->src_node)) > + { > + for (const ipa_argagg_value &av : ipcp_ts->m_agg_values) > + { > + int parm_num = av.index; > + > + if (need_remap) > + { > + /* FIXME: We cannot handle the situation when IPA-CP > + identified that a parameter is a pointer to a global > + variable and at the same time the variable has some known > + constant contents (PR 107640). The best place to make > + sure we don't drop such constants on the floor probably is > + not here, but we have to make sure that it does not > + confuse the remapping. */ > + if (parm_num >= (int) index_mapping.length ()) > + continue; > + parm_num = index_mapping[parm_num]; > + if (parm_num < 0) > + continue; > + } > + > + if (!kept[parm_num]) > + { > + /* IPA-CP has detected an aggregate constant in a parameter > + that will not be kept, which means that IPA-SRA would have > + split it if there wasn't a constant. Because we are about > + to remove the original, this is the last chance where we > + can substitute the uses with a constant (for values passed > + by reference) or do the split but initialize the > + replacement with a constant (for split aggregates passed > + by value). */ > + > + tree repl; > + if (av.by_ref) > + repl = av.value; > + else > + { > + repl = create_tmp_var (TREE_TYPE (av.value), > + "removed_ipa_cp"); > + gimple *init_stmt = gimple_build_assign (repl, av.value); > + m_split_agg_csts_inits.safe_push (init_stmt); > + } > + register_replacement (m_oparms[parm_num], av.unit_offset, > + repl); > + split[parm_num] = true; > + } > + } > + } > + } > + > if (tree_map) > { > /* Do not treat parameters which were replaced with a constant as > completely vanished. */ > - auto_vec index_mapping; > - bool need_remap = false; > - > - if (m_id) > - { > - clone_info *cinfo = clone_info::get (m_id->src_node); > - if (cinfo && cinfo->param_adjustments) > - { > - cinfo->param_adjustments->get_updated_indices (&index_mapping); > - need_remap = true; > - } > - } > - > for (unsigned i = 0; i < tree_map->length (); i++) > { > int parm_num = (*tree_map)[i]->parm_num; > @@ -1473,8 +1501,9 @@ ipa_param_body_adjustments > : m_adj_params (adj_params), m_adjustments (NULL), m_reset_debug_decls (), > m_dead_stmts (), m_dead_ssas (), m_dead_ssa_debug_equiv (), > m_dead_stmt_debug_equiv (), m_fndecl (fndecl), m_id (NULL), m_oparms (), > - m_new_decls (), m_new_types (), m_replacements (), m_removed_decls (), > - m_removed_map (), m_method2func (false) > + m_new_decls (), m_new_types (), m_replacements (), > + m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (), > + m_method2func (false) > { > common_initialization (fndecl, NULL, NULL); > } > @@ -1491,7 +1520,8 @@ ipa_param_body_adjustments > m_reset_debug_decls (), m_dead_stmts (), m_dead_ssas (), > m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl), > m_id (NULL), m_oparms (), m_new_decls (), m_new_types (), m_replacements (), > - m_removed_decls (), m_removed_map (), m_method2func (false) > + m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (), > + m_method2func (false) > { > common_initialization (fndecl, NULL, NULL); > } > @@ -1514,7 +1544,8 @@ ipa_param_body_adjustments > m_reset_debug_decls (), m_dead_stmts (), m_dead_ssas (), > m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl), > m_id (id), m_oparms (), m_new_decls (), m_new_types (), m_replacements (), > - m_removed_decls (), m_removed_map (), m_method2func (false) > + m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (), > + m_method2func (false) > { > common_initialization (old_fndecl, vars, tree_map); > } > @@ -2383,6 +2414,16 @@ ipa_param_body_adjustments::perform_cfun_body_modifications () > } > > > +/* If there are any initialization statements that need to be emitted into > + the basic block BB right at ther start of the new function, do so. */ > +void > +ipa_param_body_adjustments::append_init_stmts (basic_block bb) > +{ > + gimple_stmt_iterator si = gsi_last_bb (bb); > + while (!m_split_agg_csts_inits.is_empty ()) > + gsi_insert_after (&si, m_split_agg_csts_inits.pop (), GSI_NEW_STMT); > +} > + > /* Deallocate summaries which otherwise stay alive until the end of > compilation. */ > > diff --git a/gcc/ipa-param-manipulation.h b/gcc/ipa-param-manipulation.h > index e5654f4ff70..e20d34918b3 100644 > --- a/gcc/ipa-param-manipulation.h > +++ b/gcc/ipa-param-manipulation.h > @@ -236,13 +236,6 @@ public: > void get_surviving_params (vec *surviving_params); > /* Fill a vector with new indices of surviving original parameters. */ > void get_updated_indices (vec *new_indices); > - /* If a parameter with original INDEX has survived intact, return its new > - index. Otherwise return -1. In that case, if it has been split and there > - is a new parameter representing a portion at UNIT_OFFSET for which a value > - of a TYPE can be substituted, store its new index into SPLIT_INDEX, > - otherwise store -1 there. */ > - int get_updated_index_or_split (int index, unsigned unit_offset, tree type, > - int *split_index); > /* Return the original index for the given new parameter index. Return a > negative number if not available. */ > int get_original_index (int newidx); > @@ -321,6 +314,8 @@ public: > > /* Change the PARM_DECLs. */ > void modify_formal_parameters (); > + /* Register a REPLACEMENT for accesses to BASE at UNIT_OFFSET. */ > + void register_replacement (tree base, unsigned unit_offset, tree replacement); > /* Register a replacement decl for the transformation done in APM. */ > void register_replacement (ipa_adjusted_param *apm, tree replacement); > /* Lookup a replacement for a given offset within a given parameter. */ > @@ -340,6 +335,10 @@ public: > they are mapped to. */ > void remap_with_debug_expressions (tree *t); > > + /* If there are any initialization statements that need to be emitted into > + the basic block BB right at ther start of the new function, do so. */ > + void append_init_stmts (basic_block bb); > + > /* Pointers to data structures defining how the function should be > modified. */ > vec *m_adj_params; > @@ -405,6 +404,12 @@ private: > > auto_vec m_replacements; > > + /* List of initialization assignments to be put at the beginning of the > + cloned function to deal with split aggregates which however have known > + constant value and so their PARM_DECL disappears. */ > + > + auto_vec m_split_agg_csts_inits; > + > /* Vector for remapping SSA_BASES from old parameter declarations that are > being removed as a part of the transformation. Before a new VAR_DECL is > created, it holds the old PARM_DECL, once the variable is built it is > diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc > index fcadf64ead7..08c7f97efb9 100644 > --- a/gcc/ipa-prop.cc > +++ b/gcc/ipa-prop.cc > @@ -5518,29 +5518,21 @@ ipcp_read_transformation_summaries (void) > } > } > > -/* Adjust the aggregate replacements in TS to reflect parameters skipped in > - NODE but also if any parameter was IPA-SRAed into a scalar go ahead with > - substitution of the default_definitions of that new param with the > - appropriate constant. > +/* Adjust the aggregate replacements in TS to reflect any parameter removals > + which might have already taken place. If after adjustments there are no > + aggregate replacements left, the m_agg_values will be set to NULL. In other > + cases, it may be shrunk. */ > > - If after adjustments there are no aggregate replacements left, the > - m_agg_values will be set to NULL. In other cases, it may be shrunk. > - > - Return true if any values were already substituted for scalarized parameters > - and update_cfg shuld be run after replace_uses_by. */ > - > -static bool > -adjust_agg_replacement_values (cgraph_node *node, > - ipcp_transformation *ts, > - const vec > - &descriptors) > +static void > +adjust_agg_replacement_values (cgraph_node *node, ipcp_transformation *ts) > { > clone_info *cinfo = clone_info::get (node); > if (!cinfo || !cinfo->param_adjustments) > - return false; > + return; > > + auto_vec new_indices; > + cinfo->param_adjustments->get_updated_indices (&new_indices); > bool removed_item = false; > - bool done_replacement = false; > unsigned dst_index = 0; > unsigned count = ts->m_agg_values->length (); > for (unsigned i = 0; i < count; i++) > @@ -5548,13 +5540,10 @@ adjust_agg_replacement_values (cgraph_node *node, > ipa_argagg_value *v = &(*ts->m_agg_values)[i]; > gcc_checking_assert (v->index >= 0); > > - tree cst_type = TREE_TYPE (v->value); > - int split_idx; > - int new_idx > - = cinfo->param_adjustments->get_updated_index_or_split (v->index, > - v->unit_offset, > - cst_type, > - &split_idx); > + int new_idx = -1; > + if ((unsigned) v->index < new_indices.length ()) > + new_idx = new_indices[v->index]; > + > if (new_idx >= 0) > { > v->index = new_idx; > @@ -5563,19 +5552,7 @@ adjust_agg_replacement_values (cgraph_node *node, > dst_index++; > } > else > - { > - removed_item = true; > - if (split_idx >= 0) > - { > - tree parm = ipa_get_param (descriptors, split_idx); > - tree ddef = ssa_default_def (cfun, parm); > - if (ddef) > - { > - replace_uses_by (ddef, v->value); > - done_replacement = true; > - } > - } > - } > + removed_item = true; > } > > if (dst_index == 0) > @@ -5586,7 +5563,7 @@ adjust_agg_replacement_values (cgraph_node *node, > else if (removed_item) > ts->m_agg_values->truncate (dst_index); > > - return done_replacement; > + return; > } > > /* Dominator walker driving the ipcp modification phase. */ > @@ -5955,7 +5932,6 @@ ipcp_update_vr (struct cgraph_node *node) > unsigned int > ipcp_transform_function (struct cgraph_node *node) > { > - vec *descriptors = NULL; > struct ipa_func_body_info fbi; > int param_count; > > @@ -5974,18 +5950,13 @@ ipcp_transform_function (struct cgraph_node *node) > param_count = count_formal_params (node->decl); > if (param_count == 0) > return 0; > - vec_safe_grow_cleared (descriptors, param_count, true); > - ipa_populate_param_decls (node, *descriptors); > > - bool cfg_changed = adjust_agg_replacement_values (node, ts, *descriptors); > + adjust_agg_replacement_values (node, ts); > if (vec_safe_is_empty (ts->m_agg_values)) > { > - vec_free (descriptors); > if (dump_file) > fprintf (dump_file, " All affected aggregate parameters were either " > "removed or converted into scalars, phase done.\n"); > - if (cfg_changed) > - delete_unreachable_blocks_update_callgraph (node, false); > return 0; > } > if (dump_file) > @@ -6002,12 +5973,15 @@ ipcp_transform_function (struct cgraph_node *node) > fbi.param_count = param_count; > fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps); > > + vec *descriptors = NULL; > + vec_safe_grow_cleared (descriptors, param_count, true); > + ipa_populate_param_decls (node, *descriptors); > bool modified_mem_access = false; > calculate_dominance_info (CDI_DOMINATORS); > ipcp_modif_dom_walker walker (&fbi, descriptors, ts, &modified_mem_access); > walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun)); > free_dominance_info (CDI_DOMINATORS); > - cfg_changed |= walker.cleanup_eh (); > + bool cfg_changed = walker.cleanup_eh (); > > int i; > struct ipa_bb_info *bi; > diff --git a/gcc/ipa-sra.cc b/gcc/ipa-sra.cc > index 718201d27fa..0f137e810fe 100644 > --- a/gcc/ipa-sra.cc > +++ b/gcc/ipa-sra.cc > @@ -84,6 +84,7 @@ along with GCC; see the file COPYING3. If not see > #include "internal-fn.h" > #include "symtab-clones.h" > #include "attribs.h" > +#include "ipa-prop.h" > > static void ipa_sra_summarize_function (cgraph_node *); > > @@ -3605,13 +3606,16 @@ retval_used_p (cgraph_node *node, void *) > /* Push into NEW_PARAMS all required parameter adjustment entries to copy or > modify parameter which originally had index BASE_INDEX, in the adjustment > vector of parent clone (if any) had PREV_CLONE_INDEX and was described by > - PREV_ADJUSTMENT. If the parent clone is the original function, > - PREV_ADJUSTMENT is NULL and PREV_CLONE_INDEX is equal to BASE_INDEX. */ > + PREV_ADJUSTMENT. If IPA-CP has created a transformation summary for the > + original node, it needs to be passed in IPCP_TS, otherwise it should be > + NULL. If the parent clone is the original function, PREV_ADJUSTMENT is NULL > + and PREV_CLONE_INDEX is equal to BASE_INDEX. */ > > static void > push_param_adjustments_for_index (isra_func_summary *ifs, unsigned base_index, > unsigned prev_clone_index, > ipa_adjusted_param *prev_adjustment, > + ipcp_transformation *ipcp_ts, > vec **new_params) > { > isra_param_desc *desc = &(*ifs->m_parameters)[base_index]; > @@ -3652,6 +3656,23 @@ push_param_adjustments_for_index (isra_func_summary *ifs, unsigned base_index, > param_access *pa = (*desc->accesses)[j]; > if (!pa->certain) > continue; > + > + if (ipcp_ts) > + { > + ipa_argagg_value_list avl (ipcp_ts); > + tree value = avl.get_value (base_index, pa->unit_offset); > + if (value > + && (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (value))) / BITS_PER_UNIT > + == pa->unit_size)) > + { > + if (dump_file) > + fprintf (dump_file, " - omitting component at byte " > + "offset %u which is known to have a constant value\n ", > + pa->unit_offset); > + continue; > + } > + } > + > if (dump_file) > fprintf (dump_file, " - component at byte offset %u, " > "size %u\n", pa->unit_offset, pa->unit_size); > @@ -3732,6 +3753,7 @@ process_isra_node_results (cgraph_node *node, > fprintf (dump_file, " Will remove return value.\n"); > } > > + ipcp_transformation *ipcp_ts = ipcp_get_transformation_summary (node); > vec *new_params = NULL; > if (ipa_param_adjustments *old_adjustments > = cinfo ? cinfo->param_adjustments : NULL) > @@ -3741,12 +3763,12 @@ process_isra_node_results (cgraph_node *node, > { > ipa_adjusted_param *old_adj = &(*old_adjustments->m_adj_params)[i]; > push_param_adjustments_for_index (ifs, old_adj->base_index, i, > - old_adj, &new_params); > + old_adj, ipcp_ts, &new_params); > } > } > else > for (unsigned i = 0; i < param_count; i++) > - push_param_adjustments_for_index (ifs, i, i, NULL, &new_params); > + push_param_adjustments_for_index (ifs, i, i, NULL, ipcp_ts, &new_params); > > ipa_param_adjustments *new_adjustments > = (new (ggc_alloc ()) > diff --git a/gcc/testsuite/gcc.dg/ipa/pr107640-2.c b/gcc/testsuite/gcc.dg/ipa/pr107640-2.c > new file mode 100644 > index 00000000000..94cbe02860d > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/ipa/pr107640-2.c > @@ -0,0 +1,50 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized-slim" } */ > + > +struct S > +{ > + int a, b, c; > +}; > + > +int ellide (int c); > +volatile short gi; > + > +void __attribute__((noipa)) > +consume_s (struct S *p) > +{ > + gi = p->a; > +} > + > +static void __attribute__((noinline)) > +foo (struct S *p, short *r) > +{ > + gi = *r; > + if (!__builtin_constant_p (p->b)) > + ellide (1); > + consume_s (p); > +} > + > +static void __attribute__((noinline)) > +bar (short *r, struct S *p) > +{ > + gi = *r; > + if (!__builtin_constant_p (p->c)) > + ellide (2); > + consume_s (p); > +} > + > +struct S gs; > + > +int main (int argc, char *argv[]) > +{ > + short i = 42; > + gs.a = 10; > + gs.b = 20; > + foo (&gs, &i); > + gs.b = 30; > + gs.c = 40; > + bar (&i, &gs); > + return 0; > +} > + > +/* { dg-final { scan-tree-dump-not "ellide" "optimized" { xfail *-*-* } } } */ > diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc > index 8091ba8f13b..15a1a389493 100644 > --- a/gcc/tree-inline.cc > +++ b/gcc/tree-inline.cc > @@ -6377,6 +6377,8 @@ tree_function_versioning (tree old_decl, tree new_decl, > bb = split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))); > while (init_stmts.length ()) > insert_init_stmt (&id, bb, init_stmts.pop ()); > + if (param_body_adjs) > + param_body_adjs->append_init_stmts (bb); > update_clone_info (&id); > > /* Remap the nonlocal_goto_save_area, if any. */ > -- > 2.38.1 >