]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
emit-rtl.c (adjust_address_1): Reduce offset to a signed value that fits within Pmode.
authorJoseph Myers <joseph@codesourcery.com>
Wed, 4 Mar 2009 01:57:29 +0000 (01:57 +0000)
committerJoseph Myers <jsm28@gcc.gnu.org>
Wed, 4 Mar 2009 01:57:29 +0000 (01:57 +0000)
* emit-rtl.c (adjust_address_1): Reduce offset to a signed value
that fits within Pmode.

testsuite:
* gcc.c-torture/compile/20090303-1.c,
gcc.c-torture/compile/20090303-2.c: New tests.

From-SVN: r144595

gcc/ChangeLog
gcc/emit-rtl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20090303-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/20090303-2.c [new file with mode: 0644]

index f145fbe74d157835e38ce44413e9befba36a2e92..661f0d7e7dae09638137a206587c0f4ee5da36ef 100644 (file)
@@ -1,3 +1,8 @@
+2009-03-03  Joseph Myers  <joseph@codesourcery.com>
+
+       * emit-rtl.c (adjust_address_1): Reduce offset to a signed value
+       that fits within Pmode.
+
 2009-03-03  Steve Ellcey  <sje@cup.hp.com>
 
        PR middle-end/10109
index 679e95ea8a24eba266edb6d1c561ed98ebf9ad17..ca033824c0d0de806519620a691d6016d9e12bbc 100644 (file)
@@ -2008,6 +2008,7 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
   rtx memoffset = MEM_OFFSET (memref);
   rtx size = 0;
   unsigned int memalign = MEM_ALIGN (memref);
+  int pbits;
 
   /* If there are no changes, just return the original memory reference.  */
   if (mode == GET_MODE (memref) && !offset
@@ -2019,6 +2020,16 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
      (plus (plus reg reg) const_int) -- so do this always.  */
   addr = copy_rtx (addr);
 
+  /* Convert a possibly large offset to a signed value within the
+     range of the target address space.  */
+  pbits = GET_MODE_BITSIZE (Pmode);
+  if (HOST_BITS_PER_WIDE_INT > pbits)
+    {
+      int shift = HOST_BITS_PER_WIDE_INT - pbits;
+      offset = (((HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) offset << shift))
+               >> shift);
+    }
+
   if (adjust)
     {
       /* If MEMREF is a LO_SUM and the offset is within the alignment of the
index a4bfe792d4f6e20e403fc6a283156e610d423448..2851a70a3387dc46a687f5088e1e79f671c7b594 100644 (file)
@@ -1,3 +1,8 @@
+2009-03-03  Joseph Myers  <joseph@codesourcery.com>
+
+       * gcc.c-torture/compile/20090303-1.c,
+       gcc.c-torture/compile/20090303-2.c: New tests.
+
 2009-03-03  Jakub Jelinek  <jakub@redhat.com>
 
        PR fortran/39354
diff --git a/gcc/testsuite/gcc.c-torture/compile/20090303-1.c b/gcc/testsuite/gcc.c-torture/compile/20090303-1.c
new file mode 100644 (file)
index 0000000..18a3d91
--- /dev/null
@@ -0,0 +1,20 @@
+/* The array offset became 0x1ffffffffffffffe via a conversion from
+   signed to unsigned HOST_WIDE_INT, causing an ICE compiling for
+   Thumb.  */
+
+int r (unsigned short *);
+void s (unsigned short *, unsigned short *);
+
+int
+f (int x)
+{
+  unsigned short a[1], c[1];
+
+  if (r (a))
+    return x;
+
+  if (c[-1])
+    s (a, c);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20090303-2.c b/gcc/testsuite/gcc.c-torture/compile/20090303-2.c
new file mode 100644 (file)
index 0000000..69cee36
--- /dev/null
@@ -0,0 +1,20 @@
+/* The array offset became 0x1ffffffffffffffe via a conversion from
+   signed to unsigned HOST_WIDE_INT, causing an ICE compiling for
+   Thumb.  */
+
+int r (unsigned short *);
+void s (unsigned short *, unsigned short *);
+
+int
+f (int x)
+{
+  unsigned short a[1], c[1];
+
+  if (r (a))
+    return x;
+
+  if (c[0x7fffffff])
+    s (a, c);
+
+  return 0;
+}