389 lines · cpp
1// RUN: %clang_cc1 -verify -Wno-vla -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s2// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s3// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify -Wno-vla %s -emit-llvm -o - | FileCheck %s4// RUN: %clang_cc1 -verify -Wno-vla -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s5// RUN: %clang_cc1 -verify -Wno-vla -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s6// RUN: %clang_cc1 -verify -Wno-vla -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s7 8// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s9// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s10// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify -Wno-vla %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s11// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s12// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s13// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s14// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}15// expected-no-diagnostics16 17#ifndef ARRAY18#ifndef HEADER19#define HEADER20 21template <class T>22struct S {23 T f;24 S(T a) : f(a) {}25 S() : f() {}26 operator T() { return T(); }27 ~S() {}28};29 30volatile double g;31 32// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { ptr, ptr, i32, %union{{.+}}, %union{{.+}} }33// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }34// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { i8 }35// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]36// CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] }37// CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 }38// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { i8 }39// CHECK-DAG: [[PRIVATES_TMAIN_TY:%.+]] = type { i32, [2 x i32], [2 x [[S_INT_TY]]], [[S_INT_TY]], [104 x i8] }40// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [{{[0-9]+}} x i8], [[PRIVATES_TMAIN_TY]] }41template <typename T>42T tmain() {43 S<T> test;44 T t_var __attribute__((aligned(128))) = T();45 T vec[] = {1, 2};46 S<T> s_arr[] = {1, 2};47 S<T> var(3);48#pragma omp task private(t_var, vec, s_arr, s_arr, var, var)49 {50 vec[0] = t_var;51 s_arr[0] = var;52 }53 return T();54}55 56int main() {57 static int sivar;58#ifdef LAMBDA59 // LAMBDA: [[G:@.+]] ={{.*}} global double60 // LAMBDA-LABEL: @main61 // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](62 [&]() {63 // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](64 // LAMBDA: [[RES:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 56, i64 1, ptr [[TASK_ENTRY:@.+]])65// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i{{.+}} 0, i{{.+}} 166// LAMBDA: call i32 @__kmpc_omp_task(ptr @{{.+}}, i32 %{{.+}}, ptr [[RES]])67// LAMBDA: ret68#pragma omp task private(g, sivar)69 {70 // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]]({{.+}} [[ARG_PTR:%.+]])71 // LAMBDA: store ptr [[ARG_PTR]], ptr [[ARG_PTR_REF:%.+]],72 // LAMBDA: [[ARG_PTR:%.+]] = load ptr, ptr [[ARG_PTR_REF]]73 // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 074 // LAMBDA: [[G_REF:%.+]] = load ptr, ptr [[G_PTR_REF]]75 // LAMBDA: store double 2.0{{.+}}, ptr [[G_REF]]76 // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 177 // LAMBDA: [[SIVAR_REF:%.+]] = load ptr, ptr [[SIVAR_PTR_REF]]78 // LAMBDA: store i{{[0-9]+}} 3, ptr [[SIVAR_REF]]79 80 // LAMBDA: define internal noundef i32 [[TASK_ENTRY]](i32 noundef %0, ptr noalias noundef %1)81 g = 1;82 sivar = 2;83 // LAMBDA: store double 1.0{{.+}}, ptr %{{.+}},84 // LAMBDA: store i{{[0-9]+}} 2, ptr %{{.+}},85 // LAMBDA: call void [[INNER_LAMBDA]]({{.+}}86 // LAMBDA: ret87 [&]() {88 g = 2;89 sivar = 3;90 }();91 }92 }();93 return 0;94#elif defined(BLOCKS)95 // BLOCKS: [[G:@.+]] ={{.*}} global double96 // BLOCKS: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,97 // BLOCKS-LABEL: @main98 // BLOCKS: call void {{%.+}}(ptr99 ^{100 // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(ptr101 // BLOCKS: [[RES:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 56, i64 1, ptr [[TASK_ENTRY:@.+]])102 // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i{{.+}} 0, i{{.+}} 1103 // BLOCKS: call i32 @__kmpc_omp_task(ptr @{{.+}}, i32 %{{.+}}, ptr [[RES]])104 // BLOCKS: ret105#pragma omp task private(g, sivar)106 {107 // BLOCKS: define {{.+}} void {{@.+}}(ptr108 // BLOCKS-NOT: [[G]]{{[[^:word:]]}}109 // BLOCKS: store double 2.0{{.+}}, ptr110 // BLOCKS-NOT: [[G]]{{[[^:word:]]}}111 // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}112 // BLOCKS: store i{{[0-9]+}} 4, ptr113 // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}114 // BLOCKS: ret115 116 // BLOCKS: define internal noundef i32 [[TASK_ENTRY]](i32 noundef %0, ptr noalias noundef %1)117 g = 1;118 sivar = 3;119 // BLOCKS: store double 1.0{{.+}}, ptr %{{.+}},120 // BLOCKS-NOT: [[G]]{{[[^:word:]]}}121 // BLOCKS: store i{{[0-9]+}} 3, ptr %{{.+}},122 // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}123 // BLOCKS: call void {{%.+}}(ptr124 ^{125 g = 2;126 sivar = 4;127 }();128 }129 }();130 return 0;131#else132 S<double> test;133 int t_var = 0;134 int vec[] = {1, 2};135 S<double> s_arr[] = {1, 2};136 S<double> var(3);137#pragma omp task private(var, t_var, s_arr, vec, s_arr, var, sivar)138 {139 vec[0] = t_var;140 s_arr[0] = var;141 sivar = 8;142 }143#pragma omp task144 g+=1;145 return tmain<int>();146#endif147}148 149// CHECK: define{{.*}} i{{[0-9]+}} @main()150// CHECK: [[TEST:%.+]] = alloca [[S_DOUBLE_TY]],151// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32,152// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],153// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]],154// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]],155// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[LOC:@.+]])156 157// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR:@.+]](ptr {{[^,]*}} [[TEST]])158 159// Do not store original variables in capture struct.160// CHECK-NOT: getelementptr inbounds [[CAP_MAIN_TY]],161 162// Allocate task.163// Returns struct kmp_task_t {164// [[KMP_TASK_T_TY]] task_data;165// [[KMP_TASK_MAIN_TY]] privates;166// };167// CHECK: [[RES:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[LOC]], i32 [[GTID]], i32 9, i64 80, i64 1, ptr [[TASK_ENTRY:@[^ ]+]])168 169// CHECK: [[TASK:%.+]] = getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0170// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).171// Also copy address of private copy to the corresponding shareds reference.172// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 1173 174// Constructors for s_arr and var.175// a_arr;176// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0177// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], ptr [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0178// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i{{.+}} 2179// CHECK: call void [[S_DOUBLE_TY_DEF_CONSTR]](ptr {{[^,]*}} [[S_ARR_CUR:%.+]])180// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr [[S_ARR_CUR]], i{{.+}} 1181// CHECK: icmp eq182// CHECK: br i1183 184// var;185// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 1186// CHECK: call void [[S_DOUBLE_TY_DEF_CONSTR]](ptr {{[^,]*}} [[PRIVATE_VAR_REF:%.+]])187 188// Provide pointer to destructor function, which will destroy private variables at the end of the task.189// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds nuw [[KMP_TASK_T_TY]], ptr [[TASK]], i{{.+}} 0, i{{.+}} 3190// CHECK: store ptr [[DESTRUCTORS:@.+]], ptr [[DESTRUCTORS_REF]],191 192// Start task.193// CHECK: call i32 @__kmpc_omp_task(ptr [[LOC]], i32 [[GTID]], ptr [[RES]])194// CHECK: call i32 @__kmpc_omp_task(ptr [[LOC]], i32 [[GTID]], ptr195 196// CHECK: = call noundef i{{.+}} [[TMAIN_INT:@.+]]()197 198// No destructors must be called for private copies of s_arr and var.199// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2200// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3201// CHECK: call void [[S_DOUBLE_TY_DESTR:@.+]](ptr202// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2203// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3204// CHECK: ret205//206 207// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]](ptr noalias noundef %0, ptr noalias noundef %1, ptr noalias noundef %2, ptr noalias noundef %3, ptr noalias noundef %4, ptr noalias noundef %5)208// CHECK: [[PRIVATES:%.+]] = load ptr, ptr209// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 0210// CHECK: [[ARG3:%.+]] = load ptr, ptr %{{.+}},211// CHECK: store ptr [[PRIV_S_VAR]], ptr [[ARG3]],212// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 1213// CHECK: [[ARG1:%.+]] = load ptr, ptr {{.+}},214// CHECK: store ptr [[PRIV_VAR]], ptr [[ARG1]],215// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 2216// CHECK: [[ARG2:%.+]] = load ptr, ptr %{{.+}},217// CHECK: store ptr [[PRIV_T_VAR]], ptr [[ARG2]],218// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 3219// CHECK: [[ARG4:%.+]] = load ptr, ptr %{{.+}},220// CHECK: store ptr [[PRIV_VEC]], ptr [[ARG4]],221// CHECK: ret void222 223// CHECK: define internal noundef i32 [[TASK_ENTRY]](i32 noundef %0, ptr noalias noundef %1)224 225// CHECK: %__context226// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca ptr,227// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca ptr,228// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca ptr,229// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca ptr,230// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca ptr,231// CHECK: store ptr [[PRIVATES_MAP_FN]], ptr [[MAP_FN_ADDR:%.+]],232// CHECK: [[MAP_FN:%.+]] = load ptr, ptr [[MAP_FN_ADDR]],233// CHECK: call void [[MAP_FN]](ptr %{{.+}}, ptr [[PRIV_VAR_ADDR]], ptr [[PRIV_T_VAR_ADDR]], ptr [[PRIV_S_ARR_ADDR]], ptr [[PRIV_VEC_ADDR]], ptr [[PRIV_SIVAR_ADDR]])234// CHECK: [[PRIV_VAR:%.+]] = load ptr, ptr [[PRIV_VAR_ADDR]],235// CHECK: [[PRIV_T_VAR:%.+]] = load ptr, ptr [[PRIV_T_VAR_ADDR]],236// CHECK: [[PRIV_S_ARR:%.+]] = load ptr, ptr [[PRIV_S_ARR_ADDR]],237// CHECK: [[PRIV_VEC:%.+]] = load ptr, ptr [[PRIV_VEC_ADDR]],238// CHECK: [[PRIV_SIVAR:%.+]] = load ptr, ptr [[PRIV_SIVAR_ADDR]],239 240// Privates actually are used.241// CHECK-DAG: [[PRIV_VAR]]242// CHECK-DAG: [[PRIV_T_VAR]]243// CHECK-DAG: [[PRIV_S_ARR]]244// CHECK-DAG: [[PRIV_VEC]]245// CHECK-DAG: [[PRIV_SIVAR]]246 247// CHECK: ret248 249// CHECK: define internal noundef i32 [[DESTRUCTORS]](i32 noundef %0, ptr noalias noundef %1)250// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1251// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 0252// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 1253// CHECK: call void [[S_DOUBLE_TY_DESTR]](ptr {{[^,]*}} [[PRIVATE_VAR_REF]])254// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], ptr [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0255// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i{{.+}} 2256// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i{{.+}} -1257// CHECK: call void [[S_DOUBLE_TY_DESTR]](ptr {{[^,]*}} [[PRIVATE_S_ARR_ELEM_REF]])258// CHECK: icmp eq259// CHECK: br i1260// CHECK: ret i32261 262// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()263// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],264// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32,265// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],266// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]],267// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]],268// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[LOC:@.+]])269 270// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]](ptr {{[^,]*}} [[TEST]])271 272// Do not store original variables in capture struct.273// CHECK-NOT: getelementptr inbounds [[CAP_TMAIN_TY]],274 275// Allocate task.276// Returns struct kmp_task_t {277// [[KMP_TASK_T_TY]] task_data;278// [[KMP_TASK_TMAIN_TY]] privates;279// };280// CHECK: [[RES:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[LOC]], i32 [[GTID]], i32 9, i64 256, i64 1, ptr [[TASK_ENTRY:@[^ ]+]])281 282// CHECK: [[TASK:%.+]] = getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0283 284// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).285// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2286 287// Constructors for s_arr and var.288// a_arr;289// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2290// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], ptr [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0291// CHECK: getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i{{.+}} 2292// CHECK: call void [[S_INT_TY_DEF_CONSTR]](ptr {{[^,]*}} [[S_ARR_CUR:%.+]])293// CHECK: getelementptr inbounds [[S_INT_TY]], ptr [[S_ARR_CUR]], i{{.+}} 1294// CHECK: icmp eq295// CHECK: br i1296 297// var;298// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3299// CHECK: call void [[S_INT_TY_DEF_CONSTR]](ptr {{[^,]*}} [[PRIVATE_VAR_REF:%.+]])300 301// Provide pointer to destructor function, which will destroy private variables at the end of the task.302// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds nuw [[KMP_TASK_T_TY]], ptr [[TASK]], i{{.+}} 0, i{{.+}} 3303// CHECK: store ptr [[DESTRUCTORS:@.+]], ptr [[DESTRUCTORS_REF]],304 305// Start task.306// CHECK: call i32 @__kmpc_omp_task(ptr [[LOC]], i32 [[GTID]], ptr [[RES]])307 308// No destructors must be called for private copies of s_arr and var.309// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2310// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3311// CHECK: call void [[S_INT_TY_DESTR:@.+]](ptr312// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2313// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3314// CHECK: ret315//316 317// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]](ptr noalias noundef %0, ptr noalias noundef %1, ptr noalias noundef %2, ptr noalias noundef %3, ptr noalias noundef %4)318// CHECK: [[PRIVATES:%.+]] = load ptr, ptr319// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 0320// CHECK: [[ARG1:%.+]] = load ptr, ptr %{{.+}},321// CHECK: store ptr [[PRIV_T_VAR]], ptr [[ARG1]],322// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 1323// CHECK: [[ARG2:%.+]] = load ptr, ptr %{{.+}},324// CHECK: store ptr [[PRIV_VEC]], ptr [[ARG2]],325// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 2326// CHECK: [[ARG3:%.+]] = load ptr, ptr %{{.+}},327// CHECK: store ptr [[PRIV_S_VAR]], ptr [[ARG3]],328// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 3329// CHECK: [[ARG4:%.+]] = load ptr, ptr {{.+}},330// CHECK: store ptr [[PRIV_VAR]], ptr [[ARG4]],331// CHECK: ret void332 333// CHECK: define internal noundef i32 [[TASK_ENTRY]](i32 noundef %0, ptr noalias noundef %1)334 335// CHECK: %__context336// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca ptr,337// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca ptr,338// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca ptr,339// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca ptr,340// CHECK: store ptr [[PRIVATES_MAP_FN]], ptr [[MAP_FN_ADDR:%.+]],341// CHECK: [[MAP_FN:%.+]] = load ptr, ptr [[MAP_FN_ADDR]],342// CHECK: call void [[MAP_FN]](ptr %{{.+}}, ptr [[PRIV_T_VAR_ADDR]], ptr [[PRIV_VEC_ADDR]], ptr [[PRIV_S_ARR_ADDR]], ptr [[PRIV_VAR_ADDR]])343// CHECK: [[PRIV_T_VAR:%.+]] = load ptr, ptr [[PRIV_T_VAR_ADDR]],344// CHECK: [[PRIV_VEC:%.+]] = load ptr, ptr [[PRIV_VEC_ADDR]],345// CHECK: [[PRIV_S_ARR:%.+]] = load ptr, ptr [[PRIV_S_ARR_ADDR]],346// CHECK: [[PRIV_VAR:%.+]] = load ptr, ptr [[PRIV_VAR_ADDR]],347 348// Privates actually are used.349// CHECK-DAG: [[PRIV_VAR]]350// CHECK-DAG: [[PRIV_T_VAR]]351// CHECK-DAG: [[PRIV_S_ARR]]352// CHECK-DAG: [[PRIV_VEC]]353 354// CHECK: ret355 356// CHECK: define internal noundef i32 [[DESTRUCTORS]](i32 noundef %0, ptr noalias noundef %1)357// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2358// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2359// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3360// CHECK: call void [[S_INT_TY_DESTR]](ptr {{[^,]*}} [[PRIVATE_VAR_REF]])361// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], ptr [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0362// CHECK: getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i{{.+}} 2363// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i{{.+}} -1364// CHECK: call void [[S_INT_TY_DESTR]](ptr {{[^,]*}} [[PRIVATE_S_ARR_ELEM_REF]])365// CHECK: icmp eq366// CHECK: br i1367// CHECK: ret i32368 369#endif370#else371// ARRAY-LABEL: array_func372struct St {373 int a, b;374 St() : a(0), b(0) {}375 St &operator=(const St &) { return *this; };376 ~St() {}377};378 379void array_func(int n, float a[n], St s[2]) {380// ARRAY: call ptr @__kmpc_omp_task_alloc(381// ARRAY: call i32 @__kmpc_omp_task(382// ARRAY: store ptr %{{.+}}, ptr %{{.+}},383// ARRAY: store ptr %{{.+}}, ptr %{{.+}},384#pragma omp task private(a, s)385 ;386}387#endif388 389