1// RUN: %clang_cc1 %s -triple x86_64-apple-macosx10.7.2 -emit-llvm -o - | FileCheck %s
2
3struct X { int x[6]; };
4struct Y { char x[13]; struct X y; } __attribute((packed));
5struct Y g;
6void f(struct X);
7struct X foo(void);
8
9// <rdar://problem/10463337>
10struct X test1() {
11  // CHECK: @test1
12  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y, %struct.Y* @g, i32 0, i32 1) to i8*), i64 24, i32 1, i1 false)
13  return g.y;
14}
15struct X test2() {
16  // CHECK: @test2
17  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y, %struct.Y* @g, i32 0, i32 1) to i8*), i64 24, i32 1, i1 false)
18  struct X a = g.y;
19  return a;
20}
21
22void test3(struct X a) {
23  // CHECK: @test3
24  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y, %struct.Y* @g, i32 0, i32 1) to i8*), i8* {{.*}}, i64 24, i32 1, i1 false)
25  g.y = a;
26}
27
28// <rdar://problem/10530444>
29void test4() {
30  // CHECK: @test4
31  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y, %struct.Y* @g, i32 0, i32 1) to i8*), i64 24, i32 1, i1 false)
32  f(g.y);
33}
34
35// PR12395
36int test5() {
37  // CHECK: @test5
38  // CHECK: load i32, i32* getelementptr inbounds (%struct.Y, %struct.Y* @g, i32 0, i32 1, i32 0, i64 0), align 1
39  return g.y.x[0];
40}
41
42// <rdar://problem/11220251>
43void test6() {
44  // CHECK: @test6
45  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y, %struct.Y* @g, i32 0, i32 1) to i8*), i8* %{{.*}}, i64 24, i32 1, i1 false)
46  g.y = foo();
47}
48
49
50struct XBitfield {
51  unsigned b1 : 10;
52  unsigned b2 : 12;
53  unsigned b3 : 10;
54};
55struct YBitfield {
56  char x;
57  struct XBitfield y;
58} __attribute((packed));
59struct YBitfield gbitfield;
60
61unsigned test7() {
62  // CHECK: @test7
63  // CHECK: load i32, i32* getelementptr inbounds (%struct.YBitfield, %struct.YBitfield* @gbitfield, i32 0, i32 1, i32 0), align 1
64  return gbitfield.y.b2;
65}
66
67void test8(unsigned x) {
68  // CHECK: @test8
69  // CHECK: load i32, i32* getelementptr inbounds (%struct.YBitfield, %struct.YBitfield* @gbitfield, i32 0, i32 1, i32 0), align 1
70  // CHECK: store i32 {{.*}}, i32* getelementptr inbounds (%struct.YBitfield, %struct.YBitfield* @gbitfield, i32 0, i32 1, i32 0), align 1
71  gbitfield.y.b2 = x;
72}
73
74struct TBitfield
75{
76  long a;
77  char b;
78  unsigned c:15;
79};
80struct TBitfield tbitfield;
81
82unsigned test9() {
83  // CHECK: @test9
84  // CHECK: load i16, i16* getelementptr inbounds (%struct.TBitfield, %struct.TBitfield* @tbitfield, i32 0, i32 2), align 1
85  return tbitfield.c;
86}
87
88void test10(unsigned x) {
89  // CHECK: @test10
90  // CHECK: load i16, i16* getelementptr inbounds (%struct.TBitfield, %struct.TBitfield* @tbitfield, i32 0, i32 2), align 1
91  // CHECK: store i16 {{.*}}, i16* getelementptr inbounds (%struct.TBitfield, %struct.TBitfield* @tbitfield, i32 0, i32 2), align 1
92  tbitfield.c = x;
93}
94
95