combine: Fix bug in giving up placing REG_DEAD notes (PR82683)
authorSegher Boessenkool <segher@kernel.crashing.org>
Wed, 1 Nov 2017 16:40:42 +0000 (17:40 +0100)
committerSegher Boessenkool <segher@gcc.gnu.org>
Wed, 1 Nov 2017 16:40:42 +0000 (17:40 +0100)
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

gcc/ChangeLog
gcc/combine.c

index 799cca8ff77336ef11965ab41f46c9d797c4a4b5..cc51a722b36cf2a8efce2cca87bdc592ff1e2a49 100644 (file)
@@ -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
index 4afae213a3f129ebb4980ac3a2380a4bdeb76ade..d5b15cb3caaea17d0843c124c8d7ab9fcd1785c0 100644 (file)
@@ -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)