Hi,
the fix for PR middle-end/61268:
https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=213002
changed validize_mem to modify its argument in-place, which in turns means
that emit_move_insn can do it too. That's a little surprising, but I guess
not really problematic in the end, except when the RTX is shared with the
DECL_RTL of a DECL node, because this DECL_RTL is also used for the debug info
at -O0; it's typically a MEM based on VIRTUAL_STACK_VARS_REGNUM initially but
it can be changed into a MEM based on a pseudo which then can be assigned a
volatile register by RA, in which case the debug info would be based on this
volatile register instead of the frame pointer, which can break backtraces.
The attached patch fixes one of those cases in assign_parm_setup_reg, which
results in broken backtraces for Visium and PowerPC/EABI for some testcase.
Tested on x86_64-suse-linux, OK for the mainline? What about the release
branches (5 & 6 are affected), is the issue worth fixing there too?
2016-06-22 Eric Botcazou <ebotca...@adacore.com>
* function.c (assign_parm_setup_reg): Prevent sharing in another case.
--
Eric Botcazou
Index: function.c
===================================================================
--- function.c (revision 237677)
+++ function.c (working copy)
@@ -3314,6 +3314,8 @@ assign_parm_setup_reg (struct assign_par
set_mem_attributes (parmreg, parm, 1);
}
+ /* We need to preserve an address based on VIRTUAL_STACK_VARS_REGNUM for
+ the debug info in case it is not legitimate. */
if (GET_MODE (parmreg) != GET_MODE (rtl))
{
rtx tempreg = gen_reg_rtx (GET_MODE (rtl));
@@ -3323,7 +3325,8 @@ assign_parm_setup_reg (struct assign_par
all->last_conversion_insn);
emit_move_insn (tempreg, rtl);
tempreg = convert_to_mode (GET_MODE (parmreg), tempreg, unsigned_p);
- emit_move_insn (parmreg, tempreg);
+ emit_move_insn (MEM_P (parmreg) ? copy_rtx (parmreg) : parmreg,
+ tempreg);
all->first_conversion_insn = get_insns ();
all->last_conversion_insn = get_last_insn ();
end_sequence ();
@@ -3331,7 +3334,7 @@ assign_parm_setup_reg (struct assign_par
did_conversion = true;
}
else
- emit_move_insn (parmreg, rtl);
+ emit_move_insn (MEM_P (parmreg) ? copy_rtx (parmreg) : parmreg, rtl);
rtl = parmreg;