aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2018-08-22 15:41:05 +0200
committerSegher Boessenkool <segher@gcc.gnu.org>2018-08-22 15:41:05 +0200
commit90cb08ca01e22a2b720274611c4e5b05c961ee2c (patch)
treedb943e0a4811520e72183aad1413716632f942a3 /gcc
parent18bc19a7aa4cd08d45d64f6741b8b1e0f48f262b (diff)
downloadgcc-90cb08ca01e22a2b720274611c4e5b05c961ee2c.zip
gcc-90cb08ca01e22a2b720274611c4e5b05c961ee2c.tar.gz
gcc-90cb08ca01e22a2b720274611c4e5b05c961ee2c.tar.bz2
combine: Do another check before splitting a parallel (PR86771)
When combine splits a resulting parallel into its two SETs, it has to place one at i2, and the other stays at i3. This does not work if the destination of the SET that will be placed at i2 is modified between i2 and i3. This patch fixes it. * combine.c (try_combine): Do not allow splitting a resulting PARALLEL of two SETs into those two SETs, one to be placed at i2, if that SETs destination is modified between i2 and i3. From-SVN: r263776
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/combine.c10
2 files changed, 14 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c5515e4..fb267ab 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2018-08-22 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * combine.c (try_combine): Do not allow splitting a resulting PARALLEL
+ of two SETs into those two SETs, one to be placed at i2, if that SETs
+ destination is modified between i2 and i3.
+
2018-08-22 Richard Sandiford <richard.sandiford@arm.com>
PR tree-optimization/86725
diff --git a/gcc/combine.c b/gcc/combine.c
index 7a0abf2..d322614 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -4036,7 +4036,10 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
other insns to combine, but the destination of that SET is still live.
Also do this if we started with two insns and (at least) one of the
- resulting sets is a noop; this noop will be deleted later. */
+ resulting sets is a noop; this noop will be deleted later.
+
+ Also do this if we started with two insns neither of which was a simple
+ move. */
else if (insn_code_number < 0 && asm_noperands (newpat) < 0
&& GET_CODE (newpat) == PARALLEL
@@ -4066,13 +4069,15 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
one which uses any regs/memory set in between i2 and i3 can't
be first. The PARALLEL might also have been pre-existing in i3,
so we need to make sure that we won't wrongly hoist a SET to i2
- that would conflict with a death note present in there. */
+ that would conflict with a death note present in there, or would
+ have its dest modified between i2 and i3. */
if (!modified_between_p (SET_SRC (set1), i2, i3)
&& !(REG_P (SET_DEST (set1))
&& find_reg_note (i2, REG_DEAD, SET_DEST (set1)))
&& !(GET_CODE (SET_DEST (set1)) == SUBREG
&& find_reg_note (i2, REG_DEAD,
SUBREG_REG (SET_DEST (set1))))
+ && !modified_between_p (SET_DEST (set1), i2, i3)
&& (!HAVE_cc0 || !reg_referenced_p (cc0_rtx, set0))
/* If I3 is a jump, ensure that set0 is a jump so that
we do not create invalid RTL. */
@@ -4088,6 +4093,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
&& !(GET_CODE (SET_DEST (set0)) == SUBREG
&& find_reg_note (i2, REG_DEAD,
SUBREG_REG (SET_DEST (set0))))
+ && !modified_between_p (SET_DEST (set0), i2, i3)
&& (!HAVE_cc0 || !reg_referenced_p (cc0_rtx, set1))
/* If I3 is a jump, ensure that set1 is a jump so that
we do not create invalid RTL. */