mirror of git://gcc.gnu.org/git/gcc.git
189 lines
3.2 KiB
C
189 lines
3.2 KiB
C
/* PR middle-end/47893 */
|
|
/* { dg-do run } */
|
|
/* { dg-options "-O2" } */
|
|
/* { dg-additional-options "-mtune=atom -fno-omit-frame-pointer -fno-strict-aliasing" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */
|
|
/* { dg-skip-if "Too much RAM needed" { "avr-*-*" } } */
|
|
|
|
extern void abort (void);
|
|
|
|
struct S
|
|
{
|
|
unsigned s1:4, s2:2, s3:2, s4:2, s5:2, s6:1, s7:1, s8:1, s9:1, s10:1;
|
|
int s11:16; unsigned s12:4; int s13:16; unsigned s14:2;
|
|
int s15:16; unsigned s16:4; int s17:16; unsigned s18:2;
|
|
};
|
|
|
|
struct T
|
|
{
|
|
unsigned t[3];
|
|
};
|
|
|
|
struct U
|
|
{
|
|
unsigned u1, u2;
|
|
};
|
|
|
|
struct V;
|
|
|
|
struct W
|
|
{
|
|
char w1[24]; struct V *w2; unsigned w3; char w4[28912];
|
|
unsigned int w5; char w6[60];
|
|
};
|
|
|
|
struct X
|
|
{
|
|
unsigned int x[2];
|
|
};
|
|
|
|
struct V
|
|
{
|
|
int v1;
|
|
struct X v2[3];
|
|
char v3[28];
|
|
};
|
|
|
|
struct Y
|
|
{
|
|
void *y1;
|
|
char y2[3076];
|
|
struct T y3[32];
|
|
char y4[1052];
|
|
};
|
|
|
|
volatile struct S v1 = { .s15 = -1, .s16 = 15, .s17 = -1, .s18 = 3 };
|
|
|
|
__attribute__ ((noinline, noclone))
|
|
int
|
|
fn1 (int x)
|
|
{
|
|
int r;
|
|
__asm__ volatile ("" : "=r" (r) : "0" (1), "r" (x) : "memory");
|
|
return r;
|
|
}
|
|
|
|
volatile int cnt;
|
|
|
|
__attribute__ ((noinline, noclone))
|
|
#ifdef __i386__
|
|
__attribute__ ((regparm (2)))
|
|
#endif
|
|
struct S
|
|
fn2 (struct Y *x, const struct X *y)
|
|
{
|
|
if (++cnt > 1)
|
|
abort ();
|
|
__asm__ volatile ("" : : "r" (x), "r" (y) : "memory");
|
|
return v1;
|
|
}
|
|
|
|
__attribute__ ((noinline, noclone))
|
|
void fn3 (void *x, unsigned y, const struct S *z, unsigned w)
|
|
{
|
|
__asm__ volatile ("" : : "r" (x), "r" (y), "r" (z), "r" (w) : "memory");
|
|
}
|
|
|
|
volatile struct U v2;
|
|
|
|
__attribute__ ((noinline, noclone))
|
|
struct U
|
|
fn4 (void *x, unsigned y)
|
|
{
|
|
__asm__ volatile ("" : : "r" (x), "r" (y) : "memory");
|
|
return v2;
|
|
}
|
|
|
|
__attribute__ ((noinline, noclone))
|
|
struct S
|
|
fn5 (void *x)
|
|
{
|
|
__asm__ volatile ("" : : "r" (x) : "memory");
|
|
return v1;
|
|
}
|
|
|
|
volatile struct T v3;
|
|
|
|
__attribute__ ((noinline, noclone))
|
|
struct T fn6 (void *x)
|
|
{
|
|
__asm__ volatile ("" : : "r" (x) : "memory");
|
|
return v3;
|
|
}
|
|
|
|
__attribute__ ((noinline, noclone))
|
|
struct T fn7 (void *x, unsigned y, unsigned z)
|
|
{
|
|
__asm__ volatile ("" : : "r" (x), "r" (y), "r" (z) : "memory");
|
|
return v3;
|
|
}
|
|
|
|
static void
|
|
fn8 (struct Y *x, const struct V *y)
|
|
{
|
|
void *a = x->y1;
|
|
struct S b[4];
|
|
unsigned i, c;
|
|
c = fn1 (y->v1);
|
|
for (i = 0; i < c; i++)
|
|
b[i] = fn2 (x, &y->v2[i]);
|
|
fn3 (a, y->v1, b, c);
|
|
}
|
|
|
|
static inline void
|
|
fn9 (void *x, struct S y __attribute__((unused)))
|
|
{
|
|
fn4 (x, 8);
|
|
}
|
|
|
|
static void
|
|
fn10 (struct Y *x)
|
|
{
|
|
void *a = x->y1;
|
|
struct T b __attribute__((unused)) = fn6 (a);
|
|
fn9 (a, fn5 (a));
|
|
}
|
|
|
|
__attribute__((noinline, noclone))
|
|
int
|
|
fn11 (unsigned int x, void *y, const struct W *z,
|
|
unsigned int w, const char *v, const char *u)
|
|
{
|
|
struct Y a, *t;
|
|
unsigned i;
|
|
t = &a;
|
|
__builtin_memset (t, 0, sizeof *t);
|
|
t->y1 = y;
|
|
if (x == 0)
|
|
{
|
|
if (z->w3 & 1)
|
|
fn10 (t);
|
|
for (i = 0; i < w; i++)
|
|
{
|
|
if (v[i] == 0)
|
|
t->y3[i] = fn7 (y, 0, u[i]);
|
|
else
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
for (i = 0; i < w; i++)
|
|
t->y3[i] = fn7 (y, v[i], u[i]);
|
|
for (i = 0; i < z->w5; i++)
|
|
fn8 (t, &z->w2[i]);
|
|
return 0;
|
|
}
|
|
|
|
volatile int i;
|
|
const char *volatile p = "";
|
|
|
|
int
|
|
main ()
|
|
{
|
|
struct V v = { .v1 = 0 };
|
|
struct W w = { .w5 = 1, .w2 = &v };
|
|
fn11 (i + 1, (void *) p, &w, i, (const char *) p, (const char *) p);
|
|
if (cnt != 1)
|
|
abort ();
|
|
return 0;
|
|
}
|