blob: 79033d7f7bf5bc5e54b4915df49ede7d8f1a3d20 [file] [log] [blame]
Daniel Dunbar26772612010-04-15 03:47:33 +00001// RUN: %clang_cc1 -emit-llvm -triple x86_64 -O3 -o - %s | \
2// RUN: FileCheck -check-prefix=CHECK-OPT %s
3
4/****/
5
6// PR6176
7
8struct __attribute((packed)) s0 {
9 int f0 : 24;
10};
11
12struct s0 g0 = { 0xdeadbeef };
13
14int f0_load(struct s0 *a0) {
15 int size_check[sizeof(struct s0) == 3 ? 1 : -1];
16 return a0->f0;
17}
18int f0_store(struct s0 *a0) {
19 return (a0->f0 = 1);
20}
21int f0_reload(struct s0 *a0) {
22 return (a0->f0 += 1);
23}
24
25// CHECK-OPT: define i64 @test_0()
26// CHECK-OPT: ret i64 1
27// CHECK-OPT: }
28unsigned long long test_0() {
29 struct s0 g0 = { 0xdeadbeef };
30 unsigned long long res = 0;
31 res ^= g0.f0;
32 res ^= f0_load(&g0) ^ f0_store(&g0) ^ f0_reload(&g0);
33 res ^= g0.f0;
34 return res;
35}
36
37/****/
38
39// PR5591
40
41#pragma pack(push)
42#pragma pack(1)
43struct __attribute((packed)) s1 {
44 signed f0 : 10;
45 signed f1 : 10;
46};
47#pragma pack(pop)
48
49struct s1 g1 = { 0xdeadbeef, 0xdeadbeef };
50
51int f1_load(struct s1 *a0) {
52 int size_check[sizeof(struct s1) == 3 ? 1 : -1];
53 return a0->f1;
54}
55int f1_store(struct s1 *a0) {
56 return (a0->f1 = 1234);
57}
58int f1_reload(struct s1 *a0) {
59 return (a0->f1 += 1234);
60}
61
62// CHECK-OPT: define i64 @test_1()
63// CHECK-OPT: ret i64 210
64// CHECK-OPT: }
65unsigned long long test_1() {
66 struct s1 g1 = { 0xdeadbeef, 0xdeadbeef };
67 unsigned long long res = 0;
68 res ^= g1.f0 ^ g1.f1;
69 res ^= f1_load(&g1) ^ f1_store(&g1) ^ f1_reload(&g1);
70 res ^= g1.f0 ^ g1.f1;
71 return res;
72}
73
74/****/
75
76// PR5567
77
78union u2 {
79 unsigned long long f0 : 3;
80};
81
82union u2 g2 = { 0xdeadbeef };
83
84int f2_load(union u2 *a0) {
85 return a0->f0;
86}
87int f2_store(union u2 *a0) {
88 return (a0->f0 = 1234);
89}
90int f2_reload(union u2 *a0) {
91 return (a0->f0 += 1234);
92}
93
94// CHECK-OPT: define i64 @test_2()
95// CHECK-OPT: ret i64 2
96// CHECK-OPT: }
97unsigned long long test_2() {
98 union u2 g2 = { 0xdeadbeef };
99 unsigned long long res = 0;
100 res ^= g2.f0;
101 res ^= f2_load(&g2) ^ f2_store(&g2) ^ f2_reload(&g2);
102 res ^= g2.f0;
103 return res;
104}
105
106/***/
107
108// PR5039
109
110struct s3 {
111 long long f0 : 32;
112 long long f1 : 32;
113};
114
115struct s3 g3 = { 0xdeadbeef, 0xdeadbeef };
116
117int f3_load(struct s3 *a0) {
118 a0->f0 = 1;
119 return a0->f0;
120}
121int f3_store(struct s3 *a0) {
122 a0->f0 = 1;
123 return (a0->f0 = 1234);
124}
125int f3_reload(struct s3 *a0) {
126 a0->f0 = 1;
127 return (a0->f0 += 1234);
128}
129
130// CHECK-OPT: define i64 @test_3()
131// CHECK-OPT: ret i64 -559039940
132// CHECK-OPT: }
133unsigned long long test_3() {
134 struct s3 g3 = { 0xdeadbeef, 0xdeadbeef };
135 unsigned long long res = 0;
136 res ^= g3.f0 ^ g3.f1;
137 res ^= f3_load(&g3) ^ f3_store(&g3) ^ f3_reload(&g3);
138 res ^= g3.f0 ^ g3.f1;
139 return res;
140}
141
142/***/
143
144// This is a case where the bitfield access will straddle an alignment boundary
145// of its underlying type.
146
147struct s4 {
148 unsigned f0 : 16;
149 unsigned f1 : 28 __attribute__ ((packed));
150};
151
152struct s4 g4 = { 0xdeadbeef, 0xdeadbeef };
153
154int f4_load(struct s4 *a0) {
155 return a0->f0 ^ a0->f1;
156}
157int f4_store(struct s4 *a0) {
158 return (a0->f0 = 1234) ^ (a0->f1 = 5678);
159}
160int f4_reload(struct s4 *a0) {
161 return (a0->f0 += 1234) ^ (a0->f1 += 5678);
162}
163
164// CHECK-OPT: define i64 @test_4()
165// CHECK-OPT: ret i64 4860
166// CHECK-OPT: }
167unsigned long long test_4() {
168 struct s4 g4 = { 0xdeadbeef, 0xdeadbeef };
169 unsigned long long res = 0;
170 res ^= g4.f0 ^ g4.f1;
171 res ^= f4_load(&g4) ^ f4_store(&g4) ^ f4_reload(&g4);
172 res ^= g4.f0 ^ g4.f1;
173 return res;
174}
175
176/***/
177
178
179struct s5 {
180 unsigned f0 : 2;
181 _Bool f1 : 1;
182 _Bool f2 : 1;
183};
184
185struct s5 g5 = { 0xdeadbeef, 0xdeadbeef };
186
187int f5_load(struct s5 *a0) {
188 return a0->f0 ^ a0->f1;
189}
190int f5_store(struct s5 *a0) {
191 return (a0->f0 = 0xF) ^ (a0->f1 = 0xF) ^ (a0->f2 = 0xF);
192}
193int f5_reload(struct s5 *a0) {
194 return (a0->f0 += 0xF) ^ (a0->f1 += 0xF) ^ (a0->f2 += 0xF);
195}
196
197// CHECK-OPT: define i64 @test_5()
198// CHECK-OPT: ret i64 2
199// CHECK-OPT: }
200unsigned long long test_5() {
201 struct s5 g5 = { 0xdeadbeef, 0xdeadbeef, 0xdeadbeef };
202 unsigned long long res = 0;
203 res ^= g5.f0 ^ g5.f1 ^ g5.f2;
204 res ^= f5_load(&g5) ^ f5_store(&g5) ^ f5_reload(&g5);
205 res ^= g5.f0 ^ g5.f1 ^ g5.f2;
206 return res;
207}