* emit-rtl.c (adjust_address_1): Reduce offset to a signed value
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 4 Mar 2009 01:57:29 +0000 (01:57 +0000)
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 4 Mar 2009 01:57:29 +0000 (01:57 +0000)
that fits within Pmode.

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

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@144595 138bc75d-0d04-0410-961f-82ee72b054a4

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 f145fbe..661f0d7 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 679e95e..ca03382 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 a4bfe79..2851a70 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;
+}