Hi, the patch below should fix PR 50287 (and its many duplicates) by simply never attempting to create new default-defs for unused non-register parameters and using their DECL when calling the split function. Note that all of this is relevant only in the case when there is some other reason why we cannot change the function's signature (typically because there are function attributes). Otherwise, parameters that are not used or referenced in any way are not passed on to the split function.
This is correct because it does not really matter what actual value we pass to the split function for any non-register parameter because all statements that are going to end up in the split function are checked by mark_nonssa_use which makes sure it does not use, store or take address of any such PARM_DECL. The patch passes bootstrap and testing on x86_64-linux, it has successfully LTO-built Firefox and I'm LTO-building a few SPEC 2006 benchmarks with it right now. Of course it fixes the ICE when compiling the testcase (and I have verified that the 4.6 version also fixes the ICE when compiling the reduced testcase of PR 50295). OK for trunk (and then for the 4.6 branch)? Thanks, Martin 2011-09-06 Martin Jambor <mjam...@suse.cz> PR tree-optimization/50287 * ipa-split.c (split_function): Do not create SSA names for non-gimple-registers. * testsuite/gcc.dg/torture/pr50287.c: New test. Index: src/gcc/testsuite/gcc.dg/torture/pr50287.c =================================================================== --- /dev/null +++ src/gcc/testsuite/gcc.dg/torture/pr50287.c @@ -0,0 +1,109 @@ +/* { dg-do compile } */ + +struct PMC { + unsigned flags; +}; + +struct PVC { + unsigned flags, other_stuff; +}; + + +typedef struct Pcc_cell +{ + struct PMC *p; + long bla; + long type; +} Pcc_cell; + +int gi; +int cond; + +struct PVC g_pvc; + +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, struct PVC pvc) + __attribute__((__nonnull__(1))); + +static void +mark_cell(int * interp, Pcc_cell *c, struct PVC pvc) +{ + if (!cond) + return; + + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<8))) + never_ever(gi + 1, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<7))) + never_ever(gi + 2, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<6))) + never_ever(gi + 3, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<5))) + never_ever(gi + 4, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<4))) + never_ever(gi + 5, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<3))) + never_ever(gi + 6, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<2))) + never_ever(gi + 7, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<1))) + never_ever(gi + 8, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<9))) + never_ever(gi + 9, c->p); +} + +static void +foo(int * interp, Pcc_cell *c) +{ + mark_cell(interp, c, g_pvc); +} + +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, g_pvc); +} + +void +bar_2 (int * interp, Pcc_cell *c, struct PVC pvc) +{ + c->bla += 2; + mark_cell(interp, c, pvc); +} + Index: src/gcc/ipa-split.c =================================================================== --- src.orig/gcc/ipa-split.c +++ src/gcc/ipa-split.c @@ -985,15 +985,20 @@ split_function (struct split_point *spli bitmap_set_bit (args_to_skip, num); else { - arg = gimple_default_def (cfun, parm); - if (!arg) + /* This parm might not have been used up to now, but is going to be + used, hence register it. */ + add_referenced_var (parm); + if (is_gimple_reg (parm)) { - /* 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); + arg = gimple_default_def (cfun, parm); + if (!arg) + { + arg = make_ssa_name (parm, gimple_build_nop ()); + set_default_def (parm, arg); + } } + else + arg = parm; if (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)) != TYPE_MAIN_VARIANT (TREE_TYPE (arg)))