Commit cfeef9ac by Martin Jambor

ipa-cp: Avoid an ICE processing self-recursive cloned edges (PR 93707)

2020-02-27  Martin Jambor  <mjambor@suse.cz>
	    Feng Xue  <fxue@os.amperecomputing.com>

	PR ipa/93707
	* ipa-cp.c (same_node_or_its_all_contexts_clone_p): Replaced with
	new function calls_same_node_or_its_all_contexts_clone_p.
	(cgraph_edge_brings_value_p): Use it.
	(cgraph_edge_brings_value_p): Likewise.
	(self_recursive_pass_through_p): Return false if caller is a clone.
	(self_recursive_agg_pass_through_p): Likewise.

	testsuite/
	* gcc.dg/ipa/pr93707.c: New test.
parent 9640ff5a
2020-02-27 Martin Jambor <mjambor@suse.cz>
Feng Xue <fxue@os.amperecomputing.com>
PR ipa/93707
* ipa-cp.c (same_node_or_its_all_contexts_clone_p): Replaced with
new function calls_same_node_or_its_all_contexts_clone_p.
(cgraph_edge_brings_value_p): Use it.
(cgraph_edge_brings_value_p): Likewise.
(self_recursive_pass_through_p): Return false if caller is a clone.
(self_recursive_agg_pass_through_p): Likewise.
2020-02-27 Jan Hubicka <hubicka@ucw.cz> 2020-02-27 Jan Hubicka <hubicka@ucw.cz>
PR middle-end/92152 PR middle-end/92152
......
...@@ -4035,15 +4035,25 @@ edge_clone_summary_t::duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge, ...@@ -4035,15 +4035,25 @@ edge_clone_summary_t::duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
src_data->next_clone = dst_edge; src_data->next_clone = dst_edge;
} }
/* Return true is NODE is DEST or its clone for all contexts. */ /* Return true is CS calls DEST or its clone for all contexts. When
ALLOW_RECURSION_TO_CLONE is false, also return false for self-recursive
edges from/to an all-context clone. */
static bool static bool
same_node_or_its_all_contexts_clone_p (cgraph_node *node, cgraph_node *dest) calls_same_node_or_its_all_contexts_clone_p (cgraph_edge *cs, cgraph_node *dest,
bool allow_recursion_to_clone)
{ {
if (node == dest) enum availability availability;
cgraph_node *callee = cs->callee->function_symbol (&availability);
if (availability <= AVAIL_INTERPOSABLE)
return false;
if (callee == dest)
return true; return true;
if (!allow_recursion_to_clone && cs->caller == callee)
return false;
class ipa_node_params *info = IPA_NODE_REF (node); class ipa_node_params *info = IPA_NODE_REF (callee);
return info->is_all_contexts_clone && info->ipcp_orig_node == dest; return info->is_all_contexts_clone && info->ipcp_orig_node == dest;
} }
...@@ -4055,11 +4065,8 @@ cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src, ...@@ -4055,11 +4065,8 @@ cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src,
cgraph_node *dest, ipcp_value<tree> *dest_val) cgraph_node *dest, ipcp_value<tree> *dest_val)
{ {
class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
enum availability availability;
cgraph_node *real_dest = cs->callee->function_symbol (&availability);
if (availability <= AVAIL_INTERPOSABLE if (!calls_same_node_or_its_all_contexts_clone_p (cs, dest, !src->val)
|| !same_node_or_its_all_contexts_clone_p (real_dest, dest)
|| caller_info->node_dead) || caller_info->node_dead)
return false; return false;
...@@ -4078,9 +4085,6 @@ cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src, ...@@ -4078,9 +4085,6 @@ cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src,
} }
else 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) if (src->val == dest_val)
return true; return true;
...@@ -4115,11 +4119,8 @@ cgraph_edge_brings_value_p (cgraph_edge *cs, ...@@ -4115,11 +4119,8 @@ cgraph_edge_brings_value_p (cgraph_edge *cs,
ipcp_value<ipa_polymorphic_call_context> *) ipcp_value<ipa_polymorphic_call_context> *)
{ {
class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
enum availability avail;
cgraph_node *real_dest = cs->callee->function_symbol (&avail);
if (avail <= AVAIL_INTERPOSABLE if (!calls_same_node_or_its_all_contexts_clone_p (cs, dest, true)
|| !same_node_or_its_all_contexts_clone_p (real_dest, dest)
|| caller_info->node_dead) || caller_info->node_dead)
return false; return false;
if (!src->val) if (!src->val)
...@@ -4619,9 +4620,10 @@ create_specialized_node (struct cgraph_node *node, ...@@ -4619,9 +4620,10 @@ create_specialized_node (struct cgraph_node *node,
return new_node; return new_node;
} }
/* Return true, if JFUNC, which describes a i-th parameter of call CS, is a /* Return true if JFUNC, which describes a i-th parameter of call CS, is a
pass-through function to itself. When SIMPLE is true, further check if pass-through function to itself when the cgraph_node involved is not an
JFUNC is a simple no-operation pass-through. */ IPA-CP clone. When SIMPLE is true, further check if JFUNC is a simple
no-operation pass-through. */
static bool static bool
self_recursive_pass_through_p (cgraph_edge *cs, ipa_jump_func *jfunc, int i, self_recursive_pass_through_p (cgraph_edge *cs, ipa_jump_func *jfunc, int i,
...@@ -4632,15 +4634,18 @@ self_recursive_pass_through_p (cgraph_edge *cs, ipa_jump_func *jfunc, int i, ...@@ -4632,15 +4634,18 @@ self_recursive_pass_through_p (cgraph_edge *cs, ipa_jump_func *jfunc, int i,
&& availability > AVAIL_INTERPOSABLE && availability > AVAIL_INTERPOSABLE
&& jfunc->type == IPA_JF_PASS_THROUGH && jfunc->type == IPA_JF_PASS_THROUGH
&& (!simple || ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) && (!simple || ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
&& ipa_get_jf_pass_through_formal_id (jfunc) == i) && ipa_get_jf_pass_through_formal_id (jfunc) == i
&& IPA_NODE_REF (cs->caller)
&& !IPA_NODE_REF (cs->caller)->ipcp_orig_node)
return true; return true;
return false; return false;
} }
/* Return true, if JFUNC, which describes a part of an aggregate represented /* Return true if JFUNC, which describes a part of an aggregate represented or
or pointed to by the i-th parameter of call CS, is a pass-through function pointed to by the i-th parameter of call CS, is a pass-through function to
to itself. When SIMPLE is true, further check if JFUNC is a simple itself when the cgraph_node involved is not an IPA-CP clone.. When
no-operation pass-through. */ SIMPLE is true, further check if JFUNC is a simple no-operation
pass-through. */
static bool static bool
self_recursive_agg_pass_through_p (cgraph_edge *cs, ipa_agg_jf_item *jfunc, self_recursive_agg_pass_through_p (cgraph_edge *cs, ipa_agg_jf_item *jfunc,
...@@ -4653,7 +4658,9 @@ self_recursive_agg_pass_through_p (cgraph_edge *cs, ipa_agg_jf_item *jfunc, ...@@ -4653,7 +4658,9 @@ self_recursive_agg_pass_through_p (cgraph_edge *cs, ipa_agg_jf_item *jfunc,
&& jfunc->offset == jfunc->value.load_agg.offset && jfunc->offset == jfunc->value.load_agg.offset
&& (!simple || jfunc->value.pass_through.operation == NOP_EXPR) && (!simple || jfunc->value.pass_through.operation == NOP_EXPR)
&& jfunc->value.pass_through.formal_id == i && jfunc->value.pass_through.formal_id == i
&& useless_type_conversion_p (jfunc->value.load_agg.type, jfunc->type)) && useless_type_conversion_p (jfunc->value.load_agg.type, jfunc->type)
&& IPA_NODE_REF (cs->caller)
&& !IPA_NODE_REF (cs->caller)->ipcp_orig_node)
return true; return true;
return false; return false;
} }
......
2020-02-27 Martin Jambor <mjambor@suse.cz>
Feng Xue <fxue@os.amperecomputing.com>
PR ipa/93707
* gcc.dg/ipa/pr93707.c: New test.
2020-02-27 Jan Hubicka <hubicka@ucw.cz> 2020-02-27 Jan Hubicka <hubicka@ucw.cz>
PR middle-end/92152 PR middle-end/92152
......
/* { dg-do compile } */
/* { dg-options "-O3 --param ipa-cp-eval-threshold=1 -fdump-ipa-cp" } */
int foo();
int data[100];
__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;
}
/* { dg-final { scan-ipa-dump-times "Clone of recur_fn/" 2 "cp" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment