https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84101
--- Comment #18 from Richard Biener <rguenth at gcc dot gnu.org> --- The following "fixes" struct ciao { long a; long b; }; struct ciao square(int num) { struct ciao beta; beta.a = num; beta.b = num*num; return beta; } producing wrong code though, somehow forgetting the upper half. The idea was to give the constructor expansion an idea of the target (TImode reg) so it can optimize for that. Not sure what goes wrong - I seem to get all things twice but still somewhat correct... Index: gcc/expr.c =================================================================== --- gcc/expr.c (revision 269960) +++ gcc/expr.c (working copy) @@ -7018,7 +7018,9 @@ store_field (rtx target, poly_int64 bits } } - temp = expand_normal (exp); + temp = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);//normal (exp); + if (temp == target) + return const0_rtx; /* We don't support variable-sized BLKmode bitfields, since our handling of BLKmode is bound up with the ability to break @@ -7641,6 +7643,8 @@ safe_from_p (const_rtx x, tree exp, int return 0; return 1; } + else if (TREE_CODE (exp) == SSA_NAME) + return 1; else if (TREE_CODE (exp) == ERROR_MARK) return 1; /* An already-visited SAVE_EXPR? */ else