> Hi! > > As discussed in the PR, for functions that return an aggregate that is not > aggregate_value_p (i.e. returned in registers), using RESULT_DECL is > undesirable, that's not what we normally emit for user code. > > So, this patch instead uses a temporary, which is optimized right now as > much as similar user written code. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK, thanks! Honza > > 2015-02-06 Jakub Jelinek <ja...@redhat.com> > > PR ipa/64896 > * cgraphunit.c (cgraph_node::expand_thunk): If > restype is not is_gimple_reg_type nor the thunk_fndecl > returns aggregate_value_p, set restmp to a temporary variable > instead of resdecl. > > * g++.dg/ipa/pr64896.C: New test. > > --- gcc/cgraphunit.c.jj 2015-01-29 21:38:21.000000000 +0100 > +++ gcc/cgraphunit.c 2015-02-06 13:18:44.870527405 +0100 > @@ -1609,11 +1609,16 @@ cgraph_node::expand_thunk (bool output_a > } > else if (!is_gimple_reg_type (restype)) > { > - restmp = resdecl; > + if (aggregate_value_p (resdecl, TREE_TYPE (thunk_fndecl))) > + { > + restmp = resdecl; > > - if (TREE_CODE (restmp) == VAR_DECL) > - add_local_decl (cfun, restmp); > - BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp; > + if (TREE_CODE (restmp) == VAR_DECL) > + add_local_decl (cfun, restmp); > + BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp; > + } > + else > + restmp = create_tmp_var (restype, "retval"); > } > else > restmp = create_tmp_reg (restype, "retval"); > --- gcc/testsuite/g++.dg/ipa/pr64896.C.jj 2015-02-06 13:36:30.076680258 > +0100 > +++ gcc/testsuite/g++.dg/ipa/pr64896.C 2015-02-06 13:36:13.000000000 > +0100 > @@ -0,0 +1,29 @@ > +// PR ipa/64896 > +// { dg-do compile } > +// { dg-options "-O2" } > + > +struct A { int a, b; }; > +struct B { A c; int d; }; > +struct C { virtual B fn1 () const; }; > +struct D { B fn2 () const; int fn3 () const; C *fn4 () const; }; > + > +int > +D::fn3 () const > +{ > + fn4 ()->fn1 (); > +} > + > +B > +D::fn2 () const > +{ > + return B (); > +} > + > +class F : C > +{ > + B > + fn1 () const > + { > + return B (); > + } > +}; > > Jakub