]>
Commit | Line | Data |
---|---|---|
4b84d9b8 JJ |
1 | /* Only test on some 64-bit targets which do have bswap{si,di}2 patterns and |
2 | are either big or little endian (not pdp endian). */ | |
78668dd0 | 3 | /* { dg-do run { target { lp64 && { i?86-*-* x86_64-*-* powerpc*-*-* aarch64*-*-* } } } } */ |
4b84d9b8 | 4 | /* { dg-require-effective-target store_merge } */ |
2b8453c4 | 5 | /* { dg-options "-O2 -fno-tree-vectorize -fdump-tree-store-merging" } */ |
4b84d9b8 JJ |
6 | |
7 | __attribute__((noipa)) void | |
8 | f1 (unsigned char *p, unsigned long long q) | |
9 | { | |
10 | p[0] = q; | |
11 | p[1] = q >> 8; | |
12 | p[2] = q >> 16; | |
13 | p[3] = q >> 24; | |
14 | p[4] = q >> 32; | |
15 | p[5] = q >> 40; | |
16 | p[6] = q >> 48; | |
17 | p[7] = q >> 56; | |
18 | } | |
19 | ||
20 | __attribute__((noipa)) void | |
21 | f2 (unsigned char *p, unsigned long long q) | |
22 | { | |
23 | p[0] = q >> 56; | |
24 | p[1] = q >> 48; | |
25 | p[2] = q >> 40; | |
26 | p[3] = q >> 32; | |
27 | p[4] = q >> 24; | |
28 | p[5] = q >> 16; | |
29 | p[6] = q >> 8; | |
30 | p[7] = q; | |
31 | } | |
32 | ||
33 | __attribute__((noipa)) void | |
34 | f3 (unsigned char *__restrict p, unsigned char *__restrict q) | |
35 | { | |
36 | unsigned char q3 = q[3]; | |
37 | unsigned char q2 = q[2]; | |
38 | unsigned char q1 = q[1]; | |
39 | unsigned char q0 = q[0]; | |
40 | p[0] = q3; | |
41 | p[1] = q2; | |
42 | p[2] = q1; | |
43 | p[3] = q0; | |
44 | } | |
45 | ||
46 | __attribute__((noipa)) void | |
47 | f4 (unsigned char *__restrict p, unsigned char *__restrict q) | |
48 | { | |
49 | p[0] = q[3]; | |
50 | p[1] = q[2]; | |
51 | p[2] = q[1]; | |
52 | p[3] = q[0]; | |
53 | } | |
54 | ||
55 | struct S { unsigned char a, b; unsigned short c; }; | |
56 | ||
57 | __attribute__((noipa)) void | |
58 | f5 (struct S *__restrict p, struct S *__restrict q) | |
59 | { | |
60 | #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ | |
61 | unsigned char pa = q->c >> 8; | |
62 | unsigned char pb = q->c; | |
63 | unsigned short pc = (q->a << 8) | q->b; | |
64 | #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | |
65 | unsigned char pa = q->c; | |
66 | unsigned char pb = q->c >> 8; | |
67 | unsigned short pc = q->a | (q->b << 8); | |
68 | #endif | |
69 | p->a = pa; | |
70 | p->b = pb; | |
71 | p->c = pc; | |
72 | } | |
73 | ||
74 | __attribute__((noipa)) void | |
75 | f6 (struct S *__restrict p, struct S *__restrict q) | |
76 | { | |
77 | #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ | |
78 | p->a = q->c >> 8; | |
79 | p->b = q->c; | |
80 | p->c = (q->a << 8) | q->b; | |
81 | #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | |
82 | p->a = q->c; | |
83 | p->b = q->c >> 8; | |
84 | p->c = q->a | (q->b << 8); | |
85 | #endif | |
86 | } | |
87 | ||
88 | struct T { unsigned long long a : 8, b : 8, c : 8, d : 8, e : 8, f : 8, g : 8, h : 8; }; | |
89 | ||
90 | __attribute__((noipa)) void | |
91 | f7 (struct T *__restrict p, struct T *__restrict q) | |
92 | { | |
93 | p->a = q->h; | |
94 | p->b = q->g; | |
95 | p->c = q->f; | |
96 | p->d = q->e; | |
97 | p->e = q->d; | |
98 | p->f = q->c; | |
99 | p->g = q->b; | |
100 | p->h = q->a; | |
101 | } | |
102 | ||
103 | struct S b = { 0x11, 0x12, | |
104 | #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ | |
105 | 0x1413 | |
106 | #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | |
107 | 0x1314 | |
108 | #endif | |
109 | }; | |
110 | struct T e = { 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28 }; | |
111 | ||
112 | int | |
113 | main () | |
114 | { | |
115 | unsigned char a[8]; | |
116 | int i; | |
78668dd0 | 117 | struct S c, d; |
4b84d9b8 JJ |
118 | f1 (a, 0x0102030405060708ULL); |
119 | for (i = 0; i < 8; ++i) | |
120 | if (a[i] != 8 - i) | |
121 | __builtin_abort (); | |
122 | f2 (a, 0x0102030405060708ULL); | |
123 | for (i = 0; i < 8; ++i) | |
124 | if (a[i] != 1 + i) | |
125 | __builtin_abort (); | |
126 | f3 (a, a + 4); | |
127 | for (i = 0; i < 8; ++i) | |
128 | if (a[i] != (i < 4 ? 8 - i : 1 + i)) | |
129 | __builtin_abort (); | |
130 | f2 (a, 0x090a0b0c0d0e0f10ULL); | |
131 | f4 (a + 4, a); | |
132 | for (i = 0; i < 8; ++i) | |
133 | if (a[i] != (i < 4 ? 9 + i : 16 - i)) | |
134 | __builtin_abort (); | |
135 | f5 (&c, &b); | |
136 | if (c.a != 0x14 || c.b != 0x13 | |
137 | #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ | |
138 | || c.c != 0x1112 | |
139 | #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | |
140 | || c.c != 0x1211 | |
141 | #endif | |
142 | ) | |
143 | __builtin_abort (); | |
144 | f6 (&d, &c); | |
145 | if (d.a != 0x11 || d.b != 0x12 || d.c != b.c) | |
146 | __builtin_abort (); | |
147 | struct T f; | |
148 | f7 (&f, &e); | |
149 | if (f.a != 0x28 || f.b != 0x27 || f.c != 0x26 || f.d != 0x25 | |
150 | || f.e != 0x24 || f.f != 0x23 || f.g != 0x22 || f.h != 0x21) | |
151 | __builtin_abort (); | |
152 | return 0; | |
153 | } | |
154 | ||
155 | /* { dg-final { scan-tree-dump-times "Merging successful" 7 "store-merging" } } */ | |
156 | /* { dg-final { scan-tree-dump-times "__builtin_bswap64" 2 "store-merging" } } */ | |
157 | /* { dg-final { scan-tree-dump-times "__builtin_bswap32" 4 "store-merging" } } */ |