xref: /minix3/external/bsd/llvm/dist/clang/test/OpenMP/parallel_private_codegen.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
2*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s
3*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
4*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s
5*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -fblocks -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s
6*0a6a1f1dSLionel Sambuc // expected-no-diagnostics
7*0a6a1f1dSLionel Sambuc #ifndef HEADER
8*0a6a1f1dSLionel Sambuc #define HEADER
9*0a6a1f1dSLionel Sambuc 
10*0a6a1f1dSLionel Sambuc template <class T>
11*0a6a1f1dSLionel Sambuc struct S {
12*0a6a1f1dSLionel Sambuc   T f;
SS13*0a6a1f1dSLionel Sambuc   S(T a) : f(a) {}
SS14*0a6a1f1dSLionel Sambuc   S() : f() {}
operator TS15*0a6a1f1dSLionel Sambuc   operator T() { return T(); }
~SS16*0a6a1f1dSLionel Sambuc   ~S() {}
17*0a6a1f1dSLionel Sambuc };
18*0a6a1f1dSLionel Sambuc 
19*0a6a1f1dSLionel Sambuc volatile int g = 1212;
20*0a6a1f1dSLionel Sambuc 
21*0a6a1f1dSLionel Sambuc // CHECK: [[S_FLOAT_TY:%.+]] = type { float }
22*0a6a1f1dSLionel Sambuc // CHECK: [[CAP_MAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* }
23*0a6a1f1dSLionel Sambuc // CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
24*0a6a1f1dSLionel Sambuc // CHECK: [[CAP_TMAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* }
25*0a6a1f1dSLionel Sambuc // CHECK: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
26*0a6a1f1dSLionel Sambuc template <typename T>
tmain()27*0a6a1f1dSLionel Sambuc T tmain() {
28*0a6a1f1dSLionel Sambuc   S<T> test;
29*0a6a1f1dSLionel Sambuc   T t_var = T();
30*0a6a1f1dSLionel Sambuc   T vec[] = {1, 2};
31*0a6a1f1dSLionel Sambuc   S<T> s_arr[] = {1, 2};
32*0a6a1f1dSLionel Sambuc   S<T> var(3);
33*0a6a1f1dSLionel Sambuc #pragma omp parallel private(t_var, vec, s_arr, var)
34*0a6a1f1dSLionel Sambuc   {
35*0a6a1f1dSLionel Sambuc     vec[0] = t_var;
36*0a6a1f1dSLionel Sambuc     s_arr[0] = var;
37*0a6a1f1dSLionel Sambuc   }
38*0a6a1f1dSLionel Sambuc   return T();
39*0a6a1f1dSLionel Sambuc }
40*0a6a1f1dSLionel Sambuc 
main()41*0a6a1f1dSLionel Sambuc int main() {
42*0a6a1f1dSLionel Sambuc #ifdef LAMBDA
43*0a6a1f1dSLionel Sambuc   // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
44*0a6a1f1dSLionel Sambuc   // LAMBDA-LABEL: @main
45*0a6a1f1dSLionel Sambuc   // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
46*0a6a1f1dSLionel Sambuc   [&]() {
47*0a6a1f1dSLionel Sambuc   // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
48*0a6a1f1dSLionel Sambuc   // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
49*0a6a1f1dSLionel Sambuc   // LAMBDA: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]]
50*0a6a1f1dSLionel Sambuc   // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8*
51*0a6a1f1dSLionel Sambuc   // LAMBDA: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]])
52*0a6a1f1dSLionel Sambuc #pragma omp parallel private(g)
53*0a6a1f1dSLionel Sambuc   {
54*0a6a1f1dSLionel Sambuc     // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]])
55*0a6a1f1dSLionel Sambuc     // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
56*0a6a1f1dSLionel Sambuc     // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]],
57*0a6a1f1dSLionel Sambuc     // LAMBDA: call i32 @__kmpc_cancel_barrier(
58*0a6a1f1dSLionel Sambuc     g = 1;
59*0a6a1f1dSLionel Sambuc     // LAMBDA: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
60*0a6a1f1dSLionel Sambuc     // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
61*0a6a1f1dSLionel Sambuc     // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
62*0a6a1f1dSLionel Sambuc     // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
63*0a6a1f1dSLionel Sambuc     [&]() {
64*0a6a1f1dSLionel Sambuc       // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
65*0a6a1f1dSLionel Sambuc       // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
66*0a6a1f1dSLionel Sambuc       g = 2;
67*0a6a1f1dSLionel Sambuc       // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}** [[ARG_PTR_REF]]
68*0a6a1f1dSLionel Sambuc       // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
69*0a6a1f1dSLionel Sambuc       // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_PTR_REF]]
70*0a6a1f1dSLionel Sambuc       // LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
71*0a6a1f1dSLionel Sambuc     }();
72*0a6a1f1dSLionel Sambuc   }
73*0a6a1f1dSLionel Sambuc   }();
74*0a6a1f1dSLionel Sambuc   return 0;
75*0a6a1f1dSLionel Sambuc #elif defined(BLOCKS)
76*0a6a1f1dSLionel Sambuc   // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212,
77*0a6a1f1dSLionel Sambuc   // BLOCKS-LABEL: @main
78*0a6a1f1dSLionel Sambuc   // BLOCKS: call void {{%.+}}(i8*
79*0a6a1f1dSLionel Sambuc   ^{
80*0a6a1f1dSLionel Sambuc   // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
81*0a6a1f1dSLionel Sambuc   // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
82*0a6a1f1dSLionel Sambuc   // BLOCKS: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]]
83*0a6a1f1dSLionel Sambuc   // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8*
84*0a6a1f1dSLionel Sambuc   // BLOCKS: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]])
85*0a6a1f1dSLionel Sambuc #pragma omp parallel private(g)
86*0a6a1f1dSLionel Sambuc   {
87*0a6a1f1dSLionel Sambuc     // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]])
88*0a6a1f1dSLionel Sambuc     // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
89*0a6a1f1dSLionel Sambuc     // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]],
90*0a6a1f1dSLionel Sambuc     // BLOCKS: call i32 @__kmpc_cancel_barrier(
91*0a6a1f1dSLionel Sambuc     g = 1;
92*0a6a1f1dSLionel Sambuc     // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
93*0a6a1f1dSLionel Sambuc     // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
94*0a6a1f1dSLionel Sambuc     // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
95*0a6a1f1dSLionel Sambuc     // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
96*0a6a1f1dSLionel Sambuc     // BLOCKS: call void {{%.+}}(i8*
97*0a6a1f1dSLionel Sambuc     ^{
98*0a6a1f1dSLionel Sambuc       // BLOCKS: define {{.+}} void {{@.+}}(i8*
99*0a6a1f1dSLionel Sambuc       g = 2;
100*0a6a1f1dSLionel Sambuc       // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
101*0a6a1f1dSLionel Sambuc       // BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}*
102*0a6a1f1dSLionel Sambuc       // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
103*0a6a1f1dSLionel Sambuc       // BLOCKS: ret
104*0a6a1f1dSLionel Sambuc     }();
105*0a6a1f1dSLionel Sambuc   }
106*0a6a1f1dSLionel Sambuc   }();
107*0a6a1f1dSLionel Sambuc   return 0;
108*0a6a1f1dSLionel Sambuc #else
109*0a6a1f1dSLionel Sambuc   S<float> test;
110*0a6a1f1dSLionel Sambuc   int t_var = 0;
111*0a6a1f1dSLionel Sambuc   int vec[] = {1, 2};
112*0a6a1f1dSLionel Sambuc   S<float> s_arr[] = {1, 2};
113*0a6a1f1dSLionel Sambuc   S<float> var(3);
114*0a6a1f1dSLionel Sambuc #pragma omp parallel private(t_var, vec, s_arr, var)
115*0a6a1f1dSLionel Sambuc   {
116*0a6a1f1dSLionel Sambuc     vec[0] = t_var;
117*0a6a1f1dSLionel Sambuc     s_arr[0] = var;
118*0a6a1f1dSLionel Sambuc   }
119*0a6a1f1dSLionel Sambuc   return tmain<int>();
120*0a6a1f1dSLionel Sambuc #endif
121*0a6a1f1dSLionel Sambuc }
122*0a6a1f1dSLionel Sambuc 
123*0a6a1f1dSLionel Sambuc // CHECK: define i{{[0-9]+}} @main()
124*0a6a1f1dSLionel Sambuc // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
125*0a6a1f1dSLionel Sambuc // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
126*0a6a1f1dSLionel Sambuc // CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]*
127*0a6a1f1dSLionel Sambuc // 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]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void
128*0a6a1f1dSLionel Sambuc // CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]()
129*0a6a1f1dSLionel Sambuc // CHECK: call void [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
130*0a6a1f1dSLionel Sambuc // CHECK: ret
131*0a6a1f1dSLionel Sambuc //
132*0a6a1f1dSLionel Sambuc // CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}})
133*0a6a1f1dSLionel Sambuc // CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
134*0a6a1f1dSLionel Sambuc // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
135*0a6a1f1dSLionel Sambuc // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
136*0a6a1f1dSLionel Sambuc // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
137*0a6a1f1dSLionel Sambuc // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
138*0a6a1f1dSLionel Sambuc // CHECK-NOT: [[T_VAR_PRIV]]
139*0a6a1f1dSLionel Sambuc // CHECK-NOT: [[VEC_PRIV]]
140*0a6a1f1dSLionel Sambuc // CHECK: {{.+}}:
141*0a6a1f1dSLionel Sambuc // CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_FLOAT_TY]]*
142*0a6a1f1dSLionel Sambuc // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]])
143*0a6a1f1dSLionel Sambuc // CHECK-NOT: [[T_VAR_PRIV]]
144*0a6a1f1dSLionel Sambuc // CHECK-NOT: [[VEC_PRIV]]
145*0a6a1f1dSLionel Sambuc // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
146*0a6a1f1dSLionel Sambuc // CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}** [[GTID_ADDR_REF]]
147*0a6a1f1dSLionel Sambuc // CHECK: [[GTID:%.+]] = load i{{[0-9]+}}* [[GTID_REF]]
148*0a6a1f1dSLionel Sambuc // CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
149*0a6a1f1dSLionel Sambuc // CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
150*0a6a1f1dSLionel Sambuc // CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
151*0a6a1f1dSLionel Sambuc // CHECK: ret void
152*0a6a1f1dSLionel Sambuc 
153*0a6a1f1dSLionel Sambuc // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
154*0a6a1f1dSLionel Sambuc // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
155*0a6a1f1dSLionel Sambuc // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
156*0a6a1f1dSLionel Sambuc // 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]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void
157*0a6a1f1dSLionel Sambuc // CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
158*0a6a1f1dSLionel Sambuc // CHECK: ret
159*0a6a1f1dSLionel Sambuc //
160*0a6a1f1dSLionel Sambuc // CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}})
161*0a6a1f1dSLionel Sambuc // CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
162*0a6a1f1dSLionel Sambuc // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
163*0a6a1f1dSLionel Sambuc // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
164*0a6a1f1dSLionel Sambuc // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
165*0a6a1f1dSLionel Sambuc // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
166*0a6a1f1dSLionel Sambuc // CHECK-NOT: [[T_VAR_PRIV]]
167*0a6a1f1dSLionel Sambuc // CHECK-NOT: [[VEC_PRIV]]
168*0a6a1f1dSLionel Sambuc // CHECK: {{.+}}:
169*0a6a1f1dSLionel Sambuc // CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_INT_TY]]*
170*0a6a1f1dSLionel Sambuc // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_PRIV_ITEM]])
171*0a6a1f1dSLionel Sambuc // CHECK-NOT: [[T_VAR_PRIV]]
172*0a6a1f1dSLionel Sambuc // CHECK-NOT: [[VEC_PRIV]]
173*0a6a1f1dSLionel Sambuc // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]])
174*0a6a1f1dSLionel Sambuc // CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}** [[GTID_ADDR_REF]]
175*0a6a1f1dSLionel Sambuc // CHECK: [[GTID:%.+]] = load i{{[0-9]+}}* [[GTID_REF]]
176*0a6a1f1dSLionel Sambuc // CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
177*0a6a1f1dSLionel Sambuc // CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
178*0a6a1f1dSLionel Sambuc // CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]*
179*0a6a1f1dSLionel Sambuc // CHECK: ret void
180*0a6a1f1dSLionel Sambuc #endif
181*0a6a1f1dSLionel Sambuc 
182