This is a simpel and nice fix, but could suppress some CP opportunities for self-recursive call. Using the test case as example, the first should be a for-all-context clone, and the call "recur_fn (i, 1, depth + 1)" is replaced with a newly created recursive node. Thus, in the next round of CP iteration, the way to do CP for the 2nd arugment "1" is blocked, because its coming edge can not pass check by cgraph_edge_brings_value_p().
+__attribute__((noinline)) static int recur_fn (int i, int j, int depth) +{ + if (depth > 10) + return 1; + + data[i + j]++; + + if (depth & 3) + recur_fn (i, 1, depth + 1); + else + recur_fn (i, j & 1, depth + 1); + + foo(); + + return i + j; +} + +int caller (int v, int depth) +{ + recur_fn (1, v, depth); + + return 0; +} >However, I believe that his approach mostly papers over a bug that >happens earlier, specifically that cgraph_edge_brings_value_p returned >true for the self-recursive edge from all-context clone to itself, even >though when evaluating the second argument. We assume that all context >clones get at least as many constants as any other potential clone, but >that does not work for self-recursive edges with pass-through parameters >that that just pass along the received constant. The following check on value in cgraph_edge_brings_value_p could ensure whether the value can arrive the dest node or not. If the value is a constant without source, as above example "1", this is allowed. Otherwise, code snippet enclosed by "if (caller_info->ipcp_orig_node)" could capture for-all-context clone. Thanks, Feng