summaryrefslogtreecommitdiff
path: root/gcc/regrename.c
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>2013-01-18 00:54:47 -0700
committerJeff Law <law@gcc.gnu.org>2013-01-18 00:54:47 -0700
commitc664546f0e9d12d8f3249b67982e0b192e112bef (patch)
treeeeafc6e254984b4679789b0594673c47e2dc2585 /gcc/regrename.c
parent1f8b0400aa92a00ab1fd022d9e3eb3e0c7526f38 (diff)
re PR rtl-optimization/52573 (regrename creates overlapping register allocations for output operands)
PR rtl-optimization/52573 * regrename.c (build_def_use): Ignore REG_DEAD notes if there is a REG_UNUSED for the same register. * gcc.dg/pr52573.c: New test. From-SVN: r195288
Diffstat (limited to 'gcc/regrename.c')
-rw-r--r--gcc/regrename.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/gcc/regrename.c b/gcc/regrename.c
index df3d341db51..20e2ae9f792 100644
--- a/gcc/regrename.c
+++ b/gcc/regrename.c
@@ -1710,9 +1710,16 @@ build_def_use (basic_block bb)
scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_read,
OP_INOUT);
- /* Step 4: Close chains for registers that die here. */
+ /* Step 4: Close chains for registers that die here, unless
+ the register is mentioned in a REG_UNUSED note. In that
+ case we keep the chain open until step #7 below to ensure
+ it conflicts with other output operands of this insn.
+ See PR 52573. Arguably the insn should not have both
+ notes; it has proven difficult to fix that without
+ other undesirable side effects. */
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
- if (REG_NOTE_KIND (note) == REG_DEAD)
+ if (REG_NOTE_KIND (note) == REG_DEAD
+ && !find_regno_note (insn, REG_UNUSED, REGNO (XEXP (note, 0))))
{
remove_from_hard_reg_set (&live_hard_regs,
GET_MODE (XEXP (note, 0)),