diff options
author | rask <rask@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-11-26 13:20:19 +0000 |
---|---|---|
committer | rask <rask@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-11-26 13:20:19 +0000 |
commit | 39d50e809cdefce7021b37deb5e107777274efae (patch) | |
tree | 6f58da5b15fd0a15696502ec57a557360598571b /gcc | |
parent | 5c6565d058f8bdc273b4a9031ceada2c489137cb (diff) | |
download | gcc-39d50e809cdefce7021b37deb5e107777274efae.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130438 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/fr30/fr30.c | 48 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr34174-1.c | 44 |
4 files changed, 67 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 474e34c2142..6f273449f51 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/fr30/fr30.c b/gcc/config/fr30/fr30.c index 343dd02ba09..8c523567bb9 100644 --- a/gcc/config/fr30/fr30.c +++ b/gcc/config/fr30/fr30.c @@ -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); - - 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); - - 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); + /* 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))); + + 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) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d90427f5074..d45e36f0159 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.dg/torture/pr34174-1.c b/gcc/testsuite/gcc.dg/torture/pr34174-1.c new file mode 100644 index 00000000000..0f1ed067fb4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr34174-1.c @@ -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); +} |