re PR target/34174 (gcc produces erroneous asm for movdi)
authorRask Ingemann Lambertsen <rask@sygehus.dk>
Mon, 26 Nov 2007 13:20:19 +0000 (14:20 +0100)
committerRask Ingemann Lambertsen <rask@gcc.gnu.org>
Mon, 26 Nov 2007 13:20:19 +0000 (13:20 +0000)
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

gcc/ChangeLog
gcc/config/fr30/fr30.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr34174-1.c [new file with mode: 0644]

index 474e34c21421d5df00012bc9a473672545723d85..6f273449f5102894d93ce0938a349ad720e8d0c2 100644 (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
index 343dd02ba09d48c66408d43a11f5ec687054d95e..8c523567bb9a4c0651349f56f1f5ff725b08ee4b 100644 (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);
-
-         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)
        {
index d90427f5074653b3c95ff1adb18e8a0886ba2b4a..d45e36f015927082df141634455ef9fbd16f9882 100644 (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
diff --git a/gcc/testsuite/gcc.dg/torture/pr34174-1.c b/gcc/testsuite/gcc.dg/torture/pr34174-1.c
new file mode 100644 (file)
index 0000000..0f1ed06
--- /dev/null
@@ -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);
+}