2
0
mirror of git://gcc.gnu.org/git/gcc.git synced 2025-04-13 16:41:19 +08:00

re PR rtl-optimization/44858 (likely integer wrong code bug)

PR rtl-optimization/44858
	* combine.c (try_combine): If recog_for_combine added CLOBBERs to
	newi2pat, make sure they don't affect newpat.

	* gcc.c-torture/execute/pr44858.c: New test.

From-SVN: r163552
This commit is contained in:
Jakub Jelinek 2010-08-25 19:50:59 +02:00 committed by Jakub Jelinek
parent 932c9bffa0
commit ea9f1d6fe5
4 changed files with 87 additions and 1 deletions
gcc
ChangeLogcombine.c
testsuite
ChangeLog
gcc.c-torture/execute

@ -1,5 +1,9 @@
2010-08-25 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/44858
* combine.c (try_combine): If recog_for_combine added CLOBBERs to
newi2pat, make sure they don't affect newpat.
PR rtl-optimization/45400
* combine.c (simplify_shift_const_1) <case SUBREG>: Only use
SUBREG_REG if both modes are of MODE_INT class.

@ -3725,7 +3725,58 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
if (i2_code_number >= 0)
insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
{
/* recog_for_combine might have added CLOBBERs to newi2pat.
Make sure NEWPAT does not depend on the clobbered regs. */
if (GET_CODE (newi2pat) == PARALLEL)
{
for (i = XVECLEN (newi2pat, 0) - 1; i >= 0; i--)
if (GET_CODE (XVECEXP (newi2pat, 0, i)) == CLOBBER)
{
rtx reg = XEXP (XVECEXP (newi2pat, 0, i), 0);
if (reg_overlap_mentioned_p (reg, newpat))
break;
}
if (i >= 0)
{
/* CLOBBERs on newi2pat prevent it going first.
Try the other order of the insns if possible. */
temp = newpat;
newpat = XVECEXP (newi2pat, 0, 0);
newi2pat = temp;
#ifdef HAVE_cc0
if (reg_referenced_p (cc0_rtx, newpat))
{
undo_all ();
return 0;
}
#endif
i2_code_number = recog_for_combine (&newi2pat, i2,
&new_i2_notes);
if (i2_code_number < 0)
{
undo_all ();
return 0;
}
if (GET_CODE (newi2pat) == PARALLEL)
for (i = XVECLEN (newi2pat, 0) - 1; i >= 0; i--)
if (GET_CODE (XVECEXP (newi2pat, 0, i)) == CLOBBER)
{
rtx reg = XEXP (XVECEXP (newi2pat, 0, i), 0);
if (reg_overlap_mentioned_p (reg, newpat))
{
undo_all ();
return 0;
}
}
}
}
insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
}
}
/* If it still isn't recognized, fail and change things back the way they

@ -1,5 +1,8 @@
2010-08-25 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/44858
* gcc.c-torture/execute/pr44858.c: New test.
PR rtl-optimization/45400
* g++.dg/other/i386-8.C: New test.

@ -0,0 +1,28 @@
/* PR rtl-optimization/44858 */
extern void abort (void);
int a = 3;
int b = 1;
__attribute__((noinline)) long long
foo (int x, int y)
{
return x / y;
}
__attribute__((noinline)) int
bar (void)
{
int c = 2;
c &= foo (1, b) > b;
b = (a != 0) | c;
return c;
}
int
main (void)
{
if (bar () != 0 || b != 1)
abort ();
return 0;
}