PR inline-asm/84742
[official-gcc.git] / gcc / testsuite / gcc.target / i386 / pr37275.c
blobcf748879e86d2dedfbef0c1ac71bcf960e160f6b
1 /* PR middle-end/37275 */
2 /* { dg-do compile { target ia32 } } */
3 /* { dg-options "-g -dA -O2 -march=i686 -fstack-protector" } */
4 /* { dg-require-visibility "" } */
6 typedef __SIZE_TYPE__ size_t;
7 extern void *memcpy (void *, const void *, size_t);
8 extern void *malloc (size_t);
10 typedef int A;
12 struct B
14 int x;
17 struct C
19 struct F *c1;
20 void *c2;
23 enum D
25 D0,
29 struct E
31 struct E *e1;
32 struct E *e2;
33 struct B e3;
34 void (*fn) (void *);
35 void *fn_data;
36 enum D e4;
37 _Bool e5;
38 _Bool e6;
41 struct F
43 unsigned f1;
44 A f2;
45 int f3;
48 struct G
50 void (*fn) (void *data);
51 void *data;
52 struct C g1;
53 struct E *t;
56 extern void fn1 (A * m);
57 static inline void
58 fn2 (A *x)
60 if (!__sync_bool_compare_and_swap (x, 0, 1))
61 fn1 (x);
64 extern __thread struct G thr __attribute__ ((visibility ("hidden")));
65 static inline struct G *
66 fn3 (void)
68 return &thr;
71 extern struct B *fn4 (void);
72 extern struct B a;
74 static inline struct B *
75 fn5 (_Bool x)
77 struct E *t = fn3 ()->t;
78 if (t)
79 return &t->e3;
80 else if (x)
81 return fn4 ();
82 else
83 return &a;
86 void
87 fn6 (struct E *t, struct E *e1_t,
88 struct B *prev_e3)
90 t->e1 = e1_t;
91 t->e3 = *prev_e3;
92 t->e4 = D0;
93 t->e5 = 0;
94 t->e6 = 0;
95 t->e2 = ((void *) 0);
98 void
99 test (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *), long x, long y, _Bool z)
101 struct G *thr = fn3 ();
102 struct F *c1 = thr->g1.c1;
103 if (!z || c1 == 0 || (unsigned) c1->f3 > 64 * c1->f1)
105 struct E t;
107 fn6 (&t, thr->t, fn5 (0));
108 if (thr->t)
109 t.e6 = thr->t->e6;
110 thr->t = &t;
111 if (__builtin_expect (cpyfn != ((void *) 0), 0))
113 char buf[x + y - 1];
114 char *arg = (char *) (((unsigned long) buf + y - 1)
115 & ~(unsigned long) (y - 1));
116 cpyfn (arg, data);
117 fn (arg);
120 else
122 struct E *t;
123 struct E *e1 = thr->t;
124 char *arg;
126 t = malloc (sizeof (*t) + x + y - 1);
127 arg = (char *) (((unsigned long) (t + 1) + y - 1)
128 & ~(unsigned long) (y - 1));
129 fn6 (t, e1, fn5 (0));
130 thr->t = t;
131 if (cpyfn)
132 cpyfn (arg, data);
133 else
134 memcpy (arg, data, x);
135 thr->t = e1;
136 fn2 (&c1->f2);