diff --git a/gcc/function.c b/gcc/function.c index 00b2fe70c7d..e47931a2695 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -3036,7 +3036,23 @@ assign_parm_setup_block (struct assign_parm_data_all *all, reg = gen_rtx_REG (word_mode, REGNO (entry_parm)); reg = convert_to_mode (mode, copy_to_reg (reg), 1); } - emit_move_insn (change_address (mem, mode, 0), reg); + + /* We use change_address to get a new MEM with the mode + changed. But that new MEM will not have a full set + of attributes such as MEM_EXPR. + + This can inhibit later optimizations like DSE which + assumes if there is no MEM_EXPR, then the memory + must escape the current function. + + The MEM_EXPR on the original MEM expression should be + the PARM_DECL which should be safe to attach to the + new MEM. */ + gcc_assert (MEM_EXPR (mem)); + gcc_assert (TREE_CODE (MEM_EXPR (mem)) == PARM_DECL); + rtx new_mem = change_address (mem, mode, 0); + set_mem_attributes (new_mem, MEM_EXPR (mem), 1); + emit_move_insn (new_mem, reg); } #ifdef BLOCK_REG_PADDING