brintos

brintos / llvm-project-archived public Read only

0
0
Text · 20.9 KiB · d9a7132 Raw
431 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{{.+}}, i64, i64, i64, i32, ptr }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 master taskloop private(t_var, vec, s_arr, s_arr, var, var)49  for (int i = 0; i < 10; ++i) {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 96, i64 1, ptr [[TASK_ENTRY:@[^ ]+]])65// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i{{.+}} 0, i{{.+}} 166// LAMBDA: call void @__kmpc_taskloop(ptr @{{.+}}, i32 %{{.+}}, ptr [[RES]], i32 1, ptr %{{.+}}, ptr %{{.+}}, i64 %{{.+}}, i32 1, i32 0, i64 0, ptr null)67// LAMBDA: ret68#pragma omp master taskloop private(g, sivar)69  for (int i = 0; i < 10; ++i) {70    // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](ptr {{[^,]*}} [[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]](ptr86    // 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 96, i64 1, ptr [[TASK_ENTRY:@[^ ]+]])102  // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i{{.+}} 0, i{{.+}} 1103  // BLOCKS: call void @__kmpc_taskloop(ptr @{{.+}}, i32 %{{.+}}, ptr [[RES]], i32 1, ptr %{{.+}}, ptr %{{.+}}, i64 %{{.+}}, i32 1, i32 0, i64 0, ptr null)104  // BLOCKS: ret105#pragma omp master taskloop private(g, sivar)106  for (int i = 0; i < 10; ++i) {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 master taskloop private(var, t_var, s_arr, vec, s_arr, var, sivar)138  for (int i = 0; i < 10; ++i) {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// CHECK:       [[RES:%.+]] = call {{.*}}i32 @__kmpc_master(160// CHECK-NEXT:  [[IS_MASTER:%.+]] = icmp ne i32 [[RES]], 0161// CHECK-NEXT:  br i1 [[IS_MASTER]], label {{%?}}[[THEN:.+]], label {{%?}}[[EXIT:.+]]162// CHECK:       [[THEN]]163// Do not store original variables in capture struct.164// CHECK-NOT: getelementptr inbounds nuw [[CAP_MAIN_TY]],165 166// Allocate task.167// Returns struct kmp_task_t {168//         [[KMP_TASK_T_TY]] task_data;169//         [[KMP_TASK_MAIN_TY]] privates;170//       };171// CHECK: [[RES:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[LOC]], i32 [[GTID]], i32 9, i64 120, i64 1, ptr [[TASK_ENTRY:@[^ ]+]])172 173// CHECK: [[TASK:%.+]] = getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0174// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).175// Also copy address of private copy to the corresponding shareds reference.176// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 1177 178// Constructors for s_arr and var.179// a_arr;180// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0181// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], ptr [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0182// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i{{.+}} 2183// CHECK: call void [[S_DOUBLE_TY_DEF_CONSTR]](ptr {{[^,]*}} [[S_ARR_CUR:%.+]])184// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr [[S_ARR_CUR]], i{{.+}} 1185// CHECK: icmp eq186// CHECK: br i1187 188// var;189// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 1190// CHECK: call void [[S_DOUBLE_TY_DEF_CONSTR]](ptr {{[^,]*}} [[PRIVATE_VAR_REF:%.+]])191 192// Provide pointer to destructor function, which will destroy private variables at the end of the task.193// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds nuw [[KMP_TASK_T_TY]], ptr [[TASK]], i{{.+}} 0, i{{.+}} 3194// CHECK: store ptr [[DESTRUCTORS:@.+]], ptr [[DESTRUCTORS_REF]],195 196// Start task.197// CHECK: call void @__kmpc_taskloop(ptr [[LOC]], i32 [[GTID]], ptr [[RES]], i32 1, ptr %{{.+}}, ptr %{{.+}}, i64 %{{.+}}, i32 1, i32 0, i64 0, ptr [[MAIN_DUP:@.+]])198// CHECK:  call {{.*}}void @__kmpc_end_master(199// CHECK-NEXT:  br label {{%?}}[[EXIT]]200// CHECK:       [[EXIT]]201// CHECK: call i32 @__kmpc_omp_task(ptr [[LOC]], i32 [[GTID]], ptr202 203// CHECK: = call noundef i{{.+}} [[TMAIN_INT:@.+]]()204 205// No destructors must be called for private copies of s_arr and var.206// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2207// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3208// CHECK: call void [[S_DOUBLE_TY_DESTR:@.+]](ptr209// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2210// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3211// CHECK: ret212//213 214// 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)215// CHECK: [[PRIVATES:%.+]] = load ptr, ptr216// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 0217// CHECK: [[ARG3:%.+]] = load ptr, ptr %{{.+}},218// CHECK: store ptr [[PRIV_S_VAR]], ptr [[ARG3]],219// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 1220// CHECK: [[ARG1:%.+]] = load ptr, ptr {{.+}},221// CHECK: store ptr [[PRIV_VAR]], ptr [[ARG1]],222// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 2223// CHECK: [[ARG2:%.+]] = load ptr, ptr %{{.+}},224// CHECK: store ptr [[PRIV_T_VAR]], ptr [[ARG2]],225// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 3226// CHECK: [[ARG4:%.+]] = load ptr, ptr %{{.+}},227// CHECK: store ptr [[PRIV_VEC]], ptr [[ARG4]],228// CHECK: ret void229 230// CHECK: define internal noundef i32 [[TASK_ENTRY]](i32 noundef %0, ptr noalias noundef %1)231 232// CHECK: %__context233// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca ptr,234// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca ptr,235// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca ptr,236// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca ptr,237// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca ptr,238// CHECK: store ptr [[PRIVATES_MAP_FN]], ptr [[MAP_FN_ADDR:%.+]],239// CHECK: [[MAP_FN:%.+]] = load ptr, ptr [[MAP_FN_ADDR]],240// 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]])241// CHECK: [[PRIV_VAR:%.+]] = load ptr, ptr [[PRIV_VAR_ADDR]],242// CHECK: [[PRIV_T_VAR:%.+]] = load ptr, ptr [[PRIV_T_VAR_ADDR]],243// CHECK: [[PRIV_S_ARR:%.+]] = load ptr, ptr [[PRIV_S_ARR_ADDR]],244// CHECK: [[PRIV_VEC:%.+]] = load ptr, ptr [[PRIV_VEC_ADDR]],245// CHECK: [[PRIV_SIVAR:%.+]] = load ptr, ptr [[PRIV_SIVAR_ADDR]],246 247// Privates actually are used.248// CHECK-DAG: [[PRIV_VAR]]249// CHECK-DAG: [[PRIV_T_VAR]]250// CHECK-DAG: [[PRIV_S_ARR]]251// CHECK-DAG: [[PRIV_VEC]]252// CHECK-DAG: [[PRIV_SIVAR]]253 254// CHECK: ret255 256// CHECK: define internal void [[MAIN_DUP]](ptr noundef %0, ptr noundef %1, i32 noundef %2)257// CHECK: getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr %{{.+}}, i32 0, i32 1258// CHECK: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr %{{.+}}, i32 0, i32 0259// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], ptr %{{.+}}, i32 0, i32 0260// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i64 2261// CHECK: br label %262 263// CHECK: phi ptr264// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR]](ptr265// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i64 1266// CHECK: icmp eq ptr %267// CHECK: br i1 %268 269// CHECK: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr %{{.+}}, i32 0, i32 1270// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR]](ptr271// CHECK: ret void272 273// CHECK: define internal noundef i32 [[DESTRUCTORS]](i32 noundef %0, ptr noalias noundef %1)274// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1275// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 0276// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 1277// CHECK: call void [[S_DOUBLE_TY_DESTR]](ptr {{[^,]*}} [[PRIVATE_VAR_REF]])278// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], ptr [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0279// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i{{.+}} 2280// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i{{.+}} -1281// CHECK: call void [[S_DOUBLE_TY_DESTR]](ptr {{[^,]*}} [[PRIVATE_S_ARR_ELEM_REF]])282// CHECK: icmp eq283// CHECK: br i1284// CHECK: ret i32285 286// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()287// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],288// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32,289// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],290// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]],291// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]],292// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[LOC:@.+]])293 294// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]](ptr {{[^,]*}} [[TEST]])295 296// Do not store original variables in capture struct.297// CHECK-NOT: getelementptr inbounds nuw [[CAP_TMAIN_TY]],298 299// Allocate task.300// Returns struct kmp_task_t {301//         [[KMP_TASK_T_TY]] task_data;302//         [[KMP_TASK_TMAIN_TY]] privates;303//       };304// CHECK: [[RES:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[LOC]], i32 [[GTID]], i32 9, i64 256, i64 1, ptr [[TASK_ENTRY:@[^ ]+]])305 306// CHECK: [[TASK:%.+]] = getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0307 308// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).309// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2310 311// Constructors for s_arr and var.312// a_arr;313// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2314// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], ptr [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0315// CHECK: getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i{{.+}} 2316// CHECK: call void [[S_INT_TY_DEF_CONSTR]](ptr {{[^,]*}} [[S_ARR_CUR:%.+]])317// CHECK: getelementptr inbounds [[S_INT_TY]], ptr [[S_ARR_CUR]], i{{.+}} 1318// CHECK: icmp eq319// CHECK: br i1320 321// var;322// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3323// CHECK: call void [[S_INT_TY_DEF_CONSTR]](ptr {{[^,]*}} [[PRIVATE_VAR_REF:%.+]])324 325// Provide pointer to destructor function, which will destroy private variables at the end of the task.326// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds nuw [[KMP_TASK_T_TY]], ptr [[TASK]], i{{.+}} 0, i{{.+}} 3327// CHECK: store ptr [[DESTRUCTORS:@.+]], ptr [[DESTRUCTORS_REF]],328 329// Start task.330// CHECK: call void @__kmpc_taskloop(ptr [[LOC]], i32 [[GTID]], ptr [[RES]], i32 1, ptr %{{.+}}, ptr %{{.+}}, i64 %{{.+}}, i32 1, i32 0, i64 0, ptr [[TMAIN_DUP:@.+]])331 332// No destructors must be called for private copies of s_arr and var.333// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2334// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3335// CHECK: call void [[S_INT_TY_DESTR:@.+]](ptr noundef336// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2337// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3338// CHECK: ret339//340 341// 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)342// CHECK: [[PRIVATES:%.+]] = load ptr, ptr343// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 0344// CHECK: [[ARG1:%.+]] = load ptr, ptr %{{.+}},345// CHECK: store ptr [[PRIV_T_VAR]], ptr [[ARG1]],346// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 1347// CHECK: [[ARG2:%.+]] = load ptr, ptr %{{.+}},348// CHECK: store ptr [[PRIV_VEC]], ptr [[ARG2]],349// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 2350// CHECK: [[ARG3:%.+]] = load ptr, ptr %{{.+}},351// CHECK: store ptr [[PRIV_S_VAR]], ptr [[ARG3]],352// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 3353// CHECK: [[ARG4:%.+]] = load ptr, ptr {{.+}},354// CHECK: store ptr [[PRIV_VAR]], ptr [[ARG4]],355// CHECK: ret void356 357// CHECK: define internal noundef i32 [[TASK_ENTRY]](i32 noundef %0, ptr noalias noundef %1)358 359// CHECK: %__context360// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca ptr,361// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca ptr,362// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca ptr,363// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca ptr,364// CHECK: store ptr [[PRIVATES_MAP_FN]], ptr [[MAP_FN_ADDR:%.+]],365// CHECK: [[MAP_FN:%.+]] = load ptr, ptr [[MAP_FN_ADDR]],366// CHECK: call void [[MAP_FN]](ptr %{{.+}}, ptr [[PRIV_T_VAR_ADDR]], ptr [[PRIV_VEC_ADDR]], ptr [[PRIV_S_ARR_ADDR]], ptr [[PRIV_VAR_ADDR]])367// CHECK: [[PRIV_T_VAR:%.+]] = load ptr, ptr [[PRIV_T_VAR_ADDR]],368// CHECK: [[PRIV_VEC:%.+]] = load ptr, ptr [[PRIV_VEC_ADDR]],369// CHECK: [[PRIV_S_ARR:%.+]] = load ptr, ptr [[PRIV_S_ARR_ADDR]],370// CHECK: [[PRIV_VAR:%.+]] = load ptr, ptr [[PRIV_VAR_ADDR]],371 372// Privates actually are used.373// CHECK-DAG: [[PRIV_VAR]]374// CHECK-DAG: [[PRIV_T_VAR]]375// CHECK-DAG: [[PRIV_S_ARR]]376// CHECK-DAG: [[PRIV_VEC]]377 378// CHECK: ret379 380// CHECK: define internal void [[TMAIN_DUP]](ptr noundef %0, ptr noundef %1, i32 noundef %2)381// CHECK: getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr %{{.+}}, i32 0, i32 2382// CHECK: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr %{{.+}}, i32 0, i32 2383// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], ptr %{{.+}}, i32 0, i32 0384// CHECK: getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i64 2385// CHECK: br label %386 387// CHECK: phi ptr388// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]](ptr389// CHECK: getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i64 1390// CHECK: icmp eq ptr %391// CHECK: br i1 %392 393// CHECK: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr %{{.+}}, i32 0, i32 3394// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]](ptr395// CHECK: ret void396 397// CHECK: define internal noundef i32 [[DESTRUCTORS]](i32 noundef %0, ptr noalias noundef %1)398// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2399// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2400// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3401// CHECK: call void [[S_INT_TY_DESTR]](ptr {{[^,]*}} [[PRIVATE_VAR_REF]])402// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], ptr [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0403// CHECK: getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i{{.+}} 2404// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i{{.+}} -1405// CHECK: call void [[S_INT_TY_DESTR]](ptr {{[^,]*}} [[PRIVATE_S_ARR_ELEM_REF]])406// CHECK: icmp eq407// CHECK: br i1408// CHECK: ret i32409 410#endif411#else412// ARRAY-LABEL: array_func413struct St {414  int a, b;415  St() : a(0), b(0) {}416  St &operator=(const St &) { return *this; };417  ~St() {}418};419 420void array_func(int n, float a[n], St s[2]) {421// ARRAY: call ptr @__kmpc_omp_task_alloc(422// ARRAY: call void @__kmpc_taskloop(423// ARRAY: store ptr %{{.+}}, ptr %{{.+}},424// ARRAY: store ptr %{{.+}}, ptr %{{.+}},425#pragma omp master taskloop private(a, s)426  for (int i = 0; i < 10; ++i)427    ;428}429#endif430 431