Hi! This fixes an ICE, where the split part doesn't return a value of a is_gimple_reg_type retval, only compares its address (therefore it is addressable), and the main part only uses the var in return_bb. In that case, retval is not gimple val, but needs to be returned as gimple val. So we need to load it into a SSA_NAME. I've tried to construct testcases for other cases where we might need something similar, but have not succeeded, so maybe it is the only spot that needs such handling.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2016-02-08 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/69209 * ipa-split.c (split_function): If split part is not returning retval, retval has gimple type but is not gimple value, force it into a SSA_NAME first. * gcc.c-torture/compile/pr69209.c: New test. --- gcc/ipa-split.c.jj 2016-02-03 23:36:29.000000000 +0100 +++ gcc/ipa-split.c 2016-02-08 15:56:41.701994621 +0100 @@ -1628,8 +1628,22 @@ split_function (basic_block return_bb, s gimple_call_set_lhs (call, build_simple_mem_ref (retval)); else gimple_call_set_lhs (call, retval); + gsi_insert_after (&gsi, call, GSI_NEW_STMT); + } + else + { + gsi_insert_after (&gsi, call, GSI_NEW_STMT); + if (retval + && is_gimple_reg_type (TREE_TYPE (retval)) + && !is_gimple_val (retval)) + { + gassign *g + = gimple_build_assign (make_ssa_name (TREE_TYPE (retval)), + retval); + retval = gimple_assign_lhs (g); + gsi_insert_after (&gsi, g, GSI_NEW_STMT); + } } - gsi_insert_after (&gsi, call, GSI_NEW_STMT); /* Build bndret call to obtain returned bounds. */ if (retbnd) chkp_insert_retbnd_call (retbnd, retval, &gsi); --- gcc/testsuite/gcc.c-torture/compile/pr69209.c.jj 2016-02-08 16:13:32.527138280 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr69209.c 2016-02-08 16:13:19.000000000 +0100 @@ -0,0 +1,28 @@ +/* PR tree-optimization/69209 */ + +int a, c, *d, e; + +void foo (void) __attribute__ ((__noreturn__)); + +int +bar (void) +{ + int f; + if (a) + { + if (e) + foo (); + foo (); + } + if (d != &f) + foo (); + if (!c) + foo (); + return f; +} + +void +baz () +{ + bar (); +} Jakub