This backport contains 2 patchs from gcc main stream tree. The commit id of these patchs list as following in the order of time. 0001-Find-matched-aggregate-lattice-for-self-recursive-CP.patch 709d7838e753bbb6f16e2ed88a118ed81c367040 0002-Do-not-propagate-self-dependent-value-PR-ipa-93763.patch 47772af10c00f7e1e95cd52557fc893dc602a420 diff -Nurp a/gcc/ipa-cp.c b/gcc/ipa-cp.c --- a/gcc/ipa-cp.c 2020-05-23 16:16:58.032000000 +0800 +++ b/gcc/ipa-cp.c 2020-05-22 18:03:41.980000000 +0800 @@ -1766,8 +1766,8 @@ ipcp_lattice::add_value (valtyp } /* Return true, if a ipcp_value VAL is orginated from parameter value of - self-feeding recursive function by applying non-passthrough arithmetic - transformation. */ + self-feeding recursive function via some kind of pass-through jump + function. */ static bool self_recursively_generated_p (ipcp_value *val) @@ -1778,19 +1778,36 @@ self_recursively_generated_p (ipcp_value { cgraph_edge *cs = src->cs; - if (!src->val || cs->caller != cs->callee->function_symbol () - || src->val == val) + if (!src->val || cs->caller != cs->callee->function_symbol ()) return false; + if (src->val == val) + continue; + if (!info) info = IPA_NODE_REF (cs->caller); class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, src->index); - ipcp_lattice *src_lat = src->offset == -1 ? &plats->itself - : plats->aggs; + ipcp_lattice *src_lat; ipcp_value *src_val; + if (src->offset == -1) + src_lat = &plats->itself; + else + { + struct ipcp_agg_lattice *src_aglat; + + for (src_aglat = plats->aggs; src_aglat; src_aglat = src_aglat->next) + if (src_aglat->offset == src->offset) + break; + + if (!src_aglat) + return false; + + src_lat = src_aglat; + } + for (src_val = src_lat->values; src_val; src_val = src_val->next) if (src_val == val) break; @@ -1887,6 +1904,8 @@ propagate_vals_across_arith_jfunc (cgrap val_seeds.safe_push (src_val); } + gcc_assert ((int) val_seeds.length () + <= PARAM_VALUE (PARAM_IPA_CP_VALUE_LIST_SIZE)); /* Recursively generate lattice values with a limited count. */ FOR_EACH_VEC_ELT (val_seeds, i, src_val) { diff -Nurp a/gcc/testsuite/gcc.dg/ipa/ipa-clone-3.c b/gcc/testsuite/gcc.dg/ipa/ipa-clone-3.c --- a/gcc/testsuite/gcc.dg/ipa/ipa-clone-3.c 1970-01-01 08:00:00.000000000 +0800 +++ b/gcc/testsuite/gcc.dg/ipa/ipa-clone-3.c 2020-05-22 17:55:24.036000000 +0800 @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-ipa-cp-details -fno-early-inlining --param ipa-cp-max-recursive-depth=8 --param ipa-cp-eval-threshold=1" } */ + +struct V { + int f0; + int f1; +}; + +int data[100]; + +int fn (); + +int recur_fn (struct V * __restrict v) +{ + int i = v->f0; + int j = v->f1; + struct V t; + + if (j > 100) + { + fn (); + return 1; + } + + data[i] = i; + + t.f0 = i - 2; + t.f1 = j + 1; + + recur_fn (&t); + + return i * j; +} + +int main () +{ + struct V v = {1, 3}; + + return recur_fn (&v); +} + +/* { dg-final { scan-ipa-dump-times "Creating a specialized node of recur_fn/\[0-9\]*\\." 8 "cp" } } */ diff -Nurp a/gcc/testsuite/gcc.dg/ipa/pr93763.c b/gcc/testsuite/gcc.dg/ipa/pr93763.c --- a/gcc/testsuite/gcc.dg/ipa/pr93763.c 1970-01-01 08:00:00.000000000 +0800 +++ b/gcc/testsuite/gcc.dg/ipa/pr93763.c 2020-05-22 17:57:10.532000000 +0800 @@ -0,0 +1,46 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +typedef struct a a; +struct a { + a *b +} d; +e, k, ah, al; +f(aa) { + if (aa & 1) + goto g; + f(aa | 2); +g: + h(); +} +l() { + { + f(072); + i(e, d, 92); + } +} +ag() { + { i(e, d, 36); } +} +ai(a *m, a *n, unsigned aa) { + f(aa); + j(k, l, ah, 1); +} +j(int c, a m, int aj, int aa) { + int ak = aa; + { i(e, d, ak); } +} +i(int c, a *m, unsigned aa) { + { + { i(c, (*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*( +*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*( +*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*(*m).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b) +.b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b) +.b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b) +.b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b) +.b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b).b, 0); + } + } + int am = aa; + ai(ag, al, am); +} diff -Nurp a/gcc/testsuite/g++.dg/ipa/pr93763.C b/gcc/testsuite/g++.dg/ipa/pr93763.C --- a/gcc/testsuite/g++.dg/ipa/pr93763.C 1970-01-01 08:00:00.000000000 +0800 +++ b/gcc/testsuite/g++.dg/ipa/pr93763.C 2020-05-22 17:57:10.532000000 +0800 @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +struct search_param { + int total; +}; +void search_trivial(search_param error_left) { + search_trivial(error_left); + search_param error_left2{error_left}; + error_left2.total--; + search_trivial(error_left2); +} +void search_algo_uni(search_param error_left) { search_trivial(error_left); } +void search_algo(search_param error_left) { search_algo_uni(error_left); } +int main() { search_algo({}); return 0; }