1 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=OMP50,CHECK
2 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -fopenmp-version=45 -o - | FileCheck %s --check-prefixes=OMP45,CHECK
3 
4 // RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
5 // RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefixes=OMP50,CHECK
6 
7 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
8 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefixes=OMP45,CHECK
9 
10 // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -std=c++11 -fopenmp -fnoopenmp-use-tls -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG
11 // RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s
12 
13 // RUN: %clang_cc1 -verify -fopenmp-simd -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s
14 // RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
15 // RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
16 // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -std=c++11 -fopenmp-simd -fnoopenmp-use-tls -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
17 // RUN: %clang_cc1 -verify -fopenmp-simd -fnoopenmp-use-tls -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
18 // SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
19 // expected-no-diagnostics
20 #ifndef ARRAY
21 #ifndef HEADER
22 #define HEADER
23 
24 class TestClass {
25 public:
26   int a;
TestClass()27   TestClass() : a(0) {}
TestClass(const TestClass & C)28   TestClass(const TestClass &C) : a(C.a) {}
operator =(const TestClass &)29   TestClass &operator=(const TestClass &) { return *this;}
~TestClass()30   ~TestClass(){};
31 };
32 
33 // CHECK-DAG:   [[TEST_CLASS_TY:%.+]] = type { i{{[0-9]+}} }
34 // CHECK-DAG:   [[SST_TY:%.+]] = type { double }
35 // CHECK-DAG:   [[SS_TY:%.+]] = type { i32, i8, i32* }
36 // CHECK-DAG:   [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
37 // CHECK:       [[IMPLICIT_BARRIER_SINGLE_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 322, i32 0, i32 0, i8*
38 
39 // CHECK:       define{{( dso_local)?}} void [[FOO:@.+]]()
40 
41 TestClass tc;
42 TestClass tc2[2];
43 #pragma omp threadprivate(tc, tc2)
44 
foo()45 void foo() { extern void mayThrow(); mayThrow(); }
46 
47 struct SS {
48   int a;
49   int b : 4;
50   int &c;
SSSS51   SS(int &d) : a(0), b(0), c(d) {
52 #pragma omp parallel firstprivate(a, b, c)
53 #pragma omp single copyprivate(a, this->b, (this)->c)
54     [&]() {
55       ++this->a, --b, (this)->c /= 1;
56 #pragma omp parallel firstprivate(a, b, c)
57 #pragma omp single copyprivate(a, this->b, (this)->c)
58       ++(this)->a, --b, this->c /= 1;
59     }();
60   }
61 };
62 
63 template<typename T>
64 struct SST {
65   T a;
SSTSST66   SST() : a(T()) {
67 #pragma omp parallel firstprivate(a)
68 #pragma omp single copyprivate(this->a)
69     [&]() {
70       [&]() {
71         ++this->a;
72 #pragma omp parallel firstprivate(a)
73 #pragma omp single copyprivate((this)->a)
74         ++(this)->a;
75       }();
76     }();
77   }
78 };
79 
80 // CHECK-LABEL: @main
81 // TERM_DEBUG-LABEL: @main
main()82 int main() {
83   // CHECK:     alloca i32
84   // CHECK-DAG: [[A_ADDR:%.+]] = alloca i8
85   // CHECK-DAG: [[A2_ADDR:%.+]] = alloca [2 x i8]
86   // CHECK-DAG: [[C_ADDR:%.+]] = alloca [[TEST_CLASS_TY]]
87   // CHECK-DAG: [[DID_IT:%.+]] = alloca i32,
88   // CHECK-DAG: [[COPY_LIST:%.+]] = alloca [5 x i8*],
89   char a;
90   char a2[2];
91   TestClass &c = tc;
92   SST<double> sst;
93   SS ss(c.a);
94 
95 // CHECK:       [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]])
96 // CHECK:       [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
97 // CHECK-NEXT:  [[IS_SINGLE:%.+]] = icmp ne i32 [[RES]], 0
98 // CHECK-NEXT:  br i1 [[IS_SINGLE]], label {{%?}}[[THEN:.+]], label {{%?}}[[EXIT:.+]]
99 // CHECK:       [[THEN]]
100 // CHECK-NEXT:  store i8 2, i8* [[A_ADDR]]
101 // CHECK-NEXT:  call void @__kmpc_end_single([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
102 // CHECK-NEXT:  br label {{%?}}[[EXIT]]
103 // CHECK:       [[EXIT]]
104 // CHECK-NOT:   call {{.+}} @__kmpc_cancel_barrier
105 #pragma omp single nowait
106   a = 2;
107 // CHECK:       [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
108 // CHECK-NEXT:  [[IS_SINGLE:%.+]] = icmp ne i32 [[RES]], 0
109 // CHECK-NEXT:  br i1 [[IS_SINGLE]], label {{%?}}[[THEN:.+]], label {{%?}}[[EXIT:.+]]
110 // CHECK:       [[THEN]]
111 // CHECK-NEXT:  store i8 2, i8* [[A_ADDR]]
112 // CHECK-NEXT:  call void @__kmpc_end_single([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
113 // CHECK-NEXT:  br label {{%?}}[[EXIT]]
114 // CHECK:       [[EXIT]]
115 // CHECK:       call{{.*}} @__kmpc_barrier([[IDENT_T_TY]]* [[IMPLICIT_BARRIER_SINGLE_LOC]], i32 [[GTID]])
116 #pragma omp single
117   a = 2;
118 // CHECK:       store i32 0, i32* [[DID_IT]]
119 // CHECK:       [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
120 // CHECK-NEXT:  [[IS_SINGLE:%.+]] = icmp ne i32 [[RES]], 0
121 // CHECK-NEXT:  br i1 [[IS_SINGLE]], label {{%?}}[[THEN:.+]], label {{%?}}[[EXIT:.+]]
122 // CHECK:       [[THEN]]
123 // CHECK-NEXT:  invoke void [[FOO]]()
124 // CHECK:       to label {{%?}}[[CONT:.+]] unwind
125 // CHECK:       [[CONT]]
126 // CHECK:       call void @__kmpc_end_single([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
127 // CHECK:       store i32 1, i32* [[DID_IT]]
128 // CHECK-NEXT:  br label {{%?}}[[EXIT]]
129 // CHECK:       [[EXIT]]
130 // CHECK:       [[A_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
131 // CHECK:       store i8* [[A_ADDR]], i8** [[A_PTR_REF]],
132 // CHECK:       [[C_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
133 // CHECK:       store i8* {{.+}}, i8** [[C_PTR_REF]],
134 // CHECK:       [[TC_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
135 // CHECK:       [[TC_THREADPRIVATE_ADDR_VOID_PTR:%.+]] = call{{.*}} i8* @__kmpc_threadprivate_cached
136 // CHECK:       [[TC_THREADPRIVATE_ADDR:%.+]] = bitcast i8* [[TC_THREADPRIVATE_ADDR_VOID_PTR]] to [[TEST_CLASS_TY]]*
137 // CHECK:       [[TC_PTR_REF_VOID_PTR:%.+]] = bitcast [[TEST_CLASS_TY]]* [[TC_THREADPRIVATE_ADDR]] to i8*
138 // CHECK:       store i8* [[TC_PTR_REF_VOID_PTR]], i8** [[TC_PTR_REF]],
139 // CHECK:       [[A2_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
140 // CHECK:       [[BITCAST:%.+]] = bitcast [2 x i8]* [[A2_ADDR]] to i8*
141 // CHECK:       store i8* [[BITCAST]], i8** [[A2_PTR_REF]],
142 // CHECK:       [[TC2_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
143 // CHECK:       [[TC2_THREADPRIVATE_ADDR_VOID_PTR:%.+]] = call{{.*}} i8* @__kmpc_threadprivate_cached
144 // CHECK:       [[TC2_THREADPRIVATE_ADDR:%.+]] = bitcast i8* [[TC2_THREADPRIVATE_ADDR_VOID_PTR]] to [2 x [[TEST_CLASS_TY]]]*
145 // CHECK:       [[TC2_PTR_REF_VOID_PTR:%.+]] = bitcast [2 x [[TEST_CLASS_TY]]]* [[TC2_THREADPRIVATE_ADDR]] to i8*
146 // CHECK:       store i8* [[TC2_PTR_REF_VOID_PTR]], i8** [[TC2_PTR_REF]],
147 // CHECK:       [[COPY_LIST_VOID_PTR:%.+]] = bitcast [5 x i8*]* [[COPY_LIST]] to i8*
148 // CHECK:       [[DID_IT_VAL:%.+]] = load i32, i32* [[DID_IT]],
149 // CHECK:       call void @__kmpc_copyprivate([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i64 40, i8* [[COPY_LIST_VOID_PTR]], void (i8*, i8*)* [[COPY_FUNC:@.+]], i32 [[DID_IT_VAL]])
150 // CHECK-NOT:   call {{.+}} @__kmpc_cancel_barrier
151 #pragma omp single copyprivate(a, c, tc, a2, tc2)
152   foo();
153 // CHECK-NOT:   call i32 @__kmpc_single
154 // CHECK-NOT:   call void @__kmpc_end_single
155   return a;
156 }
157 
158 // OMP50-LABEL: declare i8* @__kmpc_threadprivate_cached(
159 // CHECK: void [[COPY_FUNC]](i8* %0, i8* %1)
160 // CHECK: store i8* %0, i8** [[DST_ADDR_REF:%.+]],
161 // CHECK: store i8* %1, i8** [[SRC_ADDR_REF:%.+]],
162 // CHECK: [[DST_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[DST_ADDR_REF]],
163 // CHECK: [[DST_ADDR:%.+]] = bitcast i8* [[DST_ADDR_VOID_PTR]] to [5 x i8*]*
164 // CHECK: [[SRC_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[SRC_ADDR_REF]],
165 // CHECK: [[SRC_ADDR:%.+]] = bitcast i8* [[SRC_ADDR_VOID_PTR]] to [5 x i8*]*
166 // CHECK: [[DST_A_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DST_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
167 // CHECK: [[DST_A_ADDR:%.+]] = load i8*, i8** [[DST_A_ADDR_REF]],
168 // CHECK: [[SRC_A_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[SRC_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
169 // CHECK: [[SRC_A_ADDR:%.+]] = load i8*, i8** [[SRC_A_ADDR_REF]],
170 // CHECK: [[SRC_A_VAL:%.+]] = load i8, i8* [[SRC_A_ADDR]],
171 // CHECK: store i8 [[SRC_A_VAL]], i8* [[DST_A_ADDR]],
172 // CHECK: [[DST_C_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DST_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
173 // CHECK: [[DST_C_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[DST_C_ADDR_REF]],
174 // CHECK: [[DST_C_ADDR:%.+]] = bitcast i8* [[DST_C_ADDR_VOID_PTR]] to [[TEST_CLASS_TY]]*
175 // CHECK: [[SRC_C_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[SRC_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
176 // CHECK: [[SRC_C_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[SRC_C_ADDR_REF]],
177 // CHECK: [[SRC_C_ADDR:%.+]] = bitcast i8* [[SRC_C_ADDR_VOID_PTR]] to [[TEST_CLASS_TY]]*
178 // CHECK: call{{.*}} [[TEST_CLASS_TY_ASSIGN:@.+]]([[TEST_CLASS_TY]]* {{[^,]*}} [[DST_C_ADDR]], [[TEST_CLASS_TY]]* {{.*}}[[SRC_C_ADDR]])
179 // CHECK: [[DST_TC_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DST_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
180 // CHECK: [[DST_TC_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[DST_TC_ADDR_REF]],
181 // CHECK: [[DST_TC_ADDR:%.+]] = bitcast i8* [[DST_TC_ADDR_VOID_PTR]] to [[TEST_CLASS_TY]]*
182 // CHECK: [[SRC_TC_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[SRC_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
183 // CHECK: [[SRC_TC_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[SRC_TC_ADDR_REF]],
184 // CHECK: [[SRC_TC_ADDR:%.+]] = bitcast i8* [[SRC_TC_ADDR_VOID_PTR]] to [[TEST_CLASS_TY]]*
185 // CHECK: call{{.*}} [[TEST_CLASS_TY_ASSIGN]]([[TEST_CLASS_TY]]* {{[^,]*}} [[DST_TC_ADDR]], [[TEST_CLASS_TY]]* {{.*}}[[SRC_TC_ADDR]])
186 // CHECK: [[DST_A2_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DST_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
187 // CHECK: [[DST_A2_ADDR:%.+]] = load i8*, i8** [[DST_A2_ADDR_REF]],
188 // CHECK: [[SRC_A2_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[SRC_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
189 // CHECK: [[SRC_A2_ADDR:%.+]] = load i8*, i8** [[SRC_A2_ADDR_REF]],
190 // CHECK: call void @llvm.memcpy.{{.+}}(i8* align 1 [[DST_A2_ADDR]], i8* align 1 [[SRC_A2_ADDR]], i{{[0-9]+}} 2, i1 false)
191 // CHECK: [[DST_TC2_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DST_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
192 // CHECK: [[DST_TC2_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[DST_TC2_ADDR_REF]],
193 // CHECK: [[DST_TC2_ADDR:%.+]] = bitcast i8* [[DST_TC2_ADDR_VOID_PTR]] to [[TEST_CLASS_TY]]*
194 // CHECK: [[SRC_TC2_ADDR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[SRC_ADDR]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
195 // CHECK: [[SRC_TC2_ADDR_VOID_PTR:%.+]] = load i8*, i8** [[SRC_TC2_ADDR_REF]],
196 // CHECK: [[SRC_TC2_ADDR:%.+]] = bitcast i8* [[SRC_TC2_ADDR_VOID_PTR]] to [[TEST_CLASS_TY]]*
197 // CHECK: br i1
198 // CHECK: call{{.*}} [[TEST_CLASS_TY_ASSIGN]]([[TEST_CLASS_TY]]* {{[^,]*}} %{{.+}}, [[TEST_CLASS_TY]]* {{.*}})
199 // CHECK: br i1
200 // CHECK: ret void
201 
202 
203 // OMP50-LABEL: void @_ZN3SSTIdEC2Ev(
204 // OMP50: getelementptr inbounds [[SST_TY]], [[SST_TY]]* %{{.+}}, i32 0, i32 0
205 // OMP50-NEXT: store double 0.000000e+00, double* %
206 // OMP50-NEXT: getelementptr inbounds [[SST_TY]], [[SST_TY]]* %{{.+}}, i32 0, i32 0
207 // OMP50-NEXT: store double* %{{.+}}, double** %
208 // OMP50-NEXT: load double*, double** %
209 // OMP50-NEXT: load double, double* %
210 // OMP50-NEXT: bitcast i64* %{{.+}} to double*
211 // OMP50-NEXT: store double %{{.+}}, double* %
212 // OMP50-NEXT: load i64, i64* %
213 // OMP50-NEXT: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* @{{.+}}, i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[SST_TY]]*, i64)* [[SST_MICROTASK:@.+]] to void
214 // OMP50-NEXT: ret void
215 
216 // OMP50: define internal void [[SST_MICROTASK]](i32* {{[^,]+}}, i32* {{[^,]+}}, [[SST_TY]]* {{.+}}, i64 {{.+}})
217 // OMP50: [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
218 // OMP50-NEXT: icmp ne i32 [[RES]], 0
219 // OMP50-NEXT: br i1
220 
221 // OMP50: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1
222 // OMP50-NEXT: load double*, double** %
223 // OMP50-NEXT: store double* %
224 // OMP50-LABEL: invoke void @_ZZN3SSTIdEC1EvENKUlvE_clEv(
225 
226 // OMP50: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
227 // OMP50-NEXT: store i32 1, i32* [[DID_IT]],
228 // OMP50-NEXT: br label
229 
230 // OMP50: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
231 // OMP50-NEXT: br label
232 
233 // OMP50: getelementptr inbounds [1 x i8*], [1 x i8*]* [[LIST:%.+]], i64 0, i64 0
234 // OMP50: load double*, double** %
235 // OMP50-NEXT: bitcast double* %
236 // OMP50-NEXT: store i8* %
237 // OMP50-NEXT: bitcast [1 x i8*]* [[LIST]] to i8*
238 // OMP50-NEXT: load i32, i32* [[DID_IT]],
239 // OMP50-NEXT: call void @__kmpc_copyprivate([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}, i64 8, i8* %{{.+}}, void (i8*, i8*)* [[COPY_FUNC:@[^,]+]], i32 %{{.+}})
240 // OMP50-NEXT:  ret void
241 
242 // OMP50-LABEL: @_ZZN3SSTIdEC1EvENKUlvE_clEv(
243 // OMP50: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1
244 // OMP50-NEXT: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1
245 // OMP50-NEXT: load double*, double** %
246 // OMP50-NEXT: store double* %
247 // OMP50-LABEL: call void @_ZZZN3SSTIdEC1EvENKUlvE_clEvENKUlvE_clEv(
248 // OMP50-NEXT: ret void
249 
250 // OMP50: define internal void [[COPY_FUNC]](i8* %0, i8* %1)
251 // OMP50: ret void
252 
253 // OMP45-LABEL:      parallel_single
254 // TERM_DEBUG-LABEL: parallel_single
parallel_single()255 void parallel_single() {
256 #pragma omp parallel
257 #pragma omp single
258   // TERM_DEBUG-NOT: __kmpc_global_thread_num
259   // TERM_DEBUG:     call i32 @__kmpc_single({{.+}}), !dbg [[DBG_LOC_START:![0-9]+]]
260   // TERM_DEBUG:     invoke void {{.*}}foo{{.*}}()
261   // TERM_DEBUG:     unwind label %[[TERM_LPAD:.+]],
262   // TERM_DEBUG-NOT: __kmpc_global_thread_num
263   // TERM_DEBUG:     call void @__kmpc_end_single({{.+}}), !dbg [[DBG_LOC_END:![0-9]+]]
264   // TERM_DEBUG:     [[TERM_LPAD]]
265   // TERM_DEBUG:     call void @__clang_call_terminate
266   // TERM_DEBUG:     unreachable
267   foo();
268 }
269 // TERM_DEBUG-DAG: [[DBG_LOC_START]] = !DILocation(line: [[@LINE-12]],
270 // TERM_DEBUG-DAG: [[DBG_LOC_END]] = !DILocation(line: [[@LINE-3]],
271 #endif
272 #else
273 // ARRAY-LABEL: array_func
274 struct St {
275   int a, b;
StSt276   St() : a(0), b(0) {}
operator =St277   St &operator=(const St &) { return *this; };
~StSt278   ~St() {}
279 };
280 
array_func(int n,int a[n],St s[2])281 void array_func(int n, int a[n], St s[2]) {
282 // ARRAY: call void @__kmpc_copyprivate(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i64 16, i8* %{{.+}}, void (i8*, i8*)* [[CPY:@.+]], i32 %{{.+}})
283 #pragma omp single copyprivate(a, s)
284   ;
285 }
286 // ARRAY: define internal void [[CPY]]
287 // ARRAY: store i32* %{{.+}}, i32** %{{.+}},
288 // ARRAY: store %struct.St* %{{.+}}, %struct.St** %{{.+}},
289 #endif
290 
291 // CHECK-LABEL:@_ZN2SSC2ERi(
292 // CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* @{{.+}}, i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[SS_TY]]*, i64, i64, i64)* [[SS_MICROTASK:@.+]] to void
293 // CHECK-NEXT: ret void
294 
295 // CHECK: define internal void [[SS_MICROTASK]](i32* {{[^,]+}}, i32* {{[^,]+}}, [[SS_TY]]* {{.+}}, i64 {{.+}}, i64 {{.+}}, i64 {{.+}})
296 // Private a
297 // CHECK: alloca i64,
298 // Private b
299 // CHECK: alloca i64,
300 // Private c
301 // CHECK: alloca i64,
302 // CHECK: alloca i32*,
303 // CHECK: alloca i32*,
304 // CHECK: alloca i32*,
305 // CHECK: alloca i32*,
306 // CHECK: [[DID_IT:%.+]] = alloca i32,
307 // CHECK: bitcast i64* %{{.+}} to i32*
308 // CHECK: bitcast i64* %{{.+}} to i32*
309 // CHECK: bitcast i64* %{{.+}} to i32*
310 // CHECK: store i32 0, i32* [[DID_IT]],
311 // CHECK: [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
312 // CHECK-NEXT: icmp ne i32 [[RES]], 0
313 // CHECK-NEXT: br i1
314 
315 // CHECK: getelementptr inbounds [[CAP_TY:%.+]], [[CAP_TY]]* [[CAP:%.+]], i32 0, i32 0
316 // CHECK: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 1
317 // CHECK-NEXT: load i32*, i32** %
318 // CHECK-NEXT: store i32* %
319 // CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 2
320 // CHECK-NEXT: store i32* %
321 // CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 3
322 // CHECK-NEXT: load i32*, i32** %
323 // CHECK-NEXT: store i32* %
324 // CHECK-LABEL: invoke void @_ZZN2SSC1ERiENKUlvE_clEv(
325 // CHECK-SAME: [[CAP_TY]]* {{[^,]*}} [[CAP]])
326 
327 // CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
328 // CHECK: store i32 1, i32* [[DID_IT]],
329 // CHECK: br label
330 
331 // CHECK: call void @__kmpc_end_single(%{{.+}}* @{{.+}}, i32 %{{.+}})
332 // CHECK: br label
333 
334 // CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST:%.+]], i64 0, i64 0
335 // CHECK: load i32*, i32** %
336 // CHECK-NEXT: bitcast i32* %
337 // CHECK-NEXT: store i8* %
338 // CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST]], i64 0, i64 1
339 // CHECK-NEXT: bitcast i32* %
340 // CHECK-NEXT: store i8* %
341 // CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST]], i64 0, i64 2
342 // CHECK: load i32*, i32** %
343 // CHECK-NEXT: bitcast i32* %
344 // CHECK-NEXT: store i8* %
345 // CHECK-NEXT: bitcast [3 x i8*]* [[LIST]] to i8*
346 // CHECK-NEXT: load i32, i32* [[DID_IT]],
347 // CHECK-NEXT: call void @__kmpc_copyprivate([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}, i64 24, i8* %{{.+}}, void (i8*, i8*)* [[COPY_FUNC:@[^,]+]], i32 %{{.+}})
348 // CHECK-NEXT: ret void
349 
350 // CHECK-LABEL: @_ZZN2SSC1ERiENKUlvE_clEv(
351 // CHECK: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP:%.+]], i32 0, i32 1
352 // CHECK-NEXT: load i32*, i32** %
353 // CHECK-NEXT: load i32, i32* %
354 // CHECK-NEXT: add nsw i32 %{{.+}}, 1
355 // CHECK-NEXT: store i32 %
356 // CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 2
357 // CHECK-NEXT: load i32*, i32** %
358 // CHECK-NEXT: load i32, i32* %
359 // CHECK-NEXT: add nsw i32 %{{.+}}, -1
360 // CHECK-NEXT: store i32 %
361 // CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 3
362 // CHECK-NEXT: load i32*, i32** %
363 // CHECK-NEXT: load i32, i32* %
364 // CHECK-NEXT: sdiv i32 %{{.+}}, 1
365 // CHECK-NEXT: store i32 %
366 // CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 1
367 // CHECK-NEXT: load i32*, i32** %
368 // CHECK-NEXT: load i32, i32* %
369 // CHECK-NEXT: bitcast i64* %
370 // CHECK-NEXT: store i32 %{{.+}}, i32* %
371 // CHECK-NEXT: load i64, i64* %
372 // CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 2
373 // CHECK-NEXT: load i32*, i32** %
374 // CHECK-NEXT: load i32, i32* %
375 // CHECK-NEXT: bitcast i64* %
376 // CHECK-NEXT: store i32 %{{.+}}, i32* %
377 // CHECK-NEXT: load i64, i64* %
378 // CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 3
379 // CHECK-NEXT: load i32*, i32** %
380 // CHECK-NEXT: load i32, i32* %
381 // CHECK-NEXT: bitcast i64* %
382 // CHECK-NEXT: store i32 %{{.+}}, i32* %
383 // CHECK-NEXT: load i64, i64* %
384 // CHECK-NEXT: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* @{{.+}}, i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[SS_TY]]*, i64, i64, i64)* [[SS_MICROTASK1:@.+]] to void
385 // CHECK-NEXT: ret void
386 
387 // CHECK: define internal void [[COPY_FUNC]](i8* %0, i8* %1)
388 // CHECK: ret void
389 
390 // CHECK: define internal void [[SS_MICROTASK1]](i32* {{[^,]+}}, i32* {{[^,]+}}, [[SS_TY]]* {{.+}}, i64 {{.+}}, i64 {{.+}}, i64 {{.+}})
391 // Private a
392 // CHECK: alloca i64,
393 // Private b
394 // CHECK: alloca i64,
395 // Private c
396 // CHECK: alloca i64,
397 // CHECK: alloca i32*,
398 // CHECK: alloca i32*,
399 // CHECK: alloca i32*,
400 // CHECK: alloca i32*,
401 // CHECK: [[DID_IT:%.+]] = alloca i32,
402 // CHECK: bitcast i64* %{{.+}} to i32*
403 // CHECK: bitcast i64* %{{.+}} to i32*
404 // CHECK: bitcast i64* %{{.+}} to i32*
405 // CHECK: [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
406 // CHECK-NEXT: icmp ne i32 [[RES]], 0
407 // CHECK-NEXT: br i1
408 
409 // CHECK-NOT: getelementptr inbounds
410 // CHECK: load i32*, i32** %
411 // CHECK-NEXT: load i32, i32* %
412 // CHECK-NEXT: add nsw i32 %{{.+}}, 1
413 // CHECK-NEXT: store i32 %
414 // CHECK-NOT: getelementptr inbounds
415 // CHECK: load i32, i32* %
416 // CHECK-NEXT: add nsw i32 %{{.+}}, -1
417 // CHECK-NEXT: store i32 %
418 // CHECK-NOT: getelementptr inbounds
419 // CHECK: load i32*, i32** %
420 // CHECK-NEXT: load i32, i32* %
421 // CHECK-NEXT: sdiv i32 %{{.+}}, 1
422 // CHECK-NEXT: store i32 %
423 // CHECK-NEXT: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
424 // CHECK-NEXT: store i32 1, i32* [[DID_IT]],
425 // CHECK-NEXT: br label
426 
427 // CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST:%.+]], i64 0, i64 0
428 // CHECK: load i32*, i32** %
429 // CHECK-NEXT: bitcast i32* %
430 // CHECK-NEXT: store i8* %
431 // CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST]], i64 0, i64 1
432 // CHECK-NEXT: bitcast i32* %
433 // CHECK-NEXT: store i8* %
434 // CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST]], i64 0, i64 2
435 // CHECK: load i32*, i32** %
436 // CHECK-NEXT: bitcast i32* %
437 // CHECK-NEXT: store i8* %
438 // CHECK-NEXT: bitcast [3 x i8*]* [[LIST]] to i8*
439 // CHECK-NEXT: load i32, i32* [[DID_IT]],
440 // CHECK-NEXT: call void @__kmpc_copyprivate([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}, i64 24, i8* %{{.+}}, void (i8*, i8*)* [[COPY_FUNC:@[^,]+]], i32 %{{.+}})
441 // CHECK-NEXT:  ret void
442 
443 // CHECK: define internal void [[COPY_FUNC]](i8* %0, i8* %1)
444 // CHECK: ret void
445 
446 // OMP45-LABEL: void @_ZN3SSTIdEC2Ev(
447 // OMP45: getelementptr inbounds [[SST_TY]], [[SST_TY]]* %{{.+}}, i32 0, i32 0
448 // OMP45-NEXT: store double 0.000000e+00, double* %
449 // OMP45-NEXT: getelementptr inbounds [[SST_TY]], [[SST_TY]]* %{{.+}}, i32 0, i32 0
450 // OMP45-NEXT: store double* %{{.+}}, double** %
451 // OMP45-NEXT: load double*, double** %
452 // OMP45-NEXT: load double, double* %
453 // OMP45-NEXT: bitcast i64* %{{.+}} to double*
454 // OMP45-NEXT: store double %{{.+}}, double* %
455 // OMP45-NEXT: load i64, i64* %
456 // OMP45-NEXT: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* @{{.+}}, i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[SST_TY]]*, i64)* [[SST_MICROTASK:@.+]] to void
457 // OMP45-NEXT: ret void
458 
459 // OMP45: define internal void [[SST_MICROTASK]](i32* {{[^,]+}}, i32* {{[^,]+}}, [[SST_TY]]* {{.+}}, i64 {{.+}})
460 // OMP45: [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
461 // OMP45-NEXT: icmp ne i32 [[RES]], 0
462 // OMP45-NEXT: br i1
463 
464 // OMP45: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1
465 // OMP45-NEXT: load double*, double** %
466 // OMP45-NEXT: store double* %
467 // OMP45-LABEL: invoke void @_ZZN3SSTIdEC1EvENKUlvE_clEv(
468 
469 // OMP45: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
470 // OMP45-NEXT: store i32 1, i32* [[DID_IT]],
471 // OMP45-NEXT: br label
472 
473 // OMP45: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
474 // OMP45-NEXT: br label
475 
476 // OMP45: getelementptr inbounds [1 x i8*], [1 x i8*]* [[LIST:%.+]], i64 0, i64 0
477 // OMP45: load double*, double** %
478 // OMP45-NEXT: bitcast double* %
479 // OMP45-NEXT: store i8* %
480 // OMP45-NEXT: bitcast [1 x i8*]* [[LIST]] to i8*
481 // OMP45-NEXT: load i32, i32* [[DID_IT]],
482 // OMP45-NEXT: call void @__kmpc_copyprivate([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}, i64 8, i8* %{{.+}}, void (i8*, i8*)* [[COPY_FUNC:@[^,]+]], i32 %{{.+}})
483 // OMP45-NEXT:  ret void
484 
485 // OMP45-LABEL: @_ZZN3SSTIdEC1EvENKUlvE_clEv(
486 // OMP45: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1
487 // OMP45-NEXT: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1
488 // OMP45-NEXT: load double*, double** %
489 // OMP45-NEXT: store double* %
490 // OMP45-LABEL: call void @_ZZZN3SSTIdEC1EvENKUlvE_clEvENKUlvE_clEv(
491 // OMP45-NEXT: ret void
492 
493 // OMP45: define internal void [[COPY_FUNC]](i8* %0, i8* %1)
494 // OMP45: ret void
495 
496 // OMP45-LABEL: @_ZZZN3SSTIdEC1EvENKUlvE_clEvENKUlvE_clEv(
497