Commit 3246afaa by Eric Botcazou

re PR rtl-optimization/58662 (wrong code at -O2 for dumb condition)

	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.

From-SVN: r203498
parent 6137391a
2013-10-13 Eric Botcazou <ebotcazou@adacore.com>
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.
2013-10-12 Oleg Endo <olegendo@gcc.gnu.org>
PR target/51244
......
......@@ -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;
......
2013-10-13 Richard Biener <rguenther@suse.de>
* gcc.c-torture/execute/pr58662.c: New test.
2013-10-12 Oleg Endo <olegendo@gcc.gnu.org>
PR target/51244
......
extern void abort (void);
int a, c, d;
volatile int b;
static int
foo (int p1, short p2)
{
return p1 / p2;
}
int
main ()
{
char e;
d = foo (a == 0, (0, 35536));
e = d % 14;
b = e && c;
if (b != 0)
abort ();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment