re PR rtl-optimization/64756 (wrong code at -O3 on x86_64-linux-gnu (in 32-bit mode))

PR rtl-optimization/64756
	* cse.c (invalidate_dest): New function.
	(cse_insn): Use it.  If dest != SET_DEST (sets[i].rtl) and
	HASH (SET_DEST (sets[i].rtl), mode) computation sets do_not_record,
	invalidate and do not record it.

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

From-SVN: r220377
This commit is contained in:
Jakub Jelinek 2015-02-03 21:41:38 +01:00 committed by Jakub Jelinek
parent 3548abca02
commit 2a1d78d8f6
4 changed files with 69 additions and 8 deletions

View file

@ -1,3 +1,11 @@
2015-02-03 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/64756
* cse.c (invalidate_dest): New function.
(cse_insn): Use it. If dest != SET_DEST (sets[i].rtl) and
HASH (SET_DEST (sets[i].rtl), mode) computation sets do_not_record,
invalidate and do not record it.
2015-02-03 Oleg Endo <olegendo@gcc.gnu.org>
PR target/64660

View file

@ -1984,6 +1984,22 @@ invalidate (rtx x, machine_mode full_mode)
gcc_unreachable ();
}
}
/* Invalidate DEST. Used when DEST is not going to be added
into the hash table for some reason, e.g. do_not_record
flagged on it. */
static void
invalidate_dest (rtx dest)
{
if (REG_P (dest)
|| GET_CODE (dest) == SUBREG
|| MEM_P (dest))
invalidate (dest, VOIDmode);
else if (GET_CODE (dest) == STRICT_LOW_PART
|| GET_CODE (dest) == ZERO_EXTRACT)
invalidate (XEXP (dest, 0), GET_MODE (dest));
}
/* Remove all expressions that refer to register REGNO,
since they are already invalid, and we are about to
@ -5510,18 +5526,20 @@ cse_insn (rtx_insn *insn)
else if (do_not_record)
{
if (REG_P (dest) || GET_CODE (dest) == SUBREG)
invalidate (dest, VOIDmode);
else if (MEM_P (dest))
invalidate (dest, VOIDmode);
else if (GET_CODE (dest) == STRICT_LOW_PART
|| GET_CODE (dest) == ZERO_EXTRACT)
invalidate (XEXP (dest, 0), GET_MODE (dest));
invalidate_dest (dest);
sets[i].rtl = 0;
}
if (sets[i].rtl != 0 && dest != SET_DEST (sets[i].rtl))
sets[i].dest_hash = HASH (SET_DEST (sets[i].rtl), mode);
{
do_not_record = 0;
sets[i].dest_hash = HASH (SET_DEST (sets[i].rtl), mode);
if (do_not_record)
{
invalidate_dest (SET_DEST (sets[i].rtl));
sets[i].rtl = 0;
}
}
#ifdef HAVE_cc0
/* If setting CC0, record what it was set to, or a constant, if it

View file

@ -1,3 +1,8 @@
2015-02-03 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/64756
* gcc.c-torture/execute/pr64756.c: New test.
2015-02-03 Oleg Endo <olegendo@gcc.gnu.org>
PR target/64660

View file

@ -0,0 +1,30 @@
/* PR rtl-optimization/64756 */
int a, *tmp, **c = &tmp;
volatile int d;
static int *volatile *e = &tmp;
unsigned int f;
static void
fn1 (int *p)
{
int g;
for (; f < 1; f++)
for (g = 1; g >= 0; g--)
{
d || d;
*c = p;
if (tmp != &a)
__builtin_abort ();
*e = 0;
}
}
int
main ()
{
fn1 (&a);
return 0;
}