1 /* { dg-do run } */
2 /* { dg-require-effective-target store_merge } */
3 /* { dg-options "-O2 -fdump-tree-store-merging" } */
4 
5 struct S { unsigned char a, b; unsigned short c; unsigned char d, e, f, g; unsigned long long h; };
6 
7 __attribute__((noipa)) void
f1(struct S * p)8 f1 (struct S *p)
9 {
10   p->a = 1;
11   p->b = 2;
12   p->c = 3;
13   p->d = 4;
14   p->e = 5;
15   p->f = 6;
16   p->g = 7;
17 }
18 
19 __attribute__((noipa)) void
f2(struct S * __restrict p,struct S * __restrict q)20 f2 (struct S *__restrict p, struct S *__restrict q)
21 {
22   p->a = q->a;
23   p->b = q->b;
24   p->c = q->c;
25   p->d = q->d;
26   p->e = q->e;
27   p->f = q->f;
28   p->g = q->g;
29 }
30 
31 __attribute__((noipa)) void
f3(struct S * p,struct S * q)32 f3 (struct S *p, struct S *q)
33 {
34   unsigned char pa = q->a;
35   unsigned char pb = q->b;
36   unsigned short pc = q->c;
37   unsigned char pd = q->d;
38   unsigned char pe = q->e;
39   unsigned char pf = q->f;
40   unsigned char pg = q->g;
41   p->a = pa;
42   p->b = pb;
43   p->c = pc;
44   p->d = pd;
45   p->e = pe;
46   p->f = pf;
47   p->g = pg;
48 }
49 
50 __attribute__((noipa)) void
f4(struct S * p,struct S * q)51 f4 (struct S *p, struct S *q)
52 {
53   unsigned char pa = p->a | q->a;
54   unsigned char pb = p->b | q->b;
55   unsigned short pc = p->c | q->c;
56   unsigned char pd = p->d | q->d;
57   unsigned char pe = p->e | q->e;
58   unsigned char pf = p->f | q->f;
59   unsigned char pg = p->g | q->g;
60   p->a = pa;
61   p->b = pb;
62   p->c = pc;
63   p->d = pd;
64   p->e = pe;
65   p->f = pf;
66   p->g = pg;
67 }
68 
69 __attribute__((noipa)) void
f5(struct S * p,struct S * q)70 f5 (struct S *p, struct S *q)
71 {
72   unsigned char pa = p->a & q->a;
73   unsigned char pb = p->b & q->b;
74   unsigned short pc = p->c & q->c;
75   unsigned char pd = p->d & q->d;
76   unsigned char pe = p->e & q->e;
77   unsigned char pf = p->f & q->f;
78   unsigned char pg = p->g & q->g;
79   p->a = pa;
80   p->b = pb;
81   p->c = pc;
82   p->d = pd;
83   p->e = pe;
84   p->f = pf;
85   p->g = pg;
86 }
87 
88 __attribute__((noipa)) void
f6(struct S * p,struct S * q)89 f6 (struct S *p, struct S *q)
90 {
91   unsigned char pa = p->a ^ q->a;
92   unsigned char pb = p->b ^ q->b;
93   unsigned short pc = p->c ^ q->c;
94   unsigned char pd = p->d ^ q->d;
95   unsigned char pe = p->e ^ q->e;
96   unsigned char pf = p->f ^ q->f;
97   unsigned char pg = p->g ^ q->g;
98   p->a = pa;
99   p->b = pb;
100   p->c = pc;
101   p->d = pd;
102   p->e = pe;
103   p->f = pf;
104   p->g = pg;
105 }
106 
107 __attribute__((noipa)) void
f7(struct S * __restrict p,struct S * __restrict q)108 f7 (struct S *__restrict p, struct S *__restrict q)
109 {
110   p->a |= q->a;
111   p->b |= q->b;
112   p->c |= q->c;
113   p->d |= q->d;
114   p->e |= q->e;
115   p->f |= q->f;
116   p->g |= q->g;
117 }
118 
119 __attribute__((noipa)) void
f8(struct S * __restrict p,struct S * __restrict q)120 f8 (struct S *__restrict p, struct S *__restrict q)
121 {
122   p->a &= q->a;
123   p->b &= q->b;
124   p->c &= q->c;
125   p->d &= q->d;
126   p->e &= q->e;
127   p->f &= q->f;
128   p->g &= q->g;
129 }
130 
131 __attribute__((noipa)) void
f9(struct S * __restrict p,struct S * __restrict q)132 f9 (struct S *__restrict p, struct S *__restrict q)
133 {
134   p->a ^= q->a;
135   p->b ^= q->b;
136   p->c ^= q->c;
137   p->d ^= q->d;
138   p->e ^= q->e;
139   p->f ^= q->f;
140   p->g ^= q->g;
141 }
142 
143 __attribute__((noipa)) void
f10(struct S * __restrict p,struct S * __restrict q)144 f10 (struct S *__restrict p, struct S *__restrict q)
145 {
146   p->a = ~q->a;
147   p->b = ~q->b;
148   p->c = ~q->c;
149   p->d = ~q->d;
150   p->e = ~q->e;
151   p->f = ~q->f;
152   p->g = ~q->g;
153 }
154 
155 __attribute__((noipa)) void
f11(struct S * __restrict p,struct S * __restrict q)156 f11 (struct S *__restrict p, struct S *__restrict q)
157 {
158   p->a = p->a | (unsigned char) ~q->a;
159   p->b = p->b | (unsigned char) ~q->b;
160   p->c = p->c | (unsigned short) ~q->c;
161   p->d = p->d | (unsigned char) ~q->d;
162   p->e = p->e | (unsigned char) ~q->e;
163   p->f = p->f | (unsigned char) ~q->f;
164   p->g = p->g | (unsigned char) ~q->g;
165 }
166 
167 __attribute__((noipa)) void
f12(struct S * __restrict p,struct S * __restrict q)168 f12 (struct S *__restrict p, struct S *__restrict q)
169 {
170   p->a = p->a & (unsigned char) ~q->a;
171   p->b = p->b & (unsigned char) ~q->b;
172   p->c = p->c & (unsigned short) ~q->c;
173   p->d = p->d & (unsigned char) ~q->d;
174   p->e = p->e & (unsigned char) ~q->e;
175   p->f = p->f & (unsigned char) ~q->f;
176   p->g = p->g & (unsigned char) ~q->g;
177 }
178 
179 __attribute__((noipa)) void
f13(struct S * __restrict p,struct S * __restrict q)180 f13 (struct S *__restrict p, struct S *__restrict q)
181 {
182   p->a = p->a ^ (unsigned char) ~q->a;
183   p->b = p->b ^ (unsigned char) ~q->b;
184   p->c = p->c ^ (unsigned short) ~q->c;
185   p->d = p->d ^ (unsigned char) ~q->d;
186   p->e = p->e ^ (unsigned char) ~q->e;
187   p->f = p->f ^ (unsigned char) ~q->f;
188   p->g = p->g ^ (unsigned char) ~q->g;
189 }
190 
191 struct S s = { 20, 21, 22, 23, 24, 25, 26, 27 };
192 struct S t = { 0x71, 0x72, 0x7f04, 0x78, 0x31, 0x32, 0x34, 0xf1f2f3f4f5f6f7f8ULL };
193 struct S u = { 28, 29, 30, 31, 32, 33, 34, 35 };
194 struct S v = { 36, 37, 38, 39, 40, 41, 42, 43 };
195 
196 int
main()197 main ()
198 {
199   asm volatile ("" : : : "memory");
200   f1 (&s);
201   asm volatile ("" : : : "memory");
202   if (s.a != 1 || s.b != 2 || s.c != 3 || s.d != 4
203       || s.e != 5 || s.f != 6 || s.g != 7 || s.h != 27)
204     __builtin_abort ();
205   f2 (&s, &u);
206   asm volatile ("" : : : "memory");
207   if (s.a != 28 || s.b != 29 || s.c != 30 || s.d != 31
208       || s.e != 32 || s.f != 33 || s.g != 34 || s.h != 27)
209     __builtin_abort ();
210   f3 (&s, &v);
211   asm volatile ("" : : : "memory");
212   if (s.a != 36 || s.b != 37 || s.c != 38 || s.d != 39
213       || s.e != 40 || s.f != 41 || s.g != 42 || s.h != 27)
214     __builtin_abort ();
215   f4 (&s, &t);
216   asm volatile ("" : : : "memory");
217   if (s.a != (36 | 0x71) || s.b != (37 | 0x72)
218       || s.c != (38 | 0x7f04) || s.d != (39 | 0x78)
219       || s.e != (40 | 0x31) || s.f != (41 | 0x32)
220       || s.g != (42 | 0x34) || s.h != 27)
221     __builtin_abort ();
222   f3 (&s, &u);
223   f5 (&s, &t);
224   asm volatile ("" : : : "memory");
225   if (s.a != (28 & 0x71) || s.b != (29 & 0x72)
226       || s.c != (30 & 0x7f04) || s.d != (31 & 0x78)
227       || s.e != (32 & 0x31) || s.f != (33 & 0x32)
228       || s.g != (34 & 0x34) || s.h != 27)
229     __builtin_abort ();
230   f2 (&s, &v);
231   f6 (&s, &t);
232   asm volatile ("" : : : "memory");
233   if (s.a != (36 ^ 0x71) || s.b != (37 ^ 0x72)
234       || s.c != (38 ^ 0x7f04) || s.d != (39 ^ 0x78)
235       || s.e != (40 ^ 0x31) || s.f != (41 ^ 0x32)
236       || s.g != (42 ^ 0x34) || s.h != 27)
237     __builtin_abort ();
238   f3 (&s, &v);
239   f7 (&s, &t);
240   asm volatile ("" : : : "memory");
241   if (s.a != (36 | 0x71) || s.b != (37 | 0x72)
242       || s.c != (38 | 0x7f04) || s.d != (39 | 0x78)
243       || s.e != (40 | 0x31) || s.f != (41 | 0x32)
244       || s.g != (42 | 0x34) || s.h != 27)
245     __builtin_abort ();
246   f3 (&s, &u);
247   f8 (&s, &t);
248   asm volatile ("" : : : "memory");
249   if (s.a != (28 & 0x71) || s.b != (29 & 0x72)
250       || s.c != (30 & 0x7f04) || s.d != (31 & 0x78)
251       || s.e != (32 & 0x31) || s.f != (33 & 0x32)
252       || s.g != (34 & 0x34) || s.h != 27)
253     __builtin_abort ();
254   f2 (&s, &v);
255   f9 (&s, &t);
256   asm volatile ("" : : : "memory");
257   if (s.a != (36 ^ 0x71) || s.b != (37 ^ 0x72)
258       || s.c != (38 ^ 0x7f04) || s.d != (39 ^ 0x78)
259       || s.e != (40 ^ 0x31) || s.f != (41 ^ 0x32)
260       || s.g != (42 ^ 0x34) || s.h != 27)
261     __builtin_abort ();
262   f10 (&s, &u);
263   asm volatile ("" : : : "memory");
264   if (s.a != (unsigned char) ~28 || s.b != (unsigned char) ~29
265       || s.c != (unsigned short) ~30 || s.d != (unsigned char) ~31
266       || s.e != (unsigned char) ~32 || s.f != (unsigned char) ~33
267       || s.g != (unsigned char) ~34 || s.h != 27)
268     __builtin_abort ();
269   f3 (&s, &v);
270   f11 (&s, &t);
271   asm volatile ("" : : : "memory");
272   if (s.a != (36 | (unsigned char) ~0x71) || s.b != (37 | (unsigned char) ~0x72)
273       || s.c != (38 | (unsigned short) ~0x7f04) || s.d != (39 | (unsigned char) ~0x78)
274       || s.e != (40 | (unsigned char) ~0x31) || s.f != (41 | (unsigned char) ~0x32)
275       || s.g != (42 | (unsigned char) ~0x34) || s.h != 27)
276     __builtin_abort ();
277   f3 (&s, &u);
278   f12 (&s, &t);
279   asm volatile ("" : : : "memory");
280   if (s.a != (28 & (unsigned char) ~0x71) || s.b != (29 & (unsigned char) ~0x72)
281       || s.c != (30 & (unsigned short) ~0x7f04) || s.d != (31 & (unsigned char) ~0x78)
282       || s.e != (32 & (unsigned char) ~0x31) || s.f != (33 & (unsigned char) ~0x32)
283       || s.g != (34 & (unsigned char) ~0x34) || s.h != 27)
284     __builtin_abort ();
285   f2 (&s, &v);
286   f13 (&s, &t);
287   asm volatile ("" : : : "memory");
288   if (s.a != (36 ^ (unsigned char) ~0x71) || s.b != (37 ^ (unsigned char) ~0x72)
289       || s.c != (38 ^ (unsigned short) ~0x7f04) || s.d != (39 ^ (unsigned char) ~0x78)
290       || s.e != (40 ^ (unsigned char) ~0x31) || s.f != (41 ^ (unsigned char) ~0x32)
291       || s.g != (42 ^ (unsigned char) ~0x34) || s.h != 27)
292     __builtin_abort ();
293   return 0;
294 }
295 
296 /* { dg-final { scan-tree-dump-times "Merging successful" 13 "store-merging" } } */
297