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
This commit is contained in:
Segher Boessenkool 2018-08-22 15:41:05 +02:00 committed by Segher Boessenkool
parent 18bc19a7aa
commit 90cb08ca01
2 changed files with 14 additions and 2 deletions

View File

@ -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

View File

@ -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. */