Hi, I'm going to apply this after a quick c-only bootstrap and test on the 4.6 branch to revert my previous fix for PR 49886 because it causes PR 50295 (and probably also PR 50287 though I do not know whether that is against trunk or 4.6 too).
I'm not reverting this on trunk because I know there is at least one another patch depending on it (the IPA-CP fro unchangeable signatures). I'm going to look into ways to fix it there right now (and Honza promised the same) and after it is done we'll backport the correct fix here too. The execution part of the testcase for PR 49886 is XFAILed by this patch but that means it XPASSes with LTO. This is the best I could do in reasonable time though, it has taken me quite a lot of time already. Thanks, Martin 2011-09-06 Martin Jambor <mjam...@suse.cz> Revert 2011-09-02 Martin Jambor <mjam...@suse.cz> PR middle-end/49886 * ipa-split.c (split_function): Do not skip any arguments if can_change_signature is set or there are function type attributes. testsuite/ * gcc.c-torture/execute/pr49886.c: Move to... * gcc.dg/torture/pr49886.c: ...here. Xfail run test for -O2 and above. Index: gcc/testsuite/gcc.c-torture/execute/pr49886.c =================================================================== --- gcc/testsuite/gcc.c-torture/execute/pr49886.c (revision 178572) +++ gcc/testsuite/gcc.c-torture/execute/pr49886.c (working copy) @@ -1,100 +0,0 @@ -struct PMC { - unsigned flags; -}; - -typedef struct Pcc_cell -{ - struct PMC *p; - long bla; - long type; -} Pcc_cell; - -int gi; -int cond; - -extern void abort (); -extern void never_ever(int interp, struct PMC *pmc) - __attribute__((noinline,noclone)); - -void never_ever (int interp, struct PMC *pmc) -{ - abort (); -} - -static void mark_cell(int * interp, Pcc_cell *c) - __attribute__((__nonnull__(1))); - -static void -mark_cell(int * interp, Pcc_cell *c) -{ - if (!cond) - return; - - if (c && c->type == 4 && c->p - && !(c->p->flags & (1<<18))) - never_ever(gi + 1, c->p); - if (c && c->type == 4 && c->p - && !(c->p->flags & (1<<17))) - never_ever(gi + 2, c->p); - if (c && c->type == 4 && c->p - && !(c->p->flags & (1<<16))) - never_ever(gi + 3, c->p); - if (c && c->type == 4 && c->p - && !(c->p->flags & (1<<15))) - never_ever(gi + 4, c->p); - if (c && c->type == 4 && c->p - && !(c->p->flags & (1<<14))) - never_ever(gi + 5, c->p); - if (c && c->type == 4 && c->p - && !(c->p->flags & (1<<13))) - never_ever(gi + 6, c->p); - if (c && c->type == 4 && c->p - && !(c->p->flags & (1<<12))) - never_ever(gi + 7, c->p); - if (c && c->type == 4 && c->p - && !(c->p->flags & (1<<11))) - never_ever(gi + 8, c->p); - if (c && c->type == 4 && c->p - && !(c->p->flags & (1<<10))) - never_ever(gi + 9, c->p); -} - -static void -foo(int * interp, Pcc_cell *c) -{ - mark_cell(interp, c); -} - -static struct Pcc_cell * -__attribute__((noinline,noclone)) -getnull(void) -{ - return (struct Pcc_cell *) 0; -} - - -int main() -{ - int i; - - cond = 1; - for (i = 0; i < 100; i++) - foo (&gi, getnull ()); - return 0; -} - - -void -bar_1 (int * interp, Pcc_cell *c) -{ - c->bla += 1; - mark_cell(interp, c); -} - -void -bar_2 (int * interp, Pcc_cell *c) -{ - c->bla += 2; - mark_cell(interp, c); -} - Index: gcc/testsuite/gcc.dg/torture/pr49886.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr49886.c (revision 178572) +++ gcc/testsuite/gcc.dg/torture/pr49886.c (working copy) @@ -1,3 +1,6 @@ +/* { dg-do run } */ +/* { dg-xfail-run-if "" { "*-*-*" } { "-O2" "-O3" "-Os" } } */ + struct PMC { unsigned flags; }; Index: gcc/ipa-split.c =================================================================== --- gcc/ipa-split.c (revision 178572) +++ gcc/ipa-split.c (working copy) @@ -943,10 +943,10 @@ static void split_function (struct split_point *split_point) { VEC (tree, heap) *args_to_pass = NULL; - bitmap args_to_skip; + bitmap args_to_skip = BITMAP_ALLOC (NULL); tree parm; int num = 0; - struct cgraph_node *node, *cur_node = cgraph_node (current_function_decl); + struct cgraph_node *node; basic_block return_bb = find_return_bb (); basic_block call_bb; gimple_stmt_iterator gsi; @@ -966,34 +966,17 @@ split_function (struct split_point *spli dump_split_point (dump_file, split_point); } - if (cur_node->local.can_change_signature - && !TYPE_ATTRIBUTES (TREE_TYPE (cur_node->decl))) - args_to_skip = BITMAP_ALLOC (NULL); - else - args_to_skip = NULL; - /* Collect the parameters of new function and args_to_skip bitmap. */ for (parm = DECL_ARGUMENTS (current_function_decl); parm; parm = DECL_CHAIN (parm), num++) - if (args_to_skip - && (!is_gimple_reg (parm) - || !gimple_default_def (cfun, parm) - || !bitmap_bit_p (split_point->ssa_names_to_pass, - SSA_NAME_VERSION (gimple_default_def (cfun, - parm))))) + if (!is_gimple_reg (parm) + || !gimple_default_def (cfun, parm) + || !bitmap_bit_p (split_point->ssa_names_to_pass, + SSA_NAME_VERSION (gimple_default_def (cfun, parm)))) bitmap_set_bit (args_to_skip, num); else { arg = gimple_default_def (cfun, parm); - if (!arg) - { - /* This parm wasn't used up to now, but is going to be used, - hence register it. */ - add_referenced_var (parm); - arg = make_ssa_name (parm, gimple_build_nop ()); - set_default_def (parm, arg); - } - if (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)) != TYPE_MAIN_VARIANT (TREE_TYPE (arg))) { @@ -1074,7 +1057,9 @@ split_function (struct split_point *spli /* Now create the actual clone. */ rebuild_cgraph_edges (); - node = cgraph_function_versioning (cur_node, NULL, NULL, args_to_skip, + node = cgraph_function_versioning (cgraph_node (current_function_decl), + NULL, NULL, + args_to_skip, split_point->split_bbs, split_point->entry_bb, "part"); /* For usual cloning it is enough to clear builtin only when signature @@ -1085,7 +1070,7 @@ split_function (struct split_point *spli DECL_BUILT_IN_CLASS (node->decl) = NOT_BUILT_IN; DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0; } - cgraph_node_remove_callees (cur_node); + cgraph_node_remove_callees (cgraph_node (current_function_decl)); if (!split_part_return_p) TREE_THIS_VOLATILE (node->decl) = 1; if (dump_file)