https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106977
--- Comment #20 from ibuclaw at gcc dot gnu.org --- (In reply to Andrew Pinski from comment #19) > (In reply to Andrew Pinski from comment #18) > > > I think the visibility type is POD (assuming D has that concept) > > At least the front-end does. > See dmd/dstruct.d:443 > > if isPOD return false, TREE_ADDRESSABLE is set on the struct. > I have not gone through the code otherwise. See d/decl.cc:950 It's not TREE_ADDRESSABLE, but on 32-bit the struct is considered to be 'aggregate_value_p', which in turn sets up return by hidden reference. This effects how the return is handled later (around toir.cc:1044), which splits up the init and return expression. Returning this way I guess is fine for extern(D) functions, however we should not be so eager to do rvo/sret for other extern language functions. Having a quick look at C++ front-end, they require both `aggregate_value_p` and for a named variable to be in the return expression. ``` if (current_function_return_value) { tree r = current_function_return_value; tree outer; if (r != error_mark_node /* This is only worth doing for fns that return in memory--and simpler, since we don't have to worry about promoted modes. */ && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)), fndecl) ``` So for the current gate in D: ``` if (TREE_ADDRESSABLE (TREE_TYPE (resdecl)) || aggregate_value_p (TREE_TYPE (resdecl), fndecl)) ``` I think tightening that to (its late, and my parentheses may be wrong). ``` if (TREE_ADDRESSABLE (TREE_TYPE (resdecl)) || ((d->resolvedLinkage () == LINK::d || (d->resolvedLinkage () == LINK::cpp && d->nrvo_var)) && aggregate_value_p (TREE_TYPE (resdecl), fndecl))) ``` Which is: 1. TREE_ADDRESSABLE 2. extern(D) and aggregate_value_p 3. extern(C++) and have NVRO variable and aggregate_value_p I guess for extern(C) functions we should just forget even attempting to do any (N)RVO/SRET returns and let tree-nrv.cc decide whether to optimize or not.