re PR target/36533 (Incorrectly assumed aligned_operand)
authorJakub Jelinek <jakub@redhat.com>
Mon, 23 Jun 2008 13:06:15 +0000 (15:06 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 23 Jun 2008 13:06:15 +0000 (15:06 +0200)
PR target/36533
* emit-rtl.c (set_reg_attrs_from_value): Do nothing if
REG is a hard register.

* gcc.target/i386/pr36533.c: New test.

From-SVN: r137038

gcc/ChangeLog
gcc/emit-rtl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr36533.c [new file with mode: 0644]

index 409f5040a24ebfca323ef4839095b086fa325e91..3478e0fa51085a557c23db4c278a2d0e54d1682c 100644 (file)
@@ -1,5 +1,9 @@
 2008-06-23  Jakub Jelinek  <jakub@redhat.com>
 
+       PR target/36533
+       * emit-rtl.c (set_reg_attrs_from_value): Do nothing if
+       REG is a hard register.
+
        PR tree-optimization/36508
        * tree-ssa-pre.c (compute_antic): Allow num_iterations up to
        499, don't check it at all in release compilers.
index d6929cf154b39105e7f4deb17726056c8d6569bd..fa2b78a4d954cfce2ca6ba7359c7dd75827c44b4 100644 (file)
@@ -963,6 +963,12 @@ set_reg_attrs_from_value (rtx reg, rtx x)
 {
   int offset;
 
+  /* Hard registers can be reused for multiple purposes within the same
+     function, so setting REG_ATTRS, REG_POINTER and REG_POINTER_ALIGN
+     on them is wrong.  */
+  if (HARD_REGISTER_P (reg))
+    return;
+
   offset = byte_lowpart_offset (GET_MODE (reg), GET_MODE (x));
   if (MEM_P (x))
     {
index 1eaff577cc78c7072e9eb2590803029b5c233efc..4e8d0e78020baf11cb6b0391f15742d5aa75d09d 100644 (file)
@@ -1,5 +1,8 @@
 2008-06-23  Jakub Jelinek  <jakub@redhat.com>
 
+       PR target/36533
+       * gcc.target/i386/pr36533.c: New test.
+
        PR tree-optimization/36508
        * gcc.dg/pr36508.c: New test.
 
diff --git a/gcc/testsuite/gcc.target/i386/pr36533.c b/gcc/testsuite/gcc.target/i386/pr36533.c
new file mode 100644 (file)
index 0000000..a271fea
--- /dev/null
@@ -0,0 +1,174 @@
+/* PR target/36533 */
+/* { dg-do run { target { { i?86-*-linux* x86_64-*-linux* } && ilp32 } } } */
+/* { dg-options "-Os" } */
+#include <string.h>
+#include <sys/mman.h>
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+typedef struct S1
+{
+  unsigned long s1;
+  struct S1 *s2;
+  char *s3;
+} S1;
+
+typedef struct
+{
+  unsigned int s4;
+  unsigned int s5;
+  int s6;
+  unsigned int *s7;
+} S2;
+
+typedef struct
+{
+  unsigned int s8;
+  unsigned short s9;
+  unsigned char s10;
+  unsigned char s11;
+  char s12[255];
+} S3;
+
+typedef struct
+{
+  unsigned int s4;
+  unsigned short s13;
+  unsigned short s14;
+} S4;
+
+typedef struct
+{
+  char s15[16];
+  unsigned long s16;
+} S5;
+
+typedef struct
+{
+  char s15[48];
+  S5 *s17;
+} S6;
+
+typedef struct
+{
+  S1 *s18;
+} S7;
+
+__attribute__((regparm (3), noinline)) int
+fn1 (const char *x, void *y, S1 *z)
+{
+  asm volatile ("" : : : "memory");
+  return *x + (y != 0);
+}
+
+__attribute__((regparm (3), noinline)) int
+fn2 (const char *x, int y, S2 *z)
+{
+  asm volatile ("" : : : "memory");
+  return 0;
+}
+
+static inline __attribute__ ((always_inline)) unsigned int
+fn4 (unsigned short x)
+{
+  unsigned len = x;
+  if (len == ((1 << 16) - 1))
+    return 1 << 16;
+  return len;
+}
+
+static inline __attribute__ ((always_inline)) S3 *
+fn3 (S3 *p)
+{
+  return (S3 *) ((char *) p + fn4 (p->s9));
+}
+
+__attribute__((regparm (3), noinline)) int
+fn5 (void)
+{
+  asm volatile ("" : : : "memory");
+  return 0;
+}
+
+static inline __attribute__ ((always_inline)) int
+fn6 (S3 *w, int x, S2 *y, S4 *z)
+{
+  int a = 2;
+  char *b = (char *) w;
+  S2 c = *y;
+
+  while ((char *) w < b + x - 2 * sizeof (S4))
+    {
+      if (w->s10 && w->s8)
+       {
+         fn2 (w->s12, w->s10, &c);
+         z--;
+         z->s4 = c.s4;
+         z->s13 = (unsigned short) ((char *) w - b);
+         z->s14 = w->s9;
+         a++;
+         fn5 ();
+       }
+
+      w = fn3 (w);
+    }
+  return a;
+}
+
+__attribute__((regparm (3), noinline)) unsigned int
+test (void *u, S6 *v, S1 **w, S7 *x, S2 *y, S1 *z)
+{
+  unsigned b = v->s17->s16;
+  unsigned a;
+  S4 *c;
+  unsigned d, e, f, i;
+
+  fn1 (__func__, u, x->s18);
+  c = (S4 *) (z->s3 + b);
+  a = fn6 ((S3 *) (*w)->s3, b, y, c);
+  c -= a;
+  f = 0;
+  e = 2;
+  for (i = a - 1; ; i--)
+    {
+      if (f + (unsigned short) (c[i].s14 / 2) > b / 2)
+       break;
+      f += c[i].s14;
+      e++;
+    }
+  d = a - e;
+  return c[d].s4;
+}
+
+int main (void)
+{
+  char *p = mmap (NULL, 131072, PROT_READ | PROT_WRITE,
+                 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  S1 wb, z, *w;
+  S6 v;
+  S7 x;
+  S2 y;
+  S5 vb;
+  S4 s4;
+  if (p == MAP_FAILED)
+    return 0;
+  if (munmap (p + 65536, 65536) < 0)
+    return 0;
+  memset (&wb, 0, sizeof (wb));
+  memset (&z, 0, sizeof (z));
+  memset (&v, 0, sizeof (v));
+  memset (&x, 0, sizeof (x));
+  memset (&y, 0, sizeof (y));
+  memset (&vb, 0, sizeof (vb));
+  memset (&s4, 0, sizeof (s4));
+  s4.s14 = 254;
+  z.s3 = p + 65536 - 2 * sizeof (S4);
+  w = &wb;
+  v.s17 = &vb;
+  vb.s16 = 2 * sizeof (S4);
+  memcpy (z.s3, &s4, sizeof (s4));
+  memcpy (z.s3 + sizeof (s4), &s4, sizeof (s4));
+  test ((void *) 0, &v, &w, &x, &y, &z);
+  return 0;
+}