1 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s 2 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s 3 // RUN: %clang_cc1 -fopenmp -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s 4 // RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s 5 // RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s 6 // 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 7 // expected-no-diagnostics 8 #ifndef ARRAY 9 #ifndef HEADER 10 #define HEADER 11 12 volatile int g = 1212; 13 #pragma omp threadprivate(g) 14 15 template <class T> 16 struct S { 17 T f; 18 S(T a) : f(a + g) {} 19 S() : f(g) {} 20 S &operator=(const S &) { return *this; }; 21 operator T() { return T(); } 22 ~S() {} 23 }; 24 25 // CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float } 26 // CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } 27 // CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* 28 29 30 // CHECK-DAG: [[T_VAR:@.+]] = internal global i{{[0-9]+}} 1122, 31 // CHECK-DAG: [[VEC:@.+]] = internal global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 1, i{{[0-9]+}} 2], 32 // CHECK-DAG: [[S_ARR:@.+]] = internal global [2 x [[S_FLOAT_TY]]] zeroinitializer, 33 // CHECK-DAG: [[VAR:@.+]] = internal global [[S_FLOAT_TY]] zeroinitializer, 34 // CHECK-DAG: [[TMAIN_T_VAR:@.+]] = linkonce_odr global i{{[0-9]+}} 333, 35 // CHECK-DAG: [[TMAIN_VEC:@.+]] = linkonce_odr global [2 x i{{[0-9]+}}] [i{{[0-9]+}} 3, i{{[0-9]+}} 3], 36 // CHECK-DAG: [[TMAIN_S_ARR:@.+]] = linkonce_odr global [2 x [[S_INT_TY]]] zeroinitializer, 37 // CHECK-DAG: [[TMAIN_VAR:@.+]] = linkonce_odr global [[S_INT_TY]] zeroinitializer, 38 template <typename T> 39 T tmain() { 40 S<T> test; 41 test = S<T>(); 42 static T t_var = 333; 43 static T vec[] = {3, 3}; 44 static S<T> s_arr[] = {1, 2}; 45 static S<T> var(3); 46 #pragma omp threadprivate(t_var, vec, s_arr, var) 47 #pragma omp parallel copyin(t_var, vec, s_arr, var) 48 { 49 vec[0] = t_var; 50 s_arr[0] = var; 51 } 52 #pragma omp parallel copyin(t_var) 53 {} 54 return T(); 55 } 56 57 int main() { 58 #ifdef LAMBDA 59 // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, 60 // LAMBDA-LABEL: @main 61 // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]]( 62 [&]() { 63 // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( 64 // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* 65 #pragma omp parallel copyin(g) 66 { 67 // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) 68 69 // threadprivate_g = g; 70 // LAMBDA: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[G]] 71 // LAMBDA: ptrtoint i{{[0-9]+}}* %{{.+}} to i{{[0-9]+}} 72 // LAMBDA: icmp ne i{{[0-9]+}} ptrtoint (i{{[0-9]+}}* [[G]] to i{{[0-9]+}}), %{{.+}} 73 // LAMBDA: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] 74 // LAMBDA: [[NOT_MASTER]] 75 // LAMBDA: load i{{[0-9]+}}, i{{[0-9]+}}* [[G]], 76 // LAMBDA: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, 77 // LAMBDA: [[DONE]] 78 79 // LAMBDA: call {{.*}}i32 @__kmpc_cancel_barrier( 80 g = 1; 81 // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* 82 [&]() { 83 // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) 84 // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], 85 g = 2; 86 // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] 87 }(); 88 } 89 }(); 90 return 0; 91 #elif defined(BLOCKS) 92 // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, 93 // BLOCKS-LABEL: @main 94 // BLOCKS: call {{.*}}void {{%.+}}(i8 95 ^{ 96 // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* 97 // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* 98 #pragma omp parallel copyin(g) 99 { 100 // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) 101 102 // threadprivate_g = g; 103 // BLOCKS: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[G]] 104 // BLOCKS: ptrtoint i{{[0-9]+}}* %{{.+}} to i{{[0-9]+}} 105 // BLOCKS: icmp ne i{{[0-9]+}} ptrtoint (i{{[0-9]+}}* [[G]] to i{{[0-9]+}}), %{{.+}} 106 // BLOCKS: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] 107 // BLOCKS: [[NOT_MASTER]] 108 // BLOCKS: load i{{[0-9]+}}, i{{[0-9]+}}* [[G]], 109 // BLOCKS: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, 110 // BLOCKS: [[DONE]] 111 112 // BLOCKS: call {{.*}}i32 @__kmpc_cancel_barrier( 113 g = 1; 114 // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* 115 // BLOCKS-NOT: [[G]]{{[[^:word:]]}} 116 // BLOCKS: call {{.*}}void {{%.+}}(i8 117 ^{ 118 // BLOCKS: define {{.+}} void {{@.+}}(i8* 119 g = 2; 120 // BLOCKS-NOT: [[G]]{{[[^:word:]]}} 121 // BLOCKS: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[G]] 122 // BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* 123 // BLOCKS-NOT: [[G]]{{[[^:word:]]}} 124 // BLOCKS: ret 125 }(); 126 } 127 }(); 128 return 0; 129 #else 130 S<float> test; 131 test = S<float>(); 132 static int t_var = 1122; 133 static int vec[] = {1, 2}; 134 static S<float> s_arr[] = {1, 2}; 135 static S<float> var(3); 136 #pragma omp threadprivate(t_var, vec, s_arr, var) 137 #pragma omp parallel copyin(t_var, vec, s_arr, var) 138 { 139 vec[0] = t_var; 140 s_arr[0] = var; 141 } 142 #pragma omp parallel copyin(t_var) 143 {} 144 return tmain<int>(); 145 #endif 146 } 147 148 // CHECK-LABEL: @main 149 // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], 150 // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN:@.+]]([[S_FLOAT_TY]]* [[TEST]], [[S_FLOAT_TY]]* 151 // 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]+}}*, {{%.+}}*)* [[MAIN_MICROTASK:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) 152 // 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]+}}*, {{%.+}}*)* [[MAIN_MICROTASK1:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) 153 // CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() 154 // CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* 155 // CHECK: ret 156 // 157 // CHECK: define internal {{.*}}void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) 158 // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], 159 // CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], 160 // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], 161 162 // threadprivate_t_var = t_var; 163 // CHECK: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[T_VAR]] 164 // CHECK: ptrtoint i{{[0-9]+}}* %{{.+}} to i{{[0-9]+}} 165 // CHECK: icmp ne i{{[0-9]+}} ptrtoint (i{{[0-9]+}}* [[T_VAR]] to i{{[0-9]+}}), %{{.+}} 166 // CHECK: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] 167 // CHECK: [[NOT_MASTER]] 168 // CHECK: load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR]], 169 // CHECK: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, 170 171 // threadprivate_vec = vec; 172 // CHECK: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[VEC]] 173 // CHECK: call void @llvm.memcpy{{.*}}(i8* %{{.+}}, i8* bitcast ([2 x i{{[0-9]+}}]* [[VEC]] to i8*), 174 175 // threadprivate_s_arr = s_arr; 176 // CHECK: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[S_ARR]] 177 // CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* {{%.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 178 // CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2 179 // CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]] 180 // CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] 181 // CHECK: [[S_ARR_BODY]] 182 // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN]]([[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}) 183 // CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] 184 185 // threadprivate_var = var; 186 // CHECK: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[VAR]] 187 // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN]]([[S_FLOAT_TY]]* {{%.+}}, [[S_FLOAT_TY]]* {{.*}}[[VAR]]) 188 // CHECK: [[DONE]] 189 190 // CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) 191 // CHECK: ret void 192 193 // CHECK: define internal {{.*}}void [[MAIN_MICROTASK1]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) 194 // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], 195 // CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], 196 // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], 197 198 // threadprivate_t_var = t_var; 199 // CHECK: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[T_VAR]] 200 // CHECK: ptrtoint i{{[0-9]+}}* %{{.+}} to i{{[0-9]+}} 201 // CHECK: icmp ne i{{[0-9]+}} ptrtoint (i{{[0-9]+}}* [[T_VAR]] to i{{[0-9]+}}), %{{.+}} 202 // CHECK: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] 203 // CHECK: [[NOT_MASTER]] 204 // CHECK: load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR]], 205 // CHECK: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, 206 // CHECK: [[DONE]] 207 208 // CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) 209 // CHECK: ret void 210 211 // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() 212 // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], 213 // CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN:@.+]]([[S_INT_TY]]* [[TEST]], [[S_INT_TY]]* 214 // 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]+}}*, {{%.+}}*)* [[TMAIN_MICROTASK:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) 215 // 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]+}}*, {{%.+}}*)* [[TMAIN_MICROTASK1:@.+]] to void (i32*, i32*, ...)*), i8* %{{.+}}) 216 // CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* 217 // CHECK: ret 218 // 219 // CHECK: define internal {{.*}}void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) 220 // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], 221 // CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], 222 // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], 223 224 // threadprivate_t_var = t_var; 225 // CHECK: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[TMAIN_T_VAR]] 226 // CHECK: ptrtoint i{{[0-9]+}}* %{{.+}} to i{{[0-9]+}} 227 // CHECK: icmp ne i{{[0-9]+}} ptrtoint (i{{[0-9]+}}* [[TMAIN_T_VAR]] to i{{[0-9]+}}), %{{.+}} 228 // CHECK: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] 229 // CHECK: [[NOT_MASTER]] 230 // CHECK: load i{{[0-9]+}}, i{{[0-9]+}}* [[TMAIN_T_VAR]], 231 // CHECK: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, 232 233 // threadprivate_vec = vec; 234 // CHECK: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[TMAIN_VEC]] 235 // CHECK: call {{.*}}void @llvm.memcpy{{.*}}(i8* %{{.+}}, i8* bitcast ([2 x i{{[0-9]+}}]* [[TMAIN_VEC]] to i8*), 236 237 // threadprivate_s_arr = s_arr; 238 // CHECK: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[TMAIN_S_ARR]] 239 // CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* {{%.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 240 // CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2 241 // CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]] 242 // CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] 243 // CHECK: [[S_ARR_BODY]] 244 // CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN]]([[S_INT_TY]]* {{.+}}, [[S_INT_TY]]* {{.+}}) 245 // CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] 246 247 // threadprivate_var = var; 248 // CHECK: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[TMAIN_VAR]] 249 // CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN]]([[S_INT_TY]]* {{%.+}}, [[S_INT_TY]]* {{.*}}[[TMAIN_VAR]]) 250 // CHECK: [[DONE]] 251 252 // CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) 253 // CHECK: ret void 254 255 // CHECK: define internal {{.*}}void [[TMAIN_MICROTASK1]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, {{%.+}}* %{{.+}}) 256 // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], 257 // CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], 258 // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]], 259 260 // threadprivate_t_var = t_var; 261 // CHECK: call {{.*}}i8* @__kmpc_threadprivate_cached({{.+}} [[TMAIN_T_VAR]] 262 // CHECK: ptrtoint i{{[0-9]+}}* %{{.+}} to i{{[0-9]+}} 263 // CHECK: icmp ne i{{[0-9]+}} ptrtoint (i{{[0-9]+}}* [[TMAIN_T_VAR]] to i{{[0-9]+}}), %{{.+}} 264 // CHECK: br i1 %{{.+}}, label %[[NOT_MASTER:.+]], label %[[DONE:.+]] 265 // CHECK: [[NOT_MASTER]] 266 // CHECK: load i{{[0-9]+}}, i{{[0-9]+}}* [[TMAIN_T_VAR]], 267 // CHECK: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* %{{.+}}, 268 // CHECK: [[DONE]] 269 270 // CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]]) 271 // CHECK: ret void 272 273 #endif 274 #else 275 // ARRAY-LABEL: array_func 276 struct St { 277 int a, b; 278 St() : a(0), b(0) {} 279 St &operator=(const St &) { return *this; }; 280 ~St() {} 281 }; 282 283 void array_func() { 284 static int a[2]; 285 static St s[2]; 286 // ARRAY: @__kmpc_fork_call( 287 // ARRAY: call i8* @__kmpc_threadprivate_cached( 288 // ARRAY: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.+}}, i8* bitcast ([2 x i32]* @{{.+}} to i8*), i64 8, i32 4, i1 false) 289 // ARRAY: call dereferenceable(8) %struct.St* @{{.+}}(%struct.St* %{{.+}}, %struct.St* dereferenceable(8) %{{.+}}) 290 #pragma omp threadprivate(a, s) 291 #pragma omp parallel copyin(a, s) 292 ; 293 } 294 #endif 295 296 297