1 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-32
2 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-pc-linux-gnu -emit-pch -o %t %s
3 // RUN: %clang_cc1 -fopenmp -x c++ -triple i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-32
4 // RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA -check-prefix=LAMBDA-32 %s
5 // RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS -check-prefix=BLOCKS-32 %s
6 
7 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
8 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple i386-pc-linux-gnu -emit-pch -o %t %s
9 // RUN: %clang_cc1 -fopenmp-simd -x c++ -triple i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
10 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++11 -DLAMBDA -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
11 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -fblocks -DBLOCKS -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
12 // SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
13 
14 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-64
15 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-pc-linux-gnu -emit-pch -o %t %s
16 // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-64
17 // RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA -check-prefix=LAMBDA-64 %s
18 // RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS -check-prefix=BLOCKS-64 %s
19 
20 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY1 %s
21 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-pc-linux-gnu -emit-pch -o %t %s
22 // RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY1 %s
23 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++11 -DLAMBDA -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY1 %s
24 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -fblocks -DBLOCKS -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY1 %s
25 // SIMD-ONLY1-NOT: {{__kmpc|__tgt}}
26 
27 // RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s
28 
29 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY2 %s
30 // SIMD-ONLY2-NOT: {{__kmpc|__tgt}}
31 // expected-no-diagnostics
32 #ifndef ARRAY
33 #ifndef HEADER
34 #define HEADER
35 
36 typedef void **omp_allocator_handle_t;
37 extern const omp_allocator_handle_t omp_default_mem_alloc;
38 extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
39 extern const omp_allocator_handle_t omp_const_mem_alloc;
40 extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
41 extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
42 extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
43 extern const omp_allocator_handle_t omp_pteam_mem_alloc;
44 extern const omp_allocator_handle_t omp_thread_mem_alloc;
45 
46 struct St {
47   int a, b;
48   St() : a(0), b(0) {}
49   St(const St &st) : a(st.a + st.b), b(0) {}
50   ~St() {}
51 };
52 
53 volatile int g __attribute__((aligned(128))) = 1212;
54 
55 struct SS {
56   int a;
57   int b : 4;
58   int &c;
59   int e[4];
60   SS(int &d) : a(0), b(0), c(d) {
61 #pragma omp parallel firstprivate(a, b, c, e)
62 #ifdef LAMBDA
63     [&]() {
64       ++this->a, --b, (this)->c /= 1;
65 #pragma omp parallel firstprivate(a, b, c)
66       ++(this)->a, --b, this->c /= 1;
67     }();
68 #elif defined(BLOCKS)
69     ^{
70       ++a;
71       --this->b;
72       (this)->c /= 1;
73 #pragma omp parallel firstprivate(a, b, c)
74       ++(this)->a, --b, this->c /= 1;
75     }();
76 #else
77     ++this->a, --b, c /= 1, e[2] = 1111;
78 #endif
79   }
80 };
81 
82 template<typename T>
83 struct SST {
84   T a;
85   SST() : a(T()) {
86 #pragma omp parallel firstprivate(a)
87 #ifdef LAMBDA
88     [&]() {
89       [&]() {
90         ++this->a;
91 #pragma omp parallel firstprivate(a)
92         ++(this)->a;
93       }();
94     }();
95 #elif defined(BLOCKS)
96     ^{
97       ^{
98         ++a;
99 #pragma omp parallel firstprivate(a)
100         ++(this)->a;
101       }();
102     }();
103 #else
104     ++(this)->a;
105 #endif
106   }
107 };
108 
109 template <class T>
110 struct S {
111   T f;
112   S(T a) : f(a + g) {}
113   S() : f(g) {}
114   S(const S &s, St t = St()) : f(s.f + t.a) {}
115   operator T() { return T(); }
116   ~S() {}
117 };
118 
119 // CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
120 // LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
121 // BLOCKS: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
122 // CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
123 // CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
124 // CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} }
125 
126 template <typename T>
127 T tmain() {
128   S<T> test;
129   SST<T> sst;
130   T t_var __attribute__((aligned(128))) = T();
131   T vec[] __attribute__((aligned(128))) = {1, 2};
132   S<T> s_arr[] __attribute__((aligned(128))) = {1, 2};
133   S<T> var __attribute__((aligned(128))) (3);
134 #pragma omp parallel firstprivate(t_var, vec, s_arr, var)
135   {
136     vec[0] = t_var;
137     s_arr[0] = var;
138   }
139 #pragma omp parallel firstprivate(t_var)
140   {}
141   return T();
142 }
143 
144 int main() {
145   static int sivar;
146   SS ss(sivar);
147 #ifdef LAMBDA
148   // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
149   // LAMBDA-LABEL: @main
150   // LAMBDA: alloca [[SS_TY]],
151   // LAMBDA: alloca [[CAP_TY:%.+]],
152   // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@[^(]+]]([[CAP_TY]]*
153   [&]() {
154   // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
155   // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 2, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]], {{.+}})
156 #pragma omp parallel firstprivate(g, sivar)
157   {
158     // LAMBDA: define {{.+}} @{{.+}}([[SS_TY]]*
159     // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
160     // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
161     // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
162     // LAMBDA: store i8
163     // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
164     // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
165     // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
166     // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
167     // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, [[iz:i64|i32]], {{i64|i32}}, {{i64|i32}}, [4 x i{{[0-9]+}}]*)* [[SS_MICROTASK:@.+]] to void
168     // LAMBDA: ret
169 
170     // LAMBDA: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [4 x i{{[0-9]+}}]* {{.+}})
171     // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %
172     // LAMBDA: call{{.*}} void
173     // LAMBDA: ret void
174 
175     // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}})
176     // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
177     // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
178     // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
179     // LAMBDA-64: [[A_CONV:%.+]] = bitcast i64* [[A_PRIV]] to i32*
180     // LAMBDA-64: store i32* [[A_CONV]], i32** [[REFA:%.+]],
181     // LAMBDA-32: store i32* [[A_PRIV]], i32** [[REFA:%.+]],
182     // LAMBDA-64: [[B_CONV:%.+]] = bitcast i64* [[B_PRIV]] to i32*
183     // LAMBDA-64: [[C_CONV:%.+]] = bitcast i64* [[C_PRIV]] to i32*
184     // LAMBDA-64: store i32* [[C_CONV]], i32** [[REFC:%.+]],
185     // LAMBDA-32: store i32* [[C_PRIV]], i32** [[REFC:%.+]],
186     // LAMBDA-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
187     // LAMBDA-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
188     // LAMBDA-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
189     // LAMBDA-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
190     // LAMBDA-64-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_CONV]],
191     // LAMBDA-32-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
192     // LAMBDA-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
193     // LAMBDA-64-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_CONV]],
194     // LAMBDA-32-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
195     // LAMBDA-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
196     // LAMBDA-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
197     // LAMBDA-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
198     // LAMBDA-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
199     // LAMBDA-NEXT: ret void
200 
201     // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[iz]] {{.*}}%{{.+}})
202     // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
203     // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128
204     // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]]
205     // LAMBDA-64: [[SIVAR_PRIVATE_CONV:%.+]] = bitcast i64* [[SIVAR_PRIVATE_ADDR]] to i32*
206     // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]], align 128
207     // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128
208     // LAMBDA-NOT: call {{.*}}void @__kmpc_barrier(
209     g = 1;
210     sivar = 2;
211     // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
212     // LAMBDA-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]],
213     // LAMBDA-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]],
214     // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
215     // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
216     // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
217     // LAMBDA-64: store i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]]
218     // LAMBDA-32: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]]
219     // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
220     [&]() {
221       // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
222       // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
223       g = 2;
224       sivar = 4;
225       // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
226       // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
227       // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
228       // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
229       // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
230       // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
231     }();
232   }
233   }();
234   return 0;
235 #elif defined(BLOCKS)
236   // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212,
237   // BLOCKS-LABEL: @main
238   // BLOCKS: call
239   // BLOCKS: call {{.*}}void {{%.+}}(i8
240   ^{
241   // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
242   // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 2, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]], {{.+}})
243 #pragma omp parallel firstprivate(g, sivar)
244   {
245     // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[iz:i64|i32]] {{.*}}%{{.+}})
246     // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
247     // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128
248     // BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]]
249     // BLOCKS-64: [[SIVAR_PRIVATE_CONV:%.+]] = bitcast i64* [[SIVAR_PRIVATE_ADDR]] to i32*
250     // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]], align 128
251     // BLOCKS: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128
252     // BLOCKS-NOT: call {{.*}}void @__kmpc_barrier(
253     g = 1;
254     sivar = 2;
255     // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
256     // BLOCKS-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]],
257     // BLOCKS-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]],
258     // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
259     // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
260     // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
261     // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
262     // BLOCKS-64: i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]]
263     // BLOCKS-32: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]]
264     // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
265     // BLOCKS: call {{.*}}void {{%.+}}(i8
266     ^{
267       // BLOCKS: define {{.+}} void {{@.+}}(i8*
268       g = 2;
269       sivar = 4;
270       // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
271       // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}*
272       // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
273       // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
274       // BLOCKS: store i{{[0-9]+}} 4, i{{[0-9]+}}*
275       // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
276       // BLOCKS: ret
277     }();
278   }
279   }();
280   return 0;
281 // BLOCKS: define {{.+}} @{{.+}}([[SS_TY]]*
282 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
283 // BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
284 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
285 // BLOCKS: store i8
286 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
287 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
288 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
289 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
290 // BLOCKS: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, [[iz]], [[iz]], [[iz]], [4 x i{{[0-9]+}}]*)* [[SS_MICROTASK:@.+]] to void
291 // BLOCKS: ret
292 
293 // BLOCKS: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [4 x i{{[0-9]+}}]* {{.+}})
294 // BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %
295 // BLOCKS: call{{.*}} void
296 // BLOCKS: ret void
297 
298 // BLOCKS: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}})
299 // BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
300 // BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
301 // BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
302 // BLOCKS-64: [[A_CONV:%.+]] = bitcast i64* [[A_PRIV]] to i32*
303 // BLOCKS-64: store i32* [[A_CONV]], i32** [[REFA:%.+]],
304 // BLOCKS-32: store i32* [[A_PRIV]], i32** [[REFA:%.+]],
305 // BLOCKS-64: [[B_CONV:%.+]] = bitcast i64* [[B_PRIV]] to i32*
306 // BLOCKS-64: [[C_CONV:%.+]] = bitcast i64* [[C_PRIV]] to i32*
307 // BLOCKS-64: store i32* [[C_CONV]], i32** [[REFC:%.+]],
308 // BLOCKS-32: store i32* [[C_PRIV]], i32** [[REFC:%.+]],
309 // BLOCKS-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
310 // BLOCKS-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
311 // BLOCKS-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
312 // BLOCKS-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
313 // BLOCKS-64-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_CONV]],
314 // BLOCKS-32-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
315 // BLOCKS-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
316 // BLOCKS-64-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_CONV]],
317 // BLOCKS-32-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
318 // BLOCKS-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
319 // BLOCKS-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
320 // BLOCKS-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
321 // BLOCKS-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
322 // BLOCKS-NEXT: ret void
323 #else
324   S<float> test;
325   int t_var = 0;
326   int vec[] = {1, 2};
327   S<float> s_arr[] = {1, 2};
328   S<float> var(3);
329 #pragma omp parallel firstprivate(t_var, vec, s_arr, var, sivar)
330   {
331     vec[0] = t_var;
332     s_arr[0] = var;
333     sivar = 2;
334   }
335 #pragma omp parallel allocate(omp_default_mem_alloc: t_var) firstprivate(t_var)
336   {}
337   return tmain<int>();
338 #endif
339 }
340 
341 // CHECK: define {{.*}}i{{[0-9]+}} @main()
342 // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
343 // CHECK: [[T_VAR:%.+]] = alloca i32,
344 // CHECK: [[T_VARCAST:%.+]] = alloca [[iz:i64|i32]],
345 // CHECK: [[SIVARCAST:%.+]] = alloca [[iz]],
346 // CHECK: [[T_VARCAST1:%.+]] = alloca [[iz:i64|i32]],
347 // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
348 // CHECK: [[T_VARVAL:%.+]] = load i32, i32* [[T_VAR]],
349 // CHECK-64: [[T_VARCONV:%.+]] = bitcast i64* [[T_VARCAST]] to i32*
350 // CHECK-64: store i32 [[T_VARVAL]], i32* [[T_VARCONV]],
351 // CHECK-32: store i32 [[T_VARVAL]], i32* [[T_VARCAST]],
352 // CHECK: [[T_VARPVT:%.+]] = load [[iz]], [[iz]]* [[T_VARCAST]],
353 // CHECK: [[SIVARVAL:%.+]] = load i32, i32* @{{.+}},
354 // CHECK-64: [[SIVARCONV:%.+]] = bitcast i64* [[SIVARCAST]] to i32*
355 // CHECK-64: store i32 [[SIVARVAL]], i32* [[SIVARCONV]],
356 // CHECK-32: store i32 [[SIVARVAL]], i32* [[SIVARCAST]],
357 // CHECK: [[SIVARPVT:%.+]] = load [[iz]], [[iz]]* [[SIVARCAST]],
358 // CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, [[iz]], [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}})* [[MAIN_MICROTASK:@.+]] to void {{.*}}[[iz]] [[T_VARPVT]],{{.*}}[[iz]] [[SIVARPVT]]
359 // CHECK: [[T_VARVAL:%.+]] = load i32, i32* [[T_VAR]],
360 // CHECK-64: [[T_VARCONV:%.+]] = bitcast i64* [[T_VARCAST1]] to i32*
361 // CHECK-64: store i32 [[T_VARVAL]], i32* [[T_VARCONV]],
362 // CHECK-32: store i32 [[T_VARVAL]], i32* [[T_VARCAST1]],
363 // CHECK: [[T_VARPVT:%.+]] = load [[iz]], [[iz]]* [[T_VARCAST1]],
364 // CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[iz]])* [[MAIN_MICROTASK1:@.+]] to void {{.*}}[[iz]] [[T_VARPVT]])
365 // CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]()
366 // CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
367 // CHECK: ret
368 //
369 // CHECK: define internal {{.*}}void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [[iz]] {{.*}}%{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, [[iz]] {{.*}}[[SIVAR:%.+]])
370 // CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
371 // CHECK: [[SIVAR7_PRIV:%.+]] = alloca i{{[0-9]+}},
372 // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
373 // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
374 // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
375 // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
376 
377 // CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** %
378 // CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** %
379 // CHECK-64: [[T_VAR_CONV:%.+]] = bitcast i64* [[T_VAR_PRIV]] to i32*
380 // CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** %
381 // CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %
382 // CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** %
383 // CHECK-64: [[SIVAR7_CONV:%.+]] = bitcast i64* [[SIVAR7_PRIV]] to i32*
384 // CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
385 // CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8*
386 // CHECK: call void @llvm.memcpy.{{.+}}(i8* align {{[0-9]+}} [[VEC_DEST]], i8* align {{[0-9]+}} [[VEC_SRC]],
387 // CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
388 // CHECK: [[S_ARR_BEGIN:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_REF]] to [[S_FLOAT_TY]]*
389 // CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2
390 // CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]]
391 // CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]]
392 // CHECK: [[S_ARR_BODY]]
393 // CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP:%.+]])
394 // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR:@.+]]([[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]])
395 // CHECK: call {{.*}} [[ST_TY_DESTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP]])
396 // CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]]
397 // CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]])
398 // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]])
399 // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
400 
401 // CHECK-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR7_CONV]],
402 // CHECK-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR7_PRIV]],
403 
404 // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
405 // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
406 // CHECK: ret void
407 
408 
409 // CHECK:    define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[iz]] [[T_VAR:%.+]])
410 // CHECK:    [[GTID_ADDR:%.+]] = alloca i32*,
411 // CHECK:    store [[iz]] [[T_VAR]], [[iz]]* [[T_VAR_ADDR:%.+]],
412 // CHECK-64: [[BC:%.+]] = bitcast [[iz]]* [[T_VAR_ADDR]] to i32*
413 // CHECK:    [[GTID_PTR:%.+]] = load i32*, i32** [[GTID_ADDR]],
414 // CHECK:    [[GTID:%.+]] = load i32, i32* [[GTID_PTR]],
415 // CHECK:    [[ALLOCATOR:%.+]] = load i8**, i8*** @omp_default_mem_alloc,
416 // CHECK:    [[T_VAR_VOID_PTR:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID]], [[iz]] 4, i8** [[ALLOCATOR]])
417 // CHECK:    [[T_VAR_PRIV:%.+]] = bitcast i8* [[T_VAR_VOID_PTR]] to i32*
418 // CHECK-32: [[T_VAR_VAL:%.+]] = load i32, i32* [[T_VAR_ADDR]],
419 // CHECK-64: [[T_VAR_VAL:%.+]] = load i32, i32* [[BC]],
420 // CHECK:    store i32 [[T_VAR_VAL]], i32* [[T_VAR_PRIV]],
421 // CHECK:    call void @__kmpc_free(i32 [[GTID]], i8* [[T_VAR_VOID_PTR]], i8** [[ALLOCATOR]])
422 // CHECK:    ret void
423 
424 
425 // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
426 // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
427 // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
428 // CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void
429 // CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
430 // CHECK: ret
431 //
432 // CHECK: define {{.+}} @{{.+}}([[SS_TY]]*
433 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
434 // CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
435 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
436 // CHECK: store i8
437 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
438 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
439 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
440 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
441 // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, [[iz]], [[iz]], [[iz]], [4 x i32]*)* [[SS_MICROTASK:@.+]] to void
442 // CHECK: ret
443 
444 // CHECK: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [4 x i{{[0-9]+}}]* {{.+}})
445 // CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
446 // CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
447 // CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
448 // CHECK: [[E_PRIV:%.+]] = alloca [4 x i{{[0-9]+}}],
449 // CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[A_PRIV]]
450 // CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[B_PRIV]]
451 // CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[C_PRIV]]
452 // CHECK-64: [[A_CONV:%.+]] = bitcast i64* [[A_PRIV:%.+]] to i32*
453 // CHECK-64: store i32* [[A_CONV]], i32** [[REFA:%.+]],
454 // CHECK-32: store i32* [[A_PRIV]], i32** [[REFA:%.+]],
455 // CHECK-64: [[B_CONV:%.+]] = bitcast i64* [[B_PRIV:%.+]] to i32*
456 // CHECK-64: [[C_CONV:%.+]] = bitcast i64* [[C_PRIV:%.+]] to i32*
457 // CHECK-64: store i32* [[C_CONV]], i32** [[REFC:%.+]],
458 // CHECK-32: store i32* [[C_PRIV]], i32** [[REFC:%.+]],
459 // CHECK: bitcast [4 x i{{[0-9]+}}]* [[E_PRIV]] to i8*
460 // CHECK: bitcast [4 x i{{[0-9]+}}]* %{{.+}} to i8*
461 // CHECK: call void @llvm.memcpy
462 // CHECK: store [4 x i{{[0-9]+}}]* [[E_PRIV]], [4 x i{{[0-9]+}}]** [[REFE:%.+]],
463 // CHECK-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
464 // CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
465 // CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
466 // CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
467 // CHECK-64-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_CONV]],
468 // CHECK-32-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
469 // CHECK-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
470 // CHECK-64-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_CONV]],
471 // CHECK-32-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
472 // CHECK-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
473 // CHECK-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
474 // CHECK-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
475 // CHECK-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
476 // CHECK-NEXT: [[E_PRIV:%.+]] = load [4 x i{{[0-9]+}}]*, [4 x i{{[0-9]+}}]** [[REFE]],
477 // CHECK-NEXT: [[E_PRIV_2:%.+]] = getelementptr inbounds [4 x i{{[0-9]+}}], [4 x i{{[0-9]+}}]* [[E_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
478 // CHECK-NEXT: store i32 1111, i32* [[E_PRIV_2]],
479 // CHECK-NEXT: ret void
480 
481 // CHECK: define internal {{.*}}void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}})
482 // CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128
483 // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], align 128
484 // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]], align 128
485 // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], align 128
486 // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
487 
488 // CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** %
489 // CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %
490 // CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** %
491 // CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** %
492 
493 // CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]], align 128
494 // CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], align 128
495 // CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
496 // CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8*
497 // CHECK: call void @llvm.memcpy.{{.+}}(i8* align 128 [[VEC_DEST]], i8* align 128 [[VEC_SRC]], i{{[0-9]+}} {{[0-9]+}}, i1
498 // CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
499 // CHECK: [[S_ARR_BEGIN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_REF]] to [[S_INT_TY]]*
500 // CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2
501 // CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]]
502 // CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]]
503 // CHECK: [[S_ARR_BODY]]
504 // CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]])
505 // CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR:@.+]]([[S_INT_TY]]* {{.+}}, [[S_INT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]])
506 // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
507 // CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]]
508 // CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]])
509 // CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]])
510 // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
511 // CHECK-NOT: call {{.*}}void @__kmpc_barrier(
512 // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
513 // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*
514 // CHECK: ret void
515 
516 #endif
517 #else
518 typedef void **omp_allocator_handle_t;
519 extern const omp_allocator_handle_t omp_default_mem_alloc;
520 extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
521 extern const omp_allocator_handle_t omp_const_mem_alloc;
522 extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
523 extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
524 extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
525 extern const omp_allocator_handle_t omp_pteam_mem_alloc;
526 extern const omp_allocator_handle_t omp_thread_mem_alloc;
527 
528 struct St {
529   int a, b;
530   St() : a(0), b(0) {}
531   St(const St &) { }
532   ~St() {}
533   void St_func(St s[2], int n, long double vla1[n]) {
534     double vla2[n][n] __attribute__((aligned(128)));
535     a = b;
536 #pragma omp parallel allocate(omp_thread_mem_alloc:vla2) firstprivate(s, vla1, vla2)
537     vla1[b] = vla2[1][n - 1] = a = b;
538   }
539 };
540 
541 // ARRAY-LABEL: array_func
542 void array_func(float a[3], St s[2], int n, long double vla1[n]) {
543   double vla2[n][n] __attribute__((aligned(128)));
544 // ARRAY: @__kmpc_fork_call(
545 // ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St*,
546 // ARRAY-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80*,
547 // ARRAY-DAG: [[PRIV_A:%.+]] = alloca float*,
548 // ARRAY-DAG: [[PRIV_VLA2:%.+]] = alloca double*,
549 // ARRAY-DAG: store %struct.St* %{{.+}}, %struct.St** [[PRIV_S]],
550 // ARRAY-DAG: store x86_fp80* %{{.+}}, x86_fp80** [[PRIV_VLA1]],
551 // ARRAY-DAG: store float* %{{.+}}, float** [[PRIV_A]],
552 // ARRAY-DAG: store double* %{{.+}}, double** [[PRIV_VLA2]],
553 // ARRAY: call i8* @llvm.stacksave()
554 // ARRAY: [[SIZE:%.+]] = mul nuw i64 %{{.+}}, 8
555 // ARRAY: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 128 %{{.+}}, i8* align 128 %{{.+}}, i64 [[SIZE]], i1 false)
556 #pragma omp parallel firstprivate(a, s, vla1, vla2)
557   s[0].St_func(s, n, vla1);
558   ;
559 }
560 
561 // ARRAY-LABEL: St_func
562 // ARRAY: @__kmpc_fork_call(
563 // ARRAY-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80*,
564 // ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St*,
565 // ARRAY-DAG: [[PRIV_VLA2:%.+]] = alloca double*,
566 // ARRAY-DAG: store %struct.St* %{{.+}}, %struct.St** [[PRIV_S]],
567 // ARRAY-DAG: store x86_fp80* %{{.+}}, x86_fp80** [[PRIV_VLA1]],
568 // ARRAY-DAG: store double* %{{.+}}, double** [[PRIV_VLA2]],
569 // ARRAY: [[SIZE:%.+]] = mul nuw i64 %{{.+}}, 8
570 // ARRAY: [[SZ1:%.+]] = add nuw i64 [[SIZE]], 127
571 // ARRAY: [[SZ2:%.+]] = udiv i64 [[SZ1]], 128
572 // ARRAY: [[SIZE:%.+]] = mul nuw i64 [[SZ2]], 128
573 // ARRAY: [[ALLOCATOR:%.+]] = load i8**, i8*** @omp_thread_mem_alloc,
574 // ARRAY: [[VLA2_VOID_PTR:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID:%.+]], i64 [[SIZE]], i8** [[ALLOCATOR]])
575 // ARRAY: [[VLA2_PTR:%.+]] = bitcast i8* [[VLA2_VOID_PTR]] to double*
576 // ARRAY: [[SIZE:%.+]] = mul nuw i64 %{{.+}}, 8
577 // ARRAY: [[BC:%.+]] = bitcast double* [[VLA2_PTR]] to i8*
578 // ARRAY: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 128 [[BC]], i8* align 128 %{{.+}}, i64 [[SIZE]], i1 false)
579 // ARRAY: call void @__kmpc_free(i32 [[GTID]], i8* [[VLA2_VOID_PTR]], i8** [[ALLOCATOR]])
580 // ARRAY-NEXT: ret void
581 #endif
582 
583 
584