]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
combine: Don't split insns if half is unused (PR82621)
authorSegher Boessenkool <segher@kernel.crashing.org>
Fri, 24 Nov 2017 17:03:04 +0000 (18:03 +0100)
committerSegher Boessenkool <segher@gcc.gnu.org>
Fri, 24 Nov 2017 17:03:04 +0000 (18:03 +0100)
If we have a PARALLEL of two SETs, and one half is unused, we currently
happily split that into two instructions (albeit the unused one is
useless).  Worse, as PR82621 shows, combine will happily merge this
insn into I3 even if some intervening insn sets the same register
again, which is wrong.

This fixes it by not splitting PARALLELs with REG_UNUSED notes.  It
all is handled fine by combine in that case; just the "single set
that is unused" case isn't handled properly.

This also results in better code: combine will now actually throw
away the unused SET.  (It still won't do that in an I3).

PR rtl-optimization/82621
* combine.c (try_combine): Do not split PARALLELs of two SETs if the
dest of one of those SETs is unused.

From-SVN: r255143

gcc/ChangeLog
gcc/combine.c

index b0e03768700fb58262d9f26b29fc5b5bdd57a6e6..42162dc2715b90bc5a34098251cb3d6931d1f398 100644 (file)
@@ -1,3 +1,12 @@
+2017-11-24  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       Backport from mainline
+       2017-11-17  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       PR rtl-optimization/82621
+       * combine.c (try_combine): Do not split PARALLELs of two SETs if the
+       dest of one of those SETs is unused.
+
 2017-11-21  Pat Haugen  <pthaugen@us.ibm.com>
 
        Backport from mainline
index a989659f2888bbc7da95b659afbd2097243ccc64..24f2af12b899976068d4c7571e4e0d5f1c00ddbb 100644 (file)
@@ -2947,7 +2947,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
       && is_parallel_of_n_reg_sets (PATTERN (i2), 2)
       && can_split_parallel_of_n_reg_sets (i2, 2)
       && !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 0)), i2, i3)
-      && !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 1)), i2, i3))
+      && !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 1)), i2, i3)
+      && !find_reg_note (i2, REG_UNUSED, 0))
     {
       /* If there is no I1, there is no I0 either.  */
       i0 = i1;