https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63573
--- Comment #6 from Jan Hubicka <hubicka at gcc dot gnu.org> --- OK, so the problem is the following. There is a parameter that is passed by reference. Because it is a single scalar (packed in structure) it gets promoted to register by function.c as an optimization. This however is not welcome by the tail call expansion code that needs to use original memory location to pass the parameter further. The original memory location is still linked by DECL_INCOMING_RTL that is readily available: Index: expr.c =================================================================== --- expr.c (revision 216942) +++ expr.c (working copy) @@ -7660,6 +7660,13 @@ expand_expr_addr_expr_1 (tree exp, rtx t modifier == EXPAND_INITIALIZER ? EXPAND_INITIALIZER : EXPAND_CONST_ADDRESS); + if (!MEM_P (result) + && TREE_ADDRESSABLE (exp) + && TREE_CODE (exp) == PARM_DECL + && DECL_INCOMING_RTL (exp) + && MEM_P (DECL_INCOMING_RTL (exp))) + result = DECL_INCOMING_RTL (exp); + /* If the DECL isn't in memory, then the DECL wasn't properly marked TREE_ADDRESSABLE, which will be either a front-end or a tree optimizer bug. */ this patch lets me to continue in bootstrap. I am bit concerned about its safety however: DECL_RTL and DECL_INCOMING_RTL may not be kept in sync in real function (not thunk) and at this point we do not have any way to assert that we are not expanding thunk. However I think this is only place I can think of where TREE_ADDRESSABLE flag is validly set on value that is not in memory. Perhaps we could replace DECL_RTL by DECL_INCOMMING_RTL instead in calls.c at the place we mark it addressable to make IL more consistent?