From: Jakub Jelinek Date: Mon, 23 Jun 2008 13:06:15 +0000 (+0200) Subject: re PR target/36533 (Incorrectly assumed aligned_operand) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=923ba36f8ce142fb94eeabd7a78b6aa8266d51b2;p=gcc.git re PR target/36533 (Incorrectly assumed aligned_operand) 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 409f5040a24..3478e0fa510 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2008-06-23 Jakub Jelinek + 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. diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index d6929cf154b..fa2b78a4d95 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -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)) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1eaff577cc7..4e8d0e78020 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2008-06-23 Jakub Jelinek + 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 index 00000000000..a271fea1cac --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr36533.c @@ -0,0 +1,174 @@ +/* PR target/36533 */ +/* { dg-do run { target { { i?86-*-linux* x86_64-*-linux* } && ilp32 } } } */ +/* { dg-options "-Os" } */ +#include +#include +#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; +}