https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63766
--- Comment #2 from Ilya Enkovich <enkovich.gnu at gmail dot com> --- Problem caused by the fact that now all function come to local optimizations in SSA form. It affects inline parameters computation and therefore inlining order. During early SRA we call convert_callers_for_node which recomputes inline parameters for functions in SSA form. Previously it was computed only for function already processed by all early local passes. Now all functions are in SSA form and it means we may recompute inline parameters for function not yet processed by local optimizations. In this test we have function marked as inlinable which is not yet processed in do_per_function_toporder called for local_optimization_passes. It allows this function to be inlined and removed before it is actually processed (and still sit in order vector). Another cgraph_node created by SRA is allocated at the same slot as removed one and thus the same function is processed twice, which causes ICE in profiling pass. Solution here would be to either use another condition for inline_parameters recomputation or to handle nodes removal in do_per_function_toporder by registering proper node removal hook. Suppose the latter is better because allows more early inlining. Here is a possible fix (works for reproducer, not fully tested): diff --git a/gcc/passes.c b/gcc/passes.c index 5e91a79..4799efa 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -1609,6 +1609,19 @@ do_per_function (void (*callback) (function *, void *data), void *data) static int nnodes; static GTY ((length ("nnodes"))) cgraph_node **order; +static void +remove_cgraph_node_from_order (cgraph_node *node, void *) +{ + int i; + + for (i = 0; i < nnodes; i++) + if (order[i] == node) + { + order[i] = NULL; + return; + } +} + /* If we are in IPA mode (i.e., current_function_decl is NULL), call function CALLBACK for every function in the call graph. Otherwise, call CALLBACK on the current function. @@ -1622,13 +1635,20 @@ do_per_function_toporder (void (*callback) (function *, void *data), void *data) callback (cfun, data); else { + cgraph_node_hook_list *hook; gcc_assert (!order); order = ggc_vec_alloc<cgraph_node *> (symtab->cgraph_count); nnodes = ipa_reverse_postorder (order); for (i = nnodes - 1; i >= 0; i--) order[i]->process = 1; + hook = symtab->add_cgraph_removal_hook (remove_cgraph_node_from_order, + NULL); for (i = nnodes - 1; i >= 0; i--) { + /* Function could be inlined and removed as unreachable. */ + if (!order[i]) + continue; + struct cgraph_node *node = order[i]; /* Allow possibly removed nodes to be garbage collected. */ @@ -1637,6 +1657,7 @@ do_per_function_toporder (void (*callback) (function *, void *data), void *data) if (node->has_gimple_body_p ()) callback (DECL_STRUCT_FUNCTION (node->decl), data); } + symtab->remove_cgraph_removal_hook (hook); } ggc_free (order); order = NULL;