| /* PR target/36533 */ |
| /* { dg-do run { target { mmap && 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; |
| } |