blob: ecf4d173df2cf7ca2e2b60d627f212a36989a83c [file] [log] [blame]
Alexey Bataeve686c1d2014-06-30 09:05:08 +00001// RUN: %clang_cc1 -fblocks -emit-llvm %s -o %t
Ben Langmuir3b4c30b2013-05-09 19:17:11 +00002// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK1
3// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK2
4
5struct A {
Alexey Bataeve686c1d2014-06-30 09:05:08 +00006 int a;
Ben Langmuir3b4c30b2013-05-09 19:17:11 +00007 float b;
8 char c;
9};
10
Alexey Bataeve686c1d2014-06-30 09:05:08 +000011void test_nest_captured_stmt(int param, int size, int param_arr[size]) {
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000012 int w;
Alexey Bataevaca7fcf2014-06-30 02:55:54 +000013 int arr[param][size];
Alexey Bataevbe5af7b2014-06-30 08:17:11 +000014 // CHECK1: %struct.anon{{.*}} = type { i32*, i32*, i{{.+}}*, i32**, i32* }
15 // CHECK1: %struct.anon{{.*}} = type { i32*, i32*, i32**, i32*, i{{.+}}*, i32**, i32* }
16 // CHECK1: [[T:%struct.anon.*]] = type { i32*, i32*, %struct.A*, i32**, i32*, i{{.+}}*, i32**, i32* }
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000017 #pragma clang __debug captured
18 {
19 int x;
20 int *y = &w;
21 #pragma clang __debug captured
22 {
23 struct A z;
24 #pragma clang __debug captured
25 {
26 w = x = z.a = 1;
27 *y = param;
28 z.b = 0.1f;
29 z.c = 'c';
Alexey Bataevaca7fcf2014-06-30 02:55:54 +000030 param_arr[size - 1] = 2;
31 arr[10][z.a] = 12;
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000032
33 // CHECK1: define internal void @__captured_stmt{{.*}}([[T]]
34 //
35 // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 2
36 // CHECK1-NEXT: load %struct.A**
37 // CHECK1-NEXT: getelementptr inbounds %struct.A*
Alexey Bataevbe5af7b2014-06-30 08:17:11 +000038 // CHECK1-NEXT: store i{{.+}} 1
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000039 //
40 // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 1
41 // CHECK1-NEXT: load i32**
42 // CHECK1-NEXT: store i32 1
43 //
44 // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 0
45 // CHECK1-NEXT: load i32**
46 // CHECK1-NEXT: store i32 1
47 //
48 // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 4
49 // CHECK1-NEXT: load i32**
50 // CHECK1-NEXT: load i32*
51 // CHECK1-NEXT: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 3
52 // CHECK1-NEXT: load i32***
53 // CHECK1-NEXT: load i32**
54 // CHECK1-NEXT: store i32
55 //
56 // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 2
57 // CHECK1-NEXT: load %struct.A**
58 // CHECK1-NEXT: getelementptr inbounds %struct.A*
59 // CHECK1-NEXT: store float
60 //
61 // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 2
62 // CHECK1-NEXT: load %struct.A**
63 // CHECK1-NEXT: getelementptr inbounds %struct.A*
64 // CHECK1-NEXT: store i8 99
Alexey Bataevaca7fcf2014-06-30 02:55:54 +000065 //
Alexey Bataevbe5af7b2014-06-30 08:17:11 +000066 // CHECK1: [[SIZE_ADDR_REF:%.*]] = getelementptr inbounds [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 5
67 // CHECK1-DAG: [[SIZE_ADDR:%.*]] = load i{{.+}}** [[SIZE_ADDR_REF]]
68 // CHECK1-DAG: [[SIZE:%.*]] = load i{{.+}}* [[SIZE_ADDR]]
69 // CHECK1-DAG: [[PARAM_ARR_IDX:%.*]] = sub nsw i{{.+}} [[SIZE]], 1
70 // CHECK1-DAG: [[PARAM_ARR_ADDR_REF:%.*]] = getelementptr inbounds [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 6
71 // CHECK1-DAG: [[PARAM_ARR_ADDR:%.*]] = load i{{.+}}*** [[PARAM_ARR_ADDR_REF]]
72 // CHECK1-DAG: [[PARAM_ARR:%.*]] = load i{{.+}}** [[PARAM_ARR_ADDR]]
Alexey Bataeve686c1d2014-06-30 09:05:08 +000073 // CHECK1-DAG: [[PARAM_ARR_SIZE_MINUS_1_ADDR:%.*]] = getelementptr inbounds i{{.+}}* [[PARAM_ARR]], i{{.*}}
Alexey Bataevbe5af7b2014-06-30 08:17:11 +000074 // CHECK1: store i{{.+}} 2, i{{.+}}* [[PARAM_ARR_SIZE_MINUS_1_ADDR]]
Alexey Bataevaca7fcf2014-06-30 02:55:54 +000075 //
Alexey Bataevbe5af7b2014-06-30 08:17:11 +000076 // CHECK1: [[Z_ADDR_REF:%.*]] = getelementptr inbounds [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 2
Alexey Bataev83222d62014-06-30 05:02:50 +000077 // CHECK1-DAG: [[Z_ADDR:%.*]] = load %struct.A** [[Z_ADDR_REF]]
Alexey Bataevbe5af7b2014-06-30 08:17:11 +000078 // CHECK1-DAG: [[Z_A_ADDR:%.*]] = getelementptr inbounds %struct.A* [[Z_ADDR]], i{{.+}} 0, i{{.+}} 0
79 // CHECK1-DAG: [[ARR_IDX_2:%.*]] = load i{{.+}}* [[Z_A_ADDR]]
80 // CHECK1-DAG: [[ARR_ADDR_REF:%.*]] = getelementptr inbounds [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 7
81 // CHECK1-DAG: [[ARR_ADDR:%.*]] = load i{{.+}}** [[ARR_ADDR_REF]]
Alexey Bataev83222d62014-06-30 05:02:50 +000082 // CHECK1-DAG: [[ARR_IDX_1:%.*]] = mul {{.*}} 10
Alexey Bataevbe5af7b2014-06-30 08:17:11 +000083 // CHECK1-DAG: [[ARR_10_ADDR:%.*]] = getelementptr inbounds i{{.+}}* [[ARR_ADDR]], i{{.*}} [[ARR_IDX_1]]
84 // CHECK1-DAG: [[ARR_10_Z_A_ADDR:%.*]] = getelementptr inbounds i{{.+}}* [[ARR_10_ADDR]], i{{.*}} [[ARR_IDX_2]]
85 // CHECK1: store i{{.+}} 12, i{{.+}}* [[ARR_10_Z_A_ADDR]]
Ben Langmuir3b4c30b2013-05-09 19:17:11 +000086 }
87 }
88 }
89}
90
91void test_nest_block() {
92 __block int x;
93 int y;
94 ^{
95 int z;
96 x = z;
97 #pragma clang __debug captured
98 {
99 z = y; // OK
100 }
101 }();
102
103 // CHECK2: define internal void @{{.*}}test_nest_block_block_invoke
104 //
105 // CHECK2: [[Z:%[0-9a-z_]*]] = alloca i32
106 // CHECK2: alloca %struct.anon{{.*}}
107 //
108 // CHECK2: store i32
109 // CHECK2: store i32* [[Z]]
110 //
111 // CHECK2: getelementptr inbounds %struct.anon
112 // CHECK2-NEXT: getelementptr inbounds
113 // CHECK2-NEXT: store i32*
114 //
115 // CHECK2: call void @__captured_stmt
116
117 int a;
118 #pragma clang __debug captured
119 {
120 __block int b;
121 int c;
122 __block int d;
123 ^{
124 b = a;
125 b = c;
126 b = d;
127 }();
128 }
129
130 // CHECK2: alloca %struct.__block_byref_b
131 // CHECK2-NEXT: [[C:%[0-9a-z_]*]] = alloca i32
132 // CHECK2-NEXT: alloca %struct.__block_byref_d
133 //
134 // CHECK2: bitcast %struct.__block_byref_b*
135 // CHECK2-NEXT: store i8*
136 //
137 // CHECK2: [[CapA:%[0-9a-z_.]*]] = getelementptr inbounds {{.*}}, i32 0, i32 7
138 //
139 // CHECK2: getelementptr inbounds %struct.anon{{.*}}, i32 0, i32 0
140 // CHECK2: load i32**
141 // CHECK2: load i32*
142 // CHECK2: store i32 {{.*}}, i32* [[CapA]]
143 //
144 // CHECK2: [[CapC:%[0-9a-z_.]*]] = getelementptr inbounds {{.*}}, i32 0, i32 8
145 // CHECK2-NEXT: [[Val:%[0-9a-z_]*]] = load i32* [[C]]
146 // CHECK2-NEXT: store i32 [[Val]], i32* [[CapC]]
147 //
148 // CHECK2: bitcast %struct.__block_byref_d*
149 // CHECK2-NEXT: store i8*
150}