diff --git a/gcc/ipa-sra.cc b/gcc/ipa-sra.cc index 3de7d426b7e7339d16b2ed8a28e88659bbf9562e..7b8260bc9e1be9d7a2b921e06b32e1c43fbb85a5 100644 --- a/gcc/ipa-sra.cc +++ b/gcc/ipa-sra.cc @@ -4028,6 +4028,70 @@ mark_callers_calls_comdat_local (struct cgraph_node *node, void *) return false; } +/* Remove any IPA-CP results stored in TS that are associated with removed + parameters as marked in IFS. */ + +static void +zap_useless_ipcp_results (const isra_func_summary *ifs, ipcp_transformation *ts) +{ + unsigned ts_len = vec_safe_length (ts->m_agg_values); + + if (ts_len == 0) + return; + + bool removed_item = false; + unsigned dst_index = 0; + + for (unsigned i = 0; i < ts_len; i++) + { + ipa_argagg_value *v = &(*ts->m_agg_values)[i]; + const isra_param_desc *desc = &(*ifs->m_parameters)[v->index]; + + if (!desc->locally_unused) + { + if (removed_item) + (*ts->m_agg_values)[dst_index] = *v; + dst_index++; + } + else + removed_item = true; + } + if (dst_index == 0) + { + ggc_free (ts->m_agg_values); + ts->m_agg_values = NULL; + } + else if (removed_item) + ts->m_agg_values->truncate (dst_index); + + bool useful_bits = false; + unsigned count = vec_safe_length (ts->bits); + for (unsigned i = 0; i < count; i++) + if ((*ts->bits)[i]) + { + const isra_param_desc *desc = &(*ifs->m_parameters)[i]; + if (desc->locally_unused) + (*ts->bits)[i] = NULL; + else + useful_bits = true; + } + if (!useful_bits) + ts->bits = NULL; + + bool useful_vr = false; + count = vec_safe_length (ts->m_vr); + for (unsigned i = 0; i < count; i++) + if ((*ts->m_vr)[i].known) + { + const isra_param_desc *desc = &(*ifs->m_parameters)[i]; + if (desc->locally_unused) + (*ts->m_vr)[i].known = false; + else + useful_vr = true; + } + if (!useful_vr) + ts->m_vr = NULL; +} /* Do final processing of results of IPA propagation regarding NODE, clone it if appropriate. */ @@ -4080,6 +4144,8 @@ process_isra_node_results (cgraph_node *node, } ipcp_transformation *ipcp_ts = ipcp_get_transformation_summary (node); + if (ipcp_ts) + zap_useless_ipcp_results (ifs, ipcp_ts); vec<ipa_adjusted_param, va_gc> *new_params = NULL; if (ipa_param_adjustments *old_adjustments = cinfo ? cinfo->param_adjustments : NULL) diff --git a/gcc/testsuite/gcc.dg/ipa/pr108959.c b/gcc/testsuite/gcc.dg/ipa/pr108959.c new file mode 100644 index 0000000000000000000000000000000000000000..cd1f88658efcfb29eda1b3cefe004b81379003ee --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr108959.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +union U2 { + long f0; + int f1; +}; +int g_16; +int g_70[20]; +static int func_61(int) { + for (;;) + g_70[g_16] = 4; +} +static int func_43(int *p_44) +{ + func_61(*p_44); +} +int main() { + union U2 l_38 = {9}; + int *l_49 = (int *) &l_38; + func_43(l_49); +}