aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2017-11-01 17:40:42 +0100
committerSegher Boessenkool <segher@gcc.gnu.org>2017-11-01 17:40:42 +0100
commit0469527c52517c543890bb6ec4d82e279c390004 (patch)
treeed4b461c1722bd9a12494bc5c1ad769ae22d20f6
parentce12115844ef8f66a28205d1f1e81ea0ccc946b1 (diff)
downloadgcc-0469527c52517c543890bb6ec4d82e279c390004.zip
gcc-0469527c52517c543890bb6ec4d82e279c390004.tar.gz
gcc-0469527c52517c543890bb6ec4d82e279c390004.tar.bz2
combine: Fix bug in giving up placing REG_DEAD notes (PR82683)
When we have a REG_DEAD note for a reg that is set in the new I2, we drop the note on the floor (we cannot find whether to place it on I2 or on I3). But the code I added to do this has a bug and does not always actually drop it. This patch fixes it. But that on its own is too pessimistic, it turns out, and we generate worse code. One case where we do know where to place the note is if it came from I3 (it should go to I3 again). Doing this fixes all of the regressions. PR rtl-optimization/64682 PR rtl-optimization/69567 PR rtl-optimization/69737 PR rtl-optimization/82683 * combine.c (distribute_notes) <REG_DEAD>: If the new I2 sets the same register mentioned in the note, drop the note, unless it came from I3, in which case it should go to I3 again. From-SVN: r254315
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/combine.c16
2 files changed, 21 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 799cca8..cc51a72 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2017-11-01 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR rtl-optimization/64682
+ PR rtl-optimization/69567
+ PR rtl-optimization/69737
+ PR rtl-optimization/82683
+ * combine.c (distribute_notes) <REG_DEAD>: If the new I2 sets the same
+ register mentioned in the note, drop the note, unless it came from I3,
+ in which case it should go to I3 again.
+
2017-11-01 Richard Sandiford <richard.sandiford@linaro.org>
* tree-ssa-dse.c (normalize_ref): Check whether the ranges overlap
diff --git a/gcc/combine.c b/gcc/combine.c
index 4afae21..d5b15cb 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -14360,6 +14360,17 @@ distribute_notes (rtx notes, rtx_insn *from_insn, rtx_insn *i3, rtx_insn *i2,
&& CALL_P (from_insn)
&& find_reg_fusage (from_insn, USE, XEXP (note, 0)))
place = from_insn;
+ else if (i2 && reg_set_p (XEXP (note, 0), PATTERN (i2)))
+ {
+ /* If the new I2 sets the same register that is marked
+ dead in the note, we do not in general know where to
+ put the note. One important case we _can_ handle is
+ when the note comes from I3. */
+ if (from_insn == i3)
+ place = i3;
+ else
+ break;
+ }
else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)))
place = i3;
else if (i2 != 0 && next_nonnote_nondebug_insn (i2) == i3
@@ -14373,11 +14384,6 @@ distribute_notes (rtx notes, rtx_insn *from_insn, rtx_insn *i3, rtx_insn *i2,
|| rtx_equal_p (XEXP (note, 0), elim_i0))
break;
tem_insn = i3;
- /* If the new I2 sets the same register that is marked dead
- in the note, we do not know where to put the note.
- Give up. */
- if (i2 != 0 && reg_set_p (XEXP (note, 0), PATTERN (i2)))
- break;
}
if (place == 0)