On February 8, 2016 7:27:49 PM GMT+01:00, Jakub Jelinek <ja...@redhat.com> wrote: >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?
OK. Thanks, Richard. >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