1 /* PR middle-end/47893 */
2 /* { dg-do run } */
3 /* { dg-options "-O2" } */
4 /* { dg-options "-O2 -mtune=atom -fno-omit-frame-pointer -fno-strict-aliasing" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
5 /* { dg-skip-if "Too much RAM needed" { "avr-*-*" } { "*" } { "" } } */
6 
7 extern void abort (void);
8 
9 struct S
10 {
11   unsigned s1:4, s2:2, s3:2, s4:2, s5:2, s6:1, s7:1, s8:1, s9:1, s10:1;
12   int s11:16; unsigned s12:4; int s13:16; unsigned s14:2;
13   int s15:16; unsigned s16:4; int s17:16; unsigned s18:2;
14 };
15 
16 struct T
17 {
18   unsigned t[3];
19 };
20 
21 struct U
22 {
23   unsigned u1, u2;
24 };
25 
26 struct V;
27 
28 struct W
29 {
30   char w1[24]; struct V *w2; unsigned w3; char w4[28912];
31   unsigned int w5; char w6[60];
32 };
33 
34 struct X
35 {
36   unsigned int x[2];
37 };
38 
39 struct V
40 {
41   int v1;
42   struct X v2[3];
43   char v3[28];
44 };
45 
46 struct Y
47 {
48   void *y1;
49   char y2[3076];
50   struct T y3[32];
51   char y4[1052];
52 };
53 
54 volatile struct S v1 = { .s15 = -1, .s16 = 15, .s17 = -1, .s18 = 3 };
55 
56 __attribute__ ((noinline, noclone))
57 int
fn1(int x)58 fn1 (int x)
59 {
60   int r;
61   __asm__ volatile ("" : "=r" (r) : "0" (1), "r" (x) : "memory");
62   return r;
63 }
64 
65 volatile int cnt;
66 
67 __attribute__ ((noinline, noclone))
68 #ifdef __i386__
69 __attribute__ ((regparm (2)))
70 #endif
71 struct S
fn2(struct Y * x,const struct X * y)72 fn2 (struct Y *x, const struct X *y)
73 {
74   if (++cnt > 1)
75     abort ();
76   __asm__ volatile ("" : : "r" (x), "r" (y) : "memory");
77   return v1;
78 }
79 
80 __attribute__ ((noinline, noclone))
fn3(void * x,unsigned y,const struct S * z,unsigned w)81 void fn3 (void *x, unsigned y, const struct S *z, unsigned w)
82 {
83   __asm__ volatile ("" : : "r" (x), "r" (y), "r" (z), "r" (w) : "memory");
84 }
85 
86 volatile struct U v2;
87 
88 __attribute__ ((noinline, noclone))
89 struct U
fn4(void * x,unsigned y)90 fn4 (void *x, unsigned y)
91 {
92   __asm__ volatile ("" : : "r" (x), "r" (y) : "memory");
93   return v2;
94 }
95 
96 __attribute__ ((noinline, noclone))
97 struct S
fn5(void * x)98 fn5 (void *x)
99 {
100   __asm__ volatile ("" : : "r" (x) : "memory");
101   return v1;
102 }
103 
104 volatile struct T v3;
105 
106 __attribute__ ((noinline, noclone))
fn6(void * x)107 struct T fn6 (void *x)
108 {
109   __asm__ volatile ("" : : "r" (x) : "memory");
110   return v3;
111 }
112 
113 __attribute__ ((noinline, noclone))
fn7(void * x,unsigned y,unsigned z)114 struct T fn7 (void *x, unsigned y, unsigned z)
115 {
116   __asm__ volatile ("" : : "r" (x), "r" (y), "r" (z) : "memory");
117   return v3;
118 }
119 
120 static void
fn8(struct Y * x,const struct V * y)121 fn8 (struct Y *x, const struct V *y)
122 {
123   void *a = x->y1;
124   struct S b[4];
125   unsigned i, c;
126   c = fn1 (y->v1);
127   for (i = 0; i < c; i++)
128     b[i] = fn2 (x, &y->v2[i]);
129   fn3 (a, y->v1, b, c);
130 }
131 
132 static inline void
fn9(void * x,struct S y)133 fn9 (void *x, struct S y __attribute__((unused)))
134 {
135   fn4 (x, 8);
136 }
137 
138 static void
fn10(struct Y * x)139 fn10 (struct Y *x)
140 {
141   void *a = x->y1;
142   struct T b __attribute__((unused)) = fn6 (a);
143   fn9 (a, fn5 (a));
144 }
145 
146 __attribute__((noinline, noclone))
147 int
fn11(unsigned int x,void * y,const struct W * z,unsigned int w,const char * v,const char * u)148 fn11 (unsigned int x, void *y, const struct W *z,
149       unsigned int w, const char *v, const char *u)
150 {
151   struct Y a, *t;
152   unsigned i;
153   t = &a;
154   __builtin_memset (t, 0, sizeof *t);
155   t->y1 = y;
156   if (x == 0)
157     {
158       if (z->w3 & 1)
159 	fn10 (t);
160       for (i = 0; i < w; i++)
161 	{
162 	  if (v[i] == 0)
163 	    t->y3[i] = fn7 (y, 0, u[i]);
164 	  else
165 	    return 0;
166 	}
167     }
168   else
169     for (i = 0; i < w; i++)
170       t->y3[i] = fn7 (y, v[i], u[i]);
171   for (i = 0; i < z->w5; i++)
172     fn8 (t, &z->w2[i]);
173   return 0;
174 }
175 
176 volatile int i;
177 const char *volatile p = "";
178 
179 int
main()180 main ()
181 {
182   struct V v = { .v1 = 0 };
183   struct W w = { .w5 = 1, .w2 = &v };
184   fn11 (i + 1, (void *) p, &w, i, (const char *) p, (const char *) p);
185   if (cnt != 1)
186     abort ();
187   return 0;
188 }
189