Hi, the issue in PR 85449 is that the code for gathering call graph edges to redirect to a new clone that identified self-recursive PASS-THROUGHs also triggered for clones of these (self recursively calling a previous clone of the same function) and redirected them too. Fixed by the patch below which moves the test to the section that deals with non-clones.
The patch has been pre-approved by Honza and, on top of the fix for PR 85447, it has passed LTO bootstrap and testing on x86_64-linux, regular bootstrap and testing on x86_64-linux, i686-linux and aarch64linux. I have also used it to LTO-build all of spec 2006 and 2017 and Firefox. I am going to commit it to trunk in a few moments. Martin 2018-04-19 Martin Jambor <mjam...@suse.cz> ipa/85449 * ipa-cp.c (cgraph_edge_brings_value_p): Move check for self-feeding recursion dependency to only apply to non-clones. testsuite/ * gcc.dg/ipa/pr85449.c: New test. --- gcc/ipa-cp.c | 11 +++-- gcc/testsuite/gcc.dg/ipa/pr85449.c | 90 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ipa/pr85449.c diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 9388482bbea..1b8f335fd32 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -3489,9 +3489,8 @@ cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src, || availability <= AVAIL_INTERPOSABLE || caller_info->node_dead) return false; - /* At the moment we do not propagate over arithmetic jump functions in SCCs, - so it is safe to detect self-feeding recursive calls in this way. */ - if (!src->val || src->val == dest_val) + + if (!src->val) return true; if (caller_info->ipcp_orig_node) @@ -3506,6 +3505,12 @@ cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src, } else { + /* At the moment we do not propagate over arithmetic jump functions in + SCCs, so it is safe to detect self-feeding recursive calls in this + way. */ + if (src->val == dest_val) + return true; + struct ipcp_agg_lattice *aglat; struct ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info, src->index); diff --git a/gcc/testsuite/gcc.dg/ipa/pr85449.c b/gcc/testsuite/gcc.dg/ipa/pr85449.c new file mode 100644 index 00000000000..57dfce263de --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr85449.c @@ -0,0 +1,90 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining" } */ + +int array[128]; + +volatile int v = 0; +volatile int blah = 0; + +int __attribute__((noipa)) +obscured_zero () +{ + return 0; +} + +int __attribute__((noipa)) +obscured_one () +{ + return 1; +} + +int __attribute__((noipa)) +obscured_two () +{ + return 2; +} + +static +void cb1 (int l) +{ + v = 25; +} + +static +void cb2 (int l) +{ + v = 125; +} + +typedef void (*silly_callback)(int); + +silly_callback __attribute__((noipa)) +get_callback () +{ + return cb1; +} + +static void +f (int c, int l, silly_callback p) +{ + int i; + + for (i = 0; i < c; i++) + array[i] = 455; + + for (i = 0; i < 200; i++) + { + p (l); + if (obscured_one ()) + break; + } + + if (l > 0) + f (c * 2, l - 1, p); + blah = l; +} + +int +main (int argc, char *argv[]) +{ + int i; + for (i = 0; i < 1000; i++) + { + f (0, 5, get_callback ()); + if (v != 25) + __builtin_abort (); + if (obscured_one ()) + break; + } + + for (i = 0; i < 1000; i++) + { + f (obscured_zero (), obscured_two (), cb2); + if (v != 125) + __builtin_abort (); + if (obscured_one ()) + break; + } + + return 0; +} -- 2.16.3