combine: Don't split insns if half is unused (PR82621)
authorSegher Boessenkool <segher@kernel.crashing.org>
Fri, 17 Nov 2017 14:46:04 +0000 (15:46 +0100)
committerSegher Boessenkool <segher@gcc.gnu.org>
Fri, 17 Nov 2017 14:46:04 +0000 (15:46 +0100)
If we have a PARALLEL of two SETs, and one half is unused, we currently
happily split that into two instructions (although 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: r254874

gcc/ChangeLog
gcc/combine.c

index 993ac9bba249bb62ed04dd1e85437ae5228a092e..c0249e81aa5f841547a79feda9547bd5adacf99e 100644 (file)
@@ -1,3 +1,9 @@
+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-17  Richard Biener  <rguenther@suse.de>
 
        PR fortran/83017
index eab10c599a61bffdbbecd1c37a38da0f30768cf8..404cf33e9d066cc2271fb58be19781052c11ea19 100644 (file)
@@ -3010,7 +3010,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;