1*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-unk-unk -emit-llvm -Os -o %t %s
2*67e74705SXin Li // RUN: FileCheck < %t %s
3*67e74705SXin Li
4*67e74705SXin Li struct s0 {
5*67e74705SXin Li unsigned int x[2] __attribute__((packed));
6*67e74705SXin Li };
7*67e74705SXin Li
8*67e74705SXin Li struct s1 {
9*67e74705SXin Li unsigned int x[2] __attribute__((packed));
10*67e74705SXin Li unsigned int y;
11*67e74705SXin Li unsigned int z __attribute__((packed));
12*67e74705SXin Li };
13*67e74705SXin Li
14*67e74705SXin Li struct s2 {
15*67e74705SXin Li unsigned int x[2] __attribute__((packed));
16*67e74705SXin Li unsigned int y __attribute__((packed));
17*67e74705SXin Li unsigned int z __attribute__((packed));
18*67e74705SXin Li };
19*67e74705SXin Li
20*67e74705SXin Li struct __attribute__((packed)) s3 {
21*67e74705SXin Li unsigned int x[2];
22*67e74705SXin Li unsigned int y;
23*67e74705SXin Li unsigned int z;
24*67e74705SXin Li };
25*67e74705SXin Li
26*67e74705SXin Li // CHECK: @align0 = local_unnamed_addr global i32 1
27*67e74705SXin Li int align0 = __alignof(struct s0);
28*67e74705SXin Li // CHECK: @align1 = local_unnamed_addr global i32 4
29*67e74705SXin Li int align1 = __alignof(struct s1);
30*67e74705SXin Li // CHECK: @align2 = local_unnamed_addr global i32 1
31*67e74705SXin Li int align2 = __alignof(struct s2);
32*67e74705SXin Li // CHECK: @align3 = local_unnamed_addr global i32 1
33*67e74705SXin Li int align3 = __alignof(struct s3);
34*67e74705SXin Li
35*67e74705SXin Li // CHECK: @align0_x = local_unnamed_addr global i32 1
36*67e74705SXin Li int align0_x = __alignof(((struct s0*) 0)->x);
37*67e74705SXin Li //
38*67e74705SXin Li // CHECK: @align1_x = local_unnamed_addr global i32 1
39*67e74705SXin Li int align1_x = __alignof(((struct s1*) 0)->x);
40*67e74705SXin Li // CHECK: @align2_x = local_unnamed_addr global i32 1
41*67e74705SXin Li int align2_x = __alignof(((struct s2*) 0)->x);
42*67e74705SXin Li // CHECK: @align3_x = local_unnamed_addr global i32 1
43*67e74705SXin Li int align3_x = __alignof(((struct s3*) 0)->x);
44*67e74705SXin Li
45*67e74705SXin Li // CHECK: @align0_x0 = local_unnamed_addr global i32 4
46*67e74705SXin Li int align0_x0 = __alignof(((struct s0*) 0)->x[0]);
47*67e74705SXin Li // CHECK: @align1_x0 = local_unnamed_addr global i32 4
48*67e74705SXin Li int align1_x0 = __alignof(((struct s1*) 0)->x[0]);
49*67e74705SXin Li // CHECK: @align2_x0 = local_unnamed_addr global i32 4
50*67e74705SXin Li int align2_x0 = __alignof(((struct s2*) 0)->x[0]);
51*67e74705SXin Li // CHECK: @align3_x0 = local_unnamed_addr global i32 4
52*67e74705SXin Li int align3_x0 = __alignof(((struct s3*) 0)->x[0]);
53*67e74705SXin Li
54*67e74705SXin Li // CHECK-LABEL: define i32 @f0_a
55*67e74705SXin Li // CHECK: load i32, i32* %{{.*}}, align 1
56*67e74705SXin Li // CHECK: }
57*67e74705SXin Li // CHECK-LABEL: define i32 @f0_b
58*67e74705SXin Li // CHECK: load i32, i32* %{{.*}}, align 4
59*67e74705SXin Li // CHECK: }
f0_a(struct s0 * a)60*67e74705SXin Li int f0_a(struct s0 *a) {
61*67e74705SXin Li return a->x[1];
62*67e74705SXin Li }
f0_b(struct s0 * a)63*67e74705SXin Li int f0_b(struct s0 *a) {
64*67e74705SXin Li return *(a->x + 1);
65*67e74705SXin Li }
66*67e74705SXin Li
67*67e74705SXin Li // Note that 'y' still causes struct s1 to be four-byte aligned.
68*67e74705SXin Li
69*67e74705SXin Li // Note that we are incompatible with GCC on this example.
70*67e74705SXin Li //
71*67e74705SXin Li // CHECK-LABEL: define i32 @f1_a
72*67e74705SXin Li // CHECK: load i32, i32* %{{.*}}, align 4
73*67e74705SXin Li // CHECK: }
74*67e74705SXin Li // CHECK-LABEL: define i32 @f1_b
75*67e74705SXin Li // CHECK: load i32, i32* %{{.*}}, align 4
76*67e74705SXin Li // CHECK: }
77*67e74705SXin Li
78*67e74705SXin Li // Note that we are incompatible with GCC on this example.
79*67e74705SXin Li //
80*67e74705SXin Li // CHECK-LABEL: define i32 @f1_c
81*67e74705SXin Li // CHECK: load i32, i32* %{{.*}}, align 4
82*67e74705SXin Li // CHECK: }
83*67e74705SXin Li // CHECK-LABEL: define i32 @f1_d
84*67e74705SXin Li // CHECK: load i32, i32* %{{.*}}, align 4
85*67e74705SXin Li // CHECK: }
f1_a(struct s1 * a)86*67e74705SXin Li int f1_a(struct s1 *a) {
87*67e74705SXin Li return a->x[1];
88*67e74705SXin Li }
f1_b(struct s1 * a)89*67e74705SXin Li int f1_b(struct s1 *a) {
90*67e74705SXin Li return *(a->x + 1);
91*67e74705SXin Li }
f1_c(struct s1 * a)92*67e74705SXin Li int f1_c(struct s1 *a) {
93*67e74705SXin Li return a->y;
94*67e74705SXin Li }
f1_d(struct s1 * a)95*67e74705SXin Li int f1_d(struct s1 *a) {
96*67e74705SXin Li return a->z;
97*67e74705SXin Li }
98*67e74705SXin Li
99*67e74705SXin Li // CHECK-LABEL: define i32 @f2_a
100*67e74705SXin Li // CHECK: load i32, i32* %{{.*}}, align 1
101*67e74705SXin Li // CHECK: }
102*67e74705SXin Li // CHECK-LABEL: define i32 @f2_b
103*67e74705SXin Li // CHECK: load i32, i32* %{{.*}}, align 4
104*67e74705SXin Li // CHECK: }
105*67e74705SXin Li // CHECK-LABEL: define i32 @f2_c
106*67e74705SXin Li // CHECK: load i32, i32* %{{.*}}, align 1
107*67e74705SXin Li // CHECK: }
108*67e74705SXin Li // CHECK-LABEL: define i32 @f2_d
109*67e74705SXin Li // CHECK: load i32, i32* %{{.*}}, align 1
110*67e74705SXin Li // CHECK: }
f2_a(struct s2 * a)111*67e74705SXin Li int f2_a(struct s2 *a) {
112*67e74705SXin Li return a->x[1];
113*67e74705SXin Li }
f2_b(struct s2 * a)114*67e74705SXin Li int f2_b(struct s2 *a) {
115*67e74705SXin Li return *(a->x + 1);
116*67e74705SXin Li }
f2_c(struct s2 * a)117*67e74705SXin Li int f2_c(struct s2 *a) {
118*67e74705SXin Li return a->y;
119*67e74705SXin Li }
f2_d(struct s2 * a)120*67e74705SXin Li int f2_d(struct s2 *a) {
121*67e74705SXin Li return a->z;
122*67e74705SXin Li }
123*67e74705SXin Li
124*67e74705SXin Li // CHECK-LABEL: define i32 @f3_a
125*67e74705SXin Li // CHECK: load i32, i32* %{{.*}}, align 1
126*67e74705SXin Li // CHECK: }
127*67e74705SXin Li // CHECK-LABEL: define i32 @f3_b
128*67e74705SXin Li // CHECK: load i32, i32* %{{.*}}, align 4
129*67e74705SXin Li // CHECK: }
130*67e74705SXin Li // CHECK-LABEL: define i32 @f3_c
131*67e74705SXin Li // CHECK: load i32, i32* %{{.*}}, align 1
132*67e74705SXin Li // CHECK: }
133*67e74705SXin Li // CHECK-LABEL: define i32 @f3_d
134*67e74705SXin Li // CHECK: load i32, i32* %{{.*}}, align 1
135*67e74705SXin Li // CHECK: }
f3_a(struct s3 * a)136*67e74705SXin Li int f3_a(struct s3 *a) {
137*67e74705SXin Li return a->x[1];
138*67e74705SXin Li }
f3_b(struct s3 * a)139*67e74705SXin Li int f3_b(struct s3 *a) {
140*67e74705SXin Li return *(a->x + 1);
141*67e74705SXin Li }
f3_c(struct s3 * a)142*67e74705SXin Li int f3_c(struct s3 *a) {
143*67e74705SXin Li return a->y;
144*67e74705SXin Li }
f3_d(struct s3 * a)145*67e74705SXin Li int f3_d(struct s3 *a) {
146*67e74705SXin Li return a->z;
147*67e74705SXin Li }
148*67e74705SXin Li
149*67e74705SXin Li // Verify we don't claim things are overaligned.
150*67e74705SXin Li //
151*67e74705SXin Li // CHECK-LABEL: define double @f4
152*67e74705SXin Li // CHECK: load double, double* {{.*}}, align 8
153*67e74705SXin Li // CHECK: }
154*67e74705SXin Li extern double g4[5] __attribute__((aligned(16)));
f4()155*67e74705SXin Li double f4() {
156*67e74705SXin Li return g4[1];
157*67e74705SXin Li }
158