On Wed, Apr 01, 2015 at 08:32:04AM +0200, Jan Hubicka wrote: > this patch solves ICE in the attached testcase on mingw32. The problem is > that > on Windows API long double is passed & returned by reference and while > expanidng > the tunk tail call, we get lost because we turn the parameter into SSA name > and > later need its address to pass it further. > > The patch extends hack > https://gcc.gnu.org/ml/gcc-patches/2014-11/msg00423.html > to handle not only non-registers but also registers. > > Bootstrapped/regtested ppc64-linux. OK?
I think it might be better to handle thunks the same way as other tail calls, but --- gcc/cgraphunit.c 2015-04-03 15:32:31.000000000 +0200 +++ gcc/cgraphunit.c 2015-04-07 13:02:16.537723725 +0200 @@ -1767,7 +1767,17 @@ cgraph_node::expand_thunk (bool output_a /* Build return value. */ if (!DECL_BY_REFERENCE (resdecl)) - ret = gimple_build_return (restmp); + { + if (is_gimple_reg_type (restype) + && aggregate_value_p (resdecl, TREE_TYPE (thunk_fndecl))) + { + gimple stmt = gimple_build_assign (resdecl, restmp); + gsi_insert_after (&bsi, stmt, GSI_NEW_STMT); + ret = gimple_build_return (resdecl); + } + else + ret = gimple_build_return (restmp); + } else ret = gimple_build_return (resdecl); (which generates the same GIMPLE code as say long double func1 (long double x); long double func2 (long double x) { return func1 (x); } on both mingw and x86_64-linux) doesn't really work, because calls.c treats calls in thunks differently from other calls - only in the thunks it takes ADDR_EXPR of the parameter/result. Thus your patch is ok for trunk, but please add the testcase into the testsuite. > PR ipa/65540 > * calls.c (initialize_argument_information): When producing tail > call also turn SSA_NAMES passed by references to original PARM_DECLs > Index: calls.c > =================================================================== > --- calls.c (revision 221805) > +++ calls.c (working copy) > @@ -1321,6 +1321,15 @@ initialize_argument_information (int num > && TREE_CODE (base) != SSA_NAME > && (!DECL_P (base) || MEM_P (DECL_RTL (base))))) > { > + /* We may have turned the parameter value into an SSA name. > + Go back to the original parameter so we can take the > + address. */ > + if (TREE_CODE (args[i].tree_value) == SSA_NAME) > + { > + gcc_assert (SSA_NAME_IS_DEFAULT_DEF (args[i].tree_value)); > + args[i].tree_value = SSA_NAME_VAR (args[i].tree_value); > + gcc_assert (TREE_CODE (args[i].tree_value) == PARM_DECL); > + } > /* Argument setup code may have copied the value to register. We > revert that optimization now because the tail call code must > use the original location. */ Jakub