aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@redhat.com>2004-06-25 18:24:51 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2004-06-25 18:24:51 +0000
commitf1526aaae77c8082ef42691d03254926f5104b64 (patch)
tree4761c6694179d05866b445599129f1c8450da5fc
parent2fbe90f22457f0a82c1d10ff5a918259c41859b1 (diff)
downloadgcc-f1526aaae77c8082ef42691d03254926f5104b64.zip
gcc-f1526aaae77c8082ef42691d03254926f5104b64.tar.gz
gcc-f1526aaae77c8082ef42691d03254926f5104b64.tar.bz2
re PR target/16176 (Miscompilation of unaligned data in MIPS backend (SB1 flavor))
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/mips/mips.c13
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20040625-1.c20
4 files changed, 36 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4720e83..7ac68fc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index fe3e66d..ba78b52 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6f39212..4964670 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..c426055
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20040625-1.c
@@ -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);
+}