https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63573
--- Comment #16 from Martin Liška <marxin at gcc dot gnu.org> --- (In reply to Jan Hubicka from comment #15) > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63573 > > > > --- Comment #14 from Martin Liška <marxin at gcc dot gnu.org> --- > > (In reply to Andreas Schwab from comment #12) > > > This also breaks g++.dg/ipa/pr63587-2.C on powerpc -m32, but the patches > > > in > > > #c6 and #c8 don't fix that. > > > > > > $ gcc/xg++ -Bgcc/ ../gcc/testsuite/g++.dg/ipa/pr63587-2.C -nostdinc++ > > > -Ipowerpc64-linux/32/libstdc++-v3/include/powerpc64-linux > > > -Ipowerpc64-linux/32/libstdc++-v3/include -I../libstdc++-v3/libsupc++ > > > -I../libstdc++-v3/include/backward -I../libstdc++-v3/testsuite/util > > > -std=gnu++11 -O2 -S -m32 -o pr63587-2.s > > > ../gcc/testsuite/g++.dg/ipa/pr63587-2.C: In static member function > > > ???static > > > int > > > boost::function_obj_invoker0<FunctionObj>::invoke(boost::function_buffer&) > > > [with FunctionObj = > > > boost::test_case_template_invoker<default_formatting_invoker>]???: > > > ../gcc/testsuite/g++.dg/ipa/pr63587-2.C:21:3: internal compiler error: in > > > expand_expr_addr_expr_1, at expr.c:7725 > > > > There's really problem that both suggested patches can fix just cases where > > DECL_INCOMING_RTL is defined. In following situation: > > > > static boost::log::make_output_actor<ActorT<LeftExprT>, RightT, > > ValueT>::type > > boost::log::make_output_actor<ActorT<LeftExprT>, RightT, > > ValueT>::make(ActorT<LeftExprT>, RightT&) [with ActorT = boost::actor; > > LeftExprT = > > boost::log::attribute_output_terminal<boost::actor<boost::log::attribute_output_terminal<boost::actor<int>, > > boost::log::to_log_fun> >, boost::log::to_log_fun>; RightT = > > boost::log::attribute_actor<int, boost::log::value_extractor, void, > > boost::actor>; ValueT = int; > > boost::log::make_output_actor<ActorT<LeftExprT>, > > RightT, ValueT>::type = > > boost::actor<boost::log::attribute_output_terminal<boost::actor<boost::log::attribute_output_terminal<boost::actor<boost::log::attribute_output_terminal<boost::actor<int>, > > boost::log::to_log_fun> >, boost::log::to_log_fun> >, > > boost::log::to_log_fun> > > >] (struct actor left, struct attribute_actor & right) > > { > > struct type D.4892; > > struct attribute_name D.4891; > > struct to_log_fun D.4890; > > struct actor left; > > > > <bb 2>: > > left = left; > > The reason here is that thunk expansion introduce extra temporary. > if (nargs) > for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN > (arg)) > { > tree tmp = arg; > if (!is_gimple_val (arg)) > { > tmp = create_tmp_reg (TYPE_MAIN_VARIANT > (TREE_TYPE (arg)), "arg"); > gimple stmt = gimple_build_assign (tmp, arg); > gsi_insert_after (&bsi, stmt, GSI_NEW_STMT); > } > vargs.quick_push (tmp); > } > > the temporary obviously is not linked with the original memory expression. Ok, that makes sense. > > I supose we may want to simply drop the tailcall flag in cases copy is > necessary, but I do not really see why a copy is desirable here: IMO whatever > can be RHS of assignment can also be passed to function. What makes > left to be !is_gimple_val here? The loops iterates from 1..(nargs-1), where 'left' is first argument and is put to vargs here: if (this_adjusting) vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset, virtual_offset)); else if (nargs) vargs.quick_push (a); -----------^ if (nargs) for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg)) Martin > > Honza