diff options
| author | amodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-11-15 00:59:21 +0000 |
|---|---|---|
| committer | amodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-11-15 00:59:21 +0000 |
| commit | 95eeafc865f79b786ab34cb2b56b0ee8efcd6b0a (patch) | |
| tree | fb1b5a7c58c0d92dea3fff32e17615973850ea40 | |
| parent | fb532926b0ccd1c50b1110225c56b3ead0064c8a (diff) | |
| download | ppe42-gcc-95eeafc865f79b786ab34cb2b56b0ee8efcd6b0a.tar.gz ppe42-gcc-95eeafc865f79b786ab34cb2b56b0ee8efcd6b0a.zip | |
PR rtl-optimization/22002
* combine.c (distribute_notes): Detect cases where a reg dies
two or more times in a bb, including on the insn we are combining,
and place the death note on the correct range.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@106921 138bc75d-0d04-0410-961f-82ee72b054a4
| -rw-r--r-- | gcc/ChangeLog | 7 | ||||
| -rw-r--r-- | gcc/combine.c | 20 |
2 files changed, 27 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 433f6d0b581..188d5095c03 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2005-11-15 Alan Modra <amodra@bigpond.net.au> + + PR rtl-optimization/22002 + * combine.c (distribute_notes): Detect cases where a reg dies + two or more times in a bb, including on the insn we are combining, + and place the death note on the correct range. + 2005-11-14 Dale Johannesen <dalej@apple.com> * expmed.c (store_bit_field): Add offset unconditionally for diff --git a/gcc/combine.c b/gcc/combine.c index 82d260dafbc..9f910a7b336 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -12232,6 +12232,10 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2, { basic_block bb = this_basic_block; + /* You might think you could search back from FROM_INSN + rather than from I3, but combine tries to split invalid + combined instructions. This can result in the old I2 + or I1 moving later in the insn sequence. */ for (tem = PREV_INSN (i3); place == 0; tem = PREV_INSN (tem)) { if (! INSN_P (tem)) @@ -12332,6 +12336,22 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2, || (CALL_P (tem) && find_reg_fusage (tem, USE, XEXP (note, 0)))) { + /* This may not be the correct place for the death + note if FROM_INSN is before TEM, and the reg is + set between FROM_INSN and TEM. The reg might + die two or more times. An existing death note + means we are looking at the wrong live range. */ + if (from_insn + && INSN_CUID (from_insn) < INSN_CUID (tem) + && find_regno_note (tem, REG_DEAD, + REGNO (XEXP (note, 0)))) + { + tem = from_insn; + if (tem == BB_HEAD (bb)) + break; + continue; + } + place = tem; /* If we are doing a 3->2 combination, and we have a |

