1 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fms-extensions -emit-llvm < %s | FileCheck %s
2 
3 // -------------
4 // Scalar integer
5 // -------------
6 __unaligned int x;
test1(void)7 void test1(void) {
8   // CHECK: {{%.*}} = load i32, i32* @x, align 1
9   // CHECK: store i32 {{%.*}}, i32* @x, align 1
10   x++;
11 }
12 
test2(void)13 void test2(void) {
14   // CHECK: %y = alloca i32, align 1
15   // CHECK: {{%.*}} = load i32, i32* %y, align 1
16   // CHECK: store i32 {{%.*}}, i32* %y, align 1
17   __unaligned int y;
18   y++;
19 }
20 
test2_1(void)21 void test2_1(void) {
22   // CHECK: %y = alloca i32, align 1
23   // CHECK: store i32 1, i32* %y, align 1
24   __unaligned int y = 1;
25 }
26 
27 // -------------
28 // Global pointer
29 // -------------
30 int *__unaligned p1;
test3(void)31 void test3(void) {
32 
33   // CHECK: {{%.*}} = load i32*, i32** @p1, align 1
34   // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 4
35   // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 4
36   (*p1)++;
37 }
38 
39 int __unaligned *p2;
test4(void)40 void test4(void) {
41   // CHECK: {{%.*}} = load i32*, i32** @p2, align 8
42   // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
43   // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
44   (*p2)++;
45 }
46 
47 int __unaligned *__unaligned p3;
test5(void)48 void test5(void) {
49   // CHECK: {{%.*}} = load i32*, i32** @p3, align 1
50   // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
51   // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
52   (*p3)++;
53 }
54 
55 // -------------
56 // Local pointer
57 // -------------
test6(void)58 void test6(void) {
59   // CHECK: %lp1 = alloca i32*, align 1
60   // CHECK: {{%.*}} = load i32*, i32** %lp1, align 1
61   // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 4
62   // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 4
63   int *__unaligned lp1;
64   (*lp1)++;
65 }
66 
test7(void)67 void test7(void) {
68   // CHECK: %lp2 = alloca i32*, align 8
69   // CHECK: {{%.*}} = load i32*, i32** %lp2, align 8
70   // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
71   // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
72   int __unaligned *lp2;
73   (*lp2)++;
74 }
75 
test8(void)76 void test8(void) {
77   // CHECK: %lp3 = alloca i32*, align 1
78   // CHECK: {{%.*}} = load i32*, i32** %lp3, align 1
79   // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
80   // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
81   int __unaligned *__unaligned lp3;
82   (*lp3)++;
83 }
84 
85 // -------------
86 // Global array
87 // -------------
88 __unaligned int a[10];
test9(void)89 void test9(void) {
90   // CHECK: {{%.*}} = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @a, i64 0, i64 3), align 1
91   // CHECK: store i32 {{%.*}}, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @a, i64 0, i64 3), align 1
92   (a[3])++;
93 }
94 
95 // -------------
96 // Local array
97 // -------------
test10(void)98 void test10(void) {
99   // CHECK: %la = alloca [10 x i32], align 1
100   // CHECK: {{%.*}} = getelementptr inbounds [10 x i32], [10 x i32]* %la, i64 0, i64 3
101   // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
102   // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
103   __unaligned int la[10];
104   (la[3])++;
105 }
106 
107 // --------
108 // Typedefs
109 // --------
110 
111 typedef __unaligned int UnalignedInt;
test13()112 void test13() {
113   // CHECK: %i = alloca i32, align 1
114   // CHECK: {{%.*}} = load i32, i32* %i, align 1
115   // CHECK: store i32 {{%.*}}, i32* %i, align 1
116   UnalignedInt i;
117   i++;
118 }
119 
120 typedef int Aligned;
121 typedef __unaligned Aligned UnalignedInt2;
test14()122 void test14() {
123   // CHECK: %i = alloca i32, align 1
124   // CHECK: {{%.*}} = load i32, i32* %i, align 1
125   // CHECK: store i32 {{%.*}}, i32* %i, align 1
126   UnalignedInt2 i;
127   i++;
128 }
129 
130 typedef UnalignedInt UnalignedInt3;
test15()131 void test15() {
132   // CHECK: %i = alloca i32, align 1
133   // CHECK: {{%.*}} = load i32, i32* %i, align 1
134   // CHECK: store i32 {{%.*}}, i32* %i, align 1
135   UnalignedInt3 i;
136   i++;
137 }
138 
139 // -------------
140 // Decayed types
141 // -------------
test16(__unaligned int c[10])142 void test16(__unaligned int c[10]) {
143   // CHECK: {{%.*}} = alloca i32*, align 8
144   // CHECK: store i32* %c, i32** {{%.*}}, align 8
145   // CHECK: {{%.*}} = load i32*, i32** {{%.*}}, align 8
146   // CHECK: {{%.*}} = getelementptr inbounds i32, i32* {{%.*}}, i64 3
147   // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
148   // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
149   c[3]++;
150 }
151 
152 // -----------
153 // __alignof__
154 // -----------
test17(void)155 int test17(void) {
156   // CHECK: ret i32 1
157   return __alignof__(__unaligned int);
158 }
159 
test18(void)160 int test18(void) {
161   // CHECK: ret i32 1
162   __unaligned int a;
163   return __alignof__(a);
164 }
165 
test19(void)166 int test19(void) {
167   // CHECK: ret i32 1
168   __unaligned int a[10];
169   return __alignof__(a);
170 }
171 
172 // -----------
173 // structs
174 // -----------
175 typedef
176 struct S1 {
177     char c;
178     int x;
179 } S1;
180 
181 __unaligned S1 s1;
test20(void)182 void test20(void) {
183     // CHECK: {{%.*}} = load i32, i32* getelementptr inbounds (%struct.S1, %struct.S1* @s1, i32 0, i32 1), align 1
184     // CHECK: store i32 {{%.*}}, i32* getelementptr inbounds (%struct.S1, %struct.S1* @s1, i32 0, i32 1), align 1
185     s1.x++;
186 }
187 
test21(void)188 void test21(void) {
189   // CHECK: {{%.*}} = alloca %struct.S1, align 1
190   // CHECK: {{%.*}} = getelementptr inbounds %struct.S1, %struct.S1* {{%.*}}, i32 0, i32 1
191   // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
192   // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
193   __unaligned S1 s1_2;
194   s1_2.x++;
195 }
196 
197 typedef
198 struct __attribute__((packed)) S2 {
199     char c;
200     int x;
201 } S2;
202 
203 __unaligned S2 s2;
test22(void)204 void test22(void) {
205     // CHECK: {{%.*}} = load i32, i32* getelementptr inbounds (%struct.S2, %struct.S2* @s2, i32 0, i32 1), align 1
206     // CHECK: store i32 {{%.*}}, i32* getelementptr inbounds (%struct.S2, %struct.S2* @s2, i32 0, i32 1), align 1
207     s2.x++;
208 }
209 
test23(void)210 void test23(void) {
211   // CHECK: {{%.*}} = alloca %struct.S2, align 1
212   // CHECK: {{%.*}} = getelementptr inbounds %struct.S2, %struct.S2* {{%.*}}, i32 0, i32 1
213   // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1
214   // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1
215   __unaligned S2 s2_2;
216   s2_2.x++;
217 }
218