1/* PR middle-end/37275 */ 2/* { dg-do compile { target ilp32 } } */ 3/* { dg-options "-g -dA -O2 -march=i686 -fstack-protector" } */ 4/* { dg-require-visibility "" } */ 5 6typedef __SIZE_TYPE__ size_t; 7extern void *memcpy (void *, const void *, size_t); 8extern void *malloc (size_t); 9 10typedef int A; 11 12struct B 13{ 14 int x; 15}; 16 17struct C 18{ 19 struct F *c1; 20 void *c2; 21}; 22 23enum D 24{ 25 D0, 26 D1 27}; 28 29struct E 30{ 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; 39}; 40 41struct F 42{ 43 unsigned f1; 44 A f2; 45 int f3; 46}; 47 48struct G 49{ 50 void (*fn) (void *data); 51 void *data; 52 struct C g1; 53 struct E *t; 54}; 55 56extern void fn1 (A * m); 57static inline void 58fn2 (A *x) 59{ 60 if (!__sync_bool_compare_and_swap (x, 0, 1)) 61 fn1 (x); 62} 63 64extern __thread struct G thr __attribute__ ((visibility ("hidden"))); 65static inline struct G * 66fn3 (void) 67{ 68 return &thr; 69} 70 71extern struct B *fn4 (void); 72extern struct B a; 73 74static inline struct B * 75fn5 (_Bool x) 76{ 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; 84} 85 86void 87fn6 (struct E *t, struct E *e1_t, 88 struct B *prev_e3) 89{ 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); 96} 97 98void 99test (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *), long x, long y, _Bool z) 100{ 101 struct G *thr = fn3 (); 102 struct F *c1 = thr->g1.c1; 103 if (!z || c1 == 0 || (unsigned) c1->f3 > 64 * c1->f1) 104 { 105 struct E t; 106 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)) 112 { 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); 118 } 119 } 120 else 121 { 122 struct E *t; 123 struct E *e1 = thr->t; 124 char *arg; 125 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); 137 } 138} 139