re PR target/34174 (gcc produces erroneous asm for movdi)

PR target/34174
	* config/fr30/fr30.c (fr30_move_double): Sanitize mem->reg case. Copy
	the address before it is clobbered.

testsuite/
	* gcc.dg/torture/pr34174-1.c: New.

From-SVN: r130438
This commit is contained in:
Rask Ingemann Lambertsen 2007-11-26 14:20:19 +01:00 committed by Rask Ingemann Lambertsen
parent f6284d979e
commit 916a659b37
4 changed files with 66 additions and 35 deletions

View file

@ -1,3 +1,9 @@
2007-11-26 Rask Ingemann Lambertsen <rask@sygehus.dk>
PR target/34174
* config/fr30/fr30.c (fr30_move_double): Sanitize mem->reg case. Copy
the address before it is clobbered.
2007-11-26 Nick Clifton <nickc@redhat.com>
* config/mn10300/mn10300.md: (call_internal): Remove mode on

View file

@ -828,47 +828,23 @@ fr30_move_double (rtx * operands)
{
rtx addr = XEXP (src, 0);
int dregno = REGNO (dest);
rtx dest0;
rtx dest1;
rtx dest0 = operand_subword (dest, 0, TRUE, mode);;
rtx dest1 = operand_subword (dest, 1, TRUE, mode);;
rtx new_mem;
/* If the high-address word is used in the address, we
must load it last. Otherwise, load it first. */
int reverse = (refers_to_regno_p (dregno, dregno + 1, addr, 0) != 0);
gcc_assert (GET_CODE (addr) == REG);
dest0 = operand_subword (dest, reverse, TRUE, mode);
dest1 = operand_subword (dest, !reverse, TRUE, mode);
/* Copy the address before clobbering it. See PR 34174. */
emit_insn (gen_rtx_SET (SImode, dest1, addr));
emit_insn (gen_rtx_SET (VOIDmode, dest0,
adjust_address (src, SImode, 0)));
emit_insn (gen_rtx_SET (SImode, dest1,
plus_constant (dest1, UNITS_PER_WORD)));
if (reverse)
{
emit_insn (gen_rtx_SET (VOIDmode, dest1,
adjust_address (src, SImode, 0)));
emit_insn (gen_rtx_SET (SImode, dest0,
gen_rtx_REG (SImode, REGNO (addr))));
emit_insn (gen_rtx_SET (SImode, dest0,
plus_constant (dest0, UNITS_PER_WORD)));
new_mem = gen_rtx_MEM (SImode, dest0);
MEM_COPY_ATTRIBUTES (new_mem, src);
new_mem = gen_rtx_MEM (SImode, dest1);
MEM_COPY_ATTRIBUTES (new_mem, src);
emit_insn (gen_rtx_SET (VOIDmode, dest0, new_mem));
}
else
{
emit_insn (gen_rtx_SET (VOIDmode, dest0,
adjust_address (src, SImode, 0)));
emit_insn (gen_rtx_SET (SImode, dest1,
gen_rtx_REG (SImode, REGNO (addr))));
emit_insn (gen_rtx_SET (SImode, dest1,
plus_constant (dest1, UNITS_PER_WORD)));
new_mem = gen_rtx_MEM (SImode, dest1);
MEM_COPY_ATTRIBUTES (new_mem, src);
emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));
}
emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));
}
else if (src_code == CONST_INT || src_code == CONST_DOUBLE)
{

View file

@ -1,3 +1,8 @@
2007-11-26 Rask Ingemann Lambertsen <rask@sygehus.dk>
PR target/34174
* gcc.dg/torture/pr34174-1.c: New.
2007-11-26 Richard Guenther <rguenther@suse.de>
PR middle-end/34233

View file

@ -0,0 +1,44 @@
/* { dg-do run } */
/* Based on PR target/27386 testcase by Joerg Wunsch. */
extern void abort (void);
extern void exit (int);
#if __INT_MAX__ >= 9223372036854775807LL
typedef unsigned int uint64_t;
#elif __LONG_MAX__ >= 9223372036854775807LL
typedef unsigned long int uint64_t;
#elif __LONG_LONG_MAX__ >= 9223372036854775807LL
typedef unsigned long long int uint64_t;
#else
int
main (void)
{
exit (0);
}
#endif
uint64_t a, b, c;
int
foo (uint64_t x, uint64_t y, uint64_t z, int i)
{
a = x;
b = y;
c = z;
return 2 * i;
}
int
main (void)
{
if (foo (1234512345123ull, 3456734567345ull, 7897897897897ull, 42) != 84)
abort ();
if (a != 1234512345123ull)
abort ();
if (b != 3456734567345ull)
abort ();
if (c != 7897897897897ull)
abort ();
exit (0);
}