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:
parent
18bc19a7aa
commit
90cb08ca01
@ -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
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user