summaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-13 13:29:28 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-13 13:29:28 +0000
commit522ca5400502ca857adab503693ef095aaf9a1bc (patch)
tree9e9e3d0b28e42649ff838117757c2528579112bc /gcc/combine.c
parent8561b0408e1a5e3a2d48d28592e01a53f2e1de0f (diff)
downloadgcc-522ca5400502ca857adab503693ef095aaf9a1bc.tar.gz
PR rtl-optimization/58662
* combine.c (try_combine): Take into account death nodes on I2 when splitting a PARALLEL of two independent SETs. Fix dump message. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@203498 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index fcf60cd08aa..13f5e29e3d6 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -3693,29 +3693,42 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p,
&& ! (contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 0)))
&& contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 1)))))
{
+ rtx set0 = XVECEXP (newpat, 0, 0);
+ rtx set1 = XVECEXP (newpat, 0, 1);
+
/* Normally, it doesn't matter which of the two is done first,
but the one that references cc0 can't be the second, and
one which uses any regs/memory set in between i2 and i3 can't
- be first. */
- if (!use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)),
- DF_INSN_LUID (i2))
+ 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. */
+ if (!use_crosses_set_p (SET_SRC (set1), DF_INSN_LUID (i2))
+ && !(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))))
#ifdef HAVE_cc0
- && !reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0))
+ && !reg_referenced_p (cc0_rtx, set0)
#endif
)
{
- newi2pat = XVECEXP (newpat, 0, 1);
- newpat = XVECEXP (newpat, 0, 0);
+ newi2pat = set1;
+ newpat = set0;
}
- else if (!use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 0)),
- DF_INSN_LUID (i2))
+ else if (!use_crosses_set_p (SET_SRC (set0), DF_INSN_LUID (i2))
+ && !(REG_P (SET_DEST (set0))
+ && find_reg_note (i2, REG_DEAD, SET_DEST (set0)))
+ && !(GET_CODE (SET_DEST (set0)) == SUBREG
+ && find_reg_note (i2, REG_DEAD,
+ SUBREG_REG (SET_DEST (set0))))
#ifdef HAVE_cc0
- && !reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 1))
+ && !reg_referenced_p (cc0_rtx, set1)
#endif
)
{
- newi2pat = XVECEXP (newpat, 0, 0);
- newpat = XVECEXP (newpat, 0, 1);
+ newi2pat = set0;
+ newpat = set1;
}
else
{
@@ -4261,9 +4274,8 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p,
}
/* Update reg_stat[].nonzero_bits et al for any changes that may have
- been made to this insn. The order of
- set_nonzero_bits_and_sign_copies() is important. Because newi2pat
- can affect nonzero_bits of newpat */
+ been made to this insn. The order is important, because newi2pat
+ can affect nonzero_bits of newpat. */
if (newi2pat)
note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
@@ -4283,7 +4295,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p,
{
if (dump_file)
{
- fprintf (dump_file, "modifying insn i1 ");
+ fprintf (dump_file, "modifying insn i0 ");
dump_insn_slim (dump_file, i0);
}
df_insn_rescan (i0);
@@ -4321,7 +4333,6 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p,
/* Set new_direct_jump_p if a new return or simple jump instruction
has been created. Adjust the CFG accordingly. */
-
if (returnjump_p (i3) || any_uncondjump_p (i3))
{
*new_direct_jump_p = 1;