Hi, PR 55260 has been reopened because there is still one use of wrong info, this time in cgraph_edge_brings_all_agg_vals_for_node when checking whether aggregate lattices are set to bottom which can lead to index out of bounds assert failures or even potentially ignoring bottom lattices.
Fixed thusly. Bootstrapped and tested on trunk on x86_64-linux, bootstrap is still underway on the 4.8 branch where this exact fix is also necessary. OK for both? Thanks, Martin 2014-02-03 Martin Jambor <mjam...@suse.cz> PR ipa/55260 * ipa-cp.c (cgraph_edge_brings_all_agg_vals_for_node): Uce correct info when checking whether lattices are bottom. testsuite/ * gcc.dg/ipa/pr55260.c: New test. diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 10fa4b6..70bb33f 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -3178,6 +3178,7 @@ cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs, struct cgraph_node *node) { struct ipa_node_params *orig_caller_info = IPA_NODE_REF (cs->caller); + struct ipa_node_params *orig_node_info; struct ipa_agg_replacement_value *aggval; int i, ec, count; @@ -3192,6 +3193,7 @@ cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs, if (aggval->index >= ec) return false; + orig_node_info = IPA_NODE_REF (IPA_NODE_REF (node)->ipcp_orig_node); if (orig_caller_info->ipcp_orig_node) orig_caller_info = IPA_NODE_REF (orig_caller_info->ipcp_orig_node); @@ -3209,7 +3211,7 @@ cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs, if (!interesting) continue; - plats = ipa_get_parm_lattices (orig_caller_info, aggval->index); + plats = ipa_get_parm_lattices (orig_node_info, aggval->index); if (plats->aggs_bottom) return false; diff --git a/gcc/testsuite/gcc.dg/ipa/pr55260.c b/gcc/testsuite/gcc.dg/ipa/pr55260.c new file mode 100644 index 0000000..ef151b0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr55260.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-inline -fipa-cp-clone" } */ + +typedef struct { + int *ptr; + int len; +} string; +typedef struct { + string nantstr; + int *nant; +} malv; +typedef struct { + int *nor; +} list_heads; +int b; +list_heads *fn1(string, int *, unsigned); +void fn2(malv *p1, list_heads *p2, unsigned p3) { + string a = p1->nantstr; + fn1(a, p1->nant, p3); +} + +void fn3(unsigned p1) { fn2(0, 0, p1); } + +list_heads *fn1(string p1, int *p2, unsigned p3) { + while (1) { + if (p3) + fn3(1); + if (b) + return 0; + fn3(1); + } +} + +void fn5() { + list_heads c; + c.nor = 0; + fn2(0, &c, 1); +}