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