aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGen/packed-arrays.c
blob: 0c8bb6c7bd4f94697533d4cd89d9f35ac2b4bf4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// RUN: %clang_cc1 -triple x86_64-unk-unk -emit-llvm -Os -o %t %s
// RUN: FileCheck < %t %s

struct s0 {
  unsigned int x[2] __attribute__((packed));
};

struct s1 {
  unsigned int x[2] __attribute__((packed));
  unsigned int y;
  unsigned int z __attribute__((packed));
};

struct s2 {
  unsigned int x[2] __attribute__((packed));
  unsigned int y __attribute__((packed));
  unsigned int z __attribute__((packed));
};

struct __attribute__((packed)) s3 {
  unsigned int x[2];
  unsigned int y;
  unsigned int z;
};

// CHECK: @align0 = global i32 1
int align0 = __alignof(struct s0);
// CHECK: @align1 = global i32 4
int align1 = __alignof(struct s1);
// CHECK: @align2 = global i32 1
int align2 = __alignof(struct s2);
// CHECK: @align3 = global i32 1
int align3 = __alignof(struct s3);

// CHECK: @align0_x = global i32 1
int align0_x = __alignof(((struct s0*) 0)->x);
//
// CHECK: @align1_x = global i32 1
int align1_x = __alignof(((struct s1*) 0)->x);
// CHECK: @align2_x = global i32 1
int align2_x = __alignof(((struct s2*) 0)->x);
// CHECK: @align3_x = global i32 1
int align3_x = __alignof(((struct s3*) 0)->x);

// CHECK: @align0_x0 = global i32 4
int align0_x0 = __alignof(((struct s0*) 0)->x[0]);
// CHECK: @align1_x0 = global i32 4
int align1_x0 = __alignof(((struct s1*) 0)->x[0]);
// CHECK: @align2_x0 = global i32 4
int align2_x0 = __alignof(((struct s2*) 0)->x[0]);
// CHECK: @align3_x0 = global i32 4
int align3_x0 = __alignof(((struct s3*) 0)->x[0]);

// CHECK: define i32 @f0_a
// CHECK:   load i32* %{{.*}}, align 1
// CHECK: }
// CHECK: define i32 @f0_b
// CHECK:   load i32* %{{.*}}, align 4
// CHECK: }
int f0_a(struct s0 *a) {
  return a->x[1];
}
int f0_b(struct s0 *a) {
  return *(a->x + 1);
}

// Note that we are incompatible with GCC on this example.
// 
// CHECK: define i32 @f1_a
// CHECK:   load i32* %{{.*}}, align 1
// CHECK: }
// CHECK: define i32 @f1_b
// CHECK:   load i32* %{{.*}}, align 4
// CHECK: }

// Note that we are incompatible with GCC on this example.
//
// CHECK: define i32 @f1_c
// CHECK:   load i32* %{{.*}}, align 4
// CHECK: }
// CHECK: define i32 @f1_d
// CHECK:   load i32* %{{.*}}, align 1
// CHECK: }
int f1_a(struct s1 *a) {
  return a->x[1];
}
int f1_b(struct s1 *a) {
  return *(a->x + 1);
}
int f1_c(struct s1 *a) {
  return a->y;
}
int f1_d(struct s1 *a) {
  return a->z;
}

// CHECK: define i32 @f2_a
// CHECK:   load i32* %{{.*}}, align 1
// CHECK: }
// CHECK: define i32 @f2_b
// CHECK:   load i32* %{{.*}}, align 4
// CHECK: }
// CHECK: define i32 @f2_c
// CHECK:   load i32* %{{.*}}, align 1
// CHECK: }
// CHECK: define i32 @f2_d
// CHECK:   load i32* %{{.*}}, align 1
// CHECK: }
int f2_a(struct s2 *a) {
  return a->x[1];
}
int f2_b(struct s2 *a) {
  return *(a->x + 1);
}
int f2_c(struct s2 *a) {
  return a->y;
}
int f2_d(struct s2 *a) {
  return a->z;
}

// CHECK: define i32 @f3_a
// CHECK:   load i32* %{{.*}}, align 1
// CHECK: }
// CHECK: define i32 @f3_b
// CHECK:   load i32* %{{.*}}, align 4
// CHECK: }
// CHECK: define i32 @f3_c
// CHECK:   load i32* %{{.*}}, align 1
// CHECK: }
// CHECK: define i32 @f3_d
// CHECK:   load i32* %{{.*}}, align 1
// CHECK: }
int f3_a(struct s3 *a) {
  return a->x[1];
}
int f3_b(struct s3 *a) {
  return *(a->x + 1);
}
int f3_c(struct s3 *a) {
  return a->y;
}
int f3_d(struct s3 *a) {
  return a->z;
}

// Verify we don't claim things are overaligned.
//
// CHECK: define double @f4
// CHECK:   load double* {{.*}}, align 8
// CHECK: }
extern double g4[5] __attribute__((aligned(16)));
double f4() {
  return g4[1];
}