re PR target/16176 (Miscompilation of unaligned data in MIPS backend (SB1 flavor))
authorRichard Sandiford <rsandifo@redhat.com>
Fri, 25 Jun 2004 18:24:51 +0000 (18:24 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 25 Jun 2004 18:24:51 +0000 (18:24 +0000)
PR target/16176
* config/mips/mips.c (mips_expand_unaligned_load): Use a temporary
register for the destination of the lwl or ldl.

From-SVN: r83668

gcc/ChangeLog
gcc/config/mips/mips.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20040625-1.c [new file with mode: 0644]

index 4720e8350285f0cd82530cb3e1588fe40ed22a95..7ac68fc7300460a9f42993c09d6551e01949e79c 100644 (file)
@@ -1,3 +1,9 @@
+2004-06-25  Richard Sandiford  <rsandifo@redhat.com>
+
+       PR target/16176
+       * config/mips/mips.c (mips_expand_unaligned_load): Use a temporary
+       register for the destination of the lwl or ldl.
+
 2004-06-25  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * tree-cfg.c (verify_expr): Add macro CHECK_OK.
index fe3e66d43e213411484960ee100c84074b87e95b..ba78b522d48184fe7949a25b096a89cdcd347593 100644 (file)
@@ -4434,7 +4434,7 @@ mips_get_unaligned_mem (rtx *op, unsigned int width, int bitpos,
 bool
 mips_expand_unaligned_load (rtx dest, rtx src, unsigned int width, int bitpos)
 {
-  rtx left, right;
+  rtx left, right, temp;
 
   /* If TARGET_64BIT, the destination of a 32-bit load will be a
      paradoxical word_mode subreg.  This is the only case in which
@@ -4453,17 +4453,16 @@ mips_expand_unaligned_load (rtx dest, rtx src, unsigned int width, int bitpos)
   if (!mips_get_unaligned_mem (&src, width, bitpos, &left, &right))
     return false;
 
+  temp = gen_reg_rtx (GET_MODE (dest));
   if (GET_MODE (dest) == DImode)
     {
-      emit_insn (gen_mov_ldl (dest, src, left));
-      emit_insn (gen_mov_ldr (copy_rtx (dest), copy_rtx (src),
-                             right, copy_rtx (dest)));
+      emit_insn (gen_mov_ldl (temp, src, left));
+      emit_insn (gen_mov_ldr (dest, copy_rtx (src), right, temp));
     }
   else
     {
-      emit_insn (gen_mov_lwl (dest, src, left));
-      emit_insn (gen_mov_lwr (copy_rtx (dest), copy_rtx (src),
-                             right, copy_rtx (dest)));
+      emit_insn (gen_mov_lwl (temp, src, left));
+      emit_insn (gen_mov_lwr (dest, copy_rtx (src), right, temp));
     }
   return true;
 }
index 6f39212007f43d28c02d937a8326a7317ab9eb32..49646705a99ad6cd81353511e8ada90ddbc1b944 100644 (file)
@@ -1,3 +1,7 @@
+2004-06-25  Richard Sandiford  <rsandifo@redhat.com>
+
+       * gcc.c-torture/execute/20040625-1.c: New test.
+
 2004-06-25  Tobias Schlueter  <tobias.schlueter@physik.uni-muenchen.de>
 
        * gfortran.fortran-torture/execute/der_init_3.f90: Fix syntax error.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20040625-1.c b/gcc/testsuite/gcc.c-torture/execute/20040625-1.c
new file mode 100644 (file)
index 0000000..c426055
--- /dev/null
@@ -0,0 +1,20 @@
+/* From PR target/16176 */
+struct __attribute__ ((packed)) s { struct s *next; };
+
+struct s * __attribute__ ((noinline))
+maybe_next (struct s *s, int t)
+{
+  if (t)
+    s = s->next;
+  return s;
+}
+
+int main ()
+{
+  struct s s1, s2;
+
+  s1.next = &s2;
+  if (maybe_next (&s1, 1) != &s2)
+    abort ();
+  exit (0);
+}