https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90990
--- Comment #8 from Jan Hubicka <hubicka at ucw dot cz> --- > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90990 > > --- Comment #7 from Martin Liška <marxin at gcc dot gnu.org> --- > So before we stream LTO byte code, we have: > > BEFORE: > > Released 0 names, 0.00%, removed 0 holes > A::A (struct A * const this) > { > <bb 2> [local count: 1073741824]: > MEM[(struct &)this_2(D)] ={v} {CLOBBER}; > return; > > } > > Released 1 names, 12.50%, removed 1 holes > C::operator() (struct C * const this) > { > struct A D.2395; > struct B * _2; > > <bb 2> [local count: 1073741824]: > _2 = &this_1(D)->m_basis; > D.2395 = B::operator[] (_2, 1); [return slot optimization] > D.2395 = B::operator[] (_2, 2); > D.2395 ={v} {CLOBBER}; > MEM[(struct &)&<retval>] ={v} {CLOBBER}; > return <retval>; > > } > > Released 1 names, 11.11%, removed 1 holes > F::F (struct F * const this, struct D & p1, const struct A & p2) > { > struct C D.2369; > > <bb 2> [local count: 1073741824]: > MEM[(struct &)this_2(D)] ={v} {CLOBBER}; > D::m_fn1 (p1_4(D)); > *this_2(D).m_pivotInB = C::operator() (&D.2369); [return slot optimization] > D.2369 ={v} {CLOBBER}; > return; > } > > AFTER: > > Released 0 names, 0.00%, removed 0 holes > A::A (struct A * const this) > { > <bb 2> [local count: 1073741824]: > *this_2(D) ={v} {CLOBBER}; > return; > } > > Released 1 names, 12.50%, removed 1 holes > C::operator() (struct C * const this) > { > struct A D.2397; > struct B * _2; > > <bb 2> [local count: 1073741824]: > _2 = &this_1(D)->m_basis; > D.2397 = B::operator[] (_2, 1); [return slot optimization] > D.2397 = B::operator[] (_2, 2); > D.2397 ={v} {CLOBBER}; > <retval> ={v} {CLOBBER}; > return <retval>; > } > > Released 1 names, 11.11%, removed 1 holes > F::F (struct F * const this, struct D & p1, const struct A & p2) > { > struct C D.2371; > > <bb 2> [local count: 1073741824]: > *this_2(D) ={v} {CLOBBER}; > D::m_fn1 (p1_4(D)); > *this_2(D).m_pivotInB = C::operator() (&D.2371); [return slot optimization] > D.2371 ={v} {CLOBBER}; > return; So it is inliner substituting the return slot which happens to be clobber? It makes sense but I wonder how this worked w/o the patch. > #10 0x00000000010f9dd5 in remap_gimple_stmt (stmt=0x7ffff75311e0, > id=0x7fffffffd6d0) at /home/marxin/Programming/gcc/gcc/tree-inline.c:1896 remap_gimple_stmt already has some code to drop clobbers after substitution /* For *ptr_N ={v} {CLOBBER}, if ptr_N is SSA_NAME defined in a block that we aren't copying during tree_function_versioning, just drop the clobber stmt. */ if (id->blocks_to_copy && gimple_clobber_p (stmt)) { tree lhs = gimple_assign_lhs (stmt); if (TREE_CODE (lhs) == MEM_REF && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME) perhaps we need to care about the retval here. Honza