brintos

brintos / llvm-project-archived public Read only

0
0
Text · 20.1 KiB · 410892c Raw
417 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 parallel 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 parallel 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 parallel 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 parallel 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 156// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR:@.+]](ptr {{[^,]*}} [[TEST]])157 158// CHECK:       [[RES:%.+]] = call {{.*}}i32 @__kmpc_master(159// CHECK-NEXT:  [[IS_MASTER:%.+]] = icmp ne i32 [[RES]], 0160// CHECK-NEXT:  br i1 [[IS_MASTER]], label {{%?}}[[THEN:.+]], label {{%?}}[[EXIT:.+]]161// CHECK:       [[THEN]]162// Do not store original variables in capture struct.163// CHECK-NOT: getelementptr inbounds nuw [[CAP_MAIN_TY]],164 165// Allocate task.166// Returns struct kmp_task_t {167//         [[KMP_TASK_T_TY]] task_data;168//         [[KMP_TASK_MAIN_TY]] privates;169//       };170// CHECK: [[RES:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[LOC:@.+]], i32 [[GTID:%.+]], i32 9, i64 120, i64 1, ptr [[TASK_ENTRY:@[^ ]+]])171 172// CHECK: [[TASK:%.+]] = getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0173// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).174// Also copy address of private copy to the corresponding shareds reference.175// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 1176 177// Constructors for s_arr and var.178// a_arr;179// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0180// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], ptr [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0181// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i{{.+}} 2182// CHECK: call void [[S_DOUBLE_TY_DEF_CONSTR]](ptr {{[^,]*}} [[S_ARR_CUR:%.+]])183// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr [[S_ARR_CUR]], i{{.+}} 1184// CHECK: icmp eq185// CHECK: br i1186 187// var;188// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 1189// CHECK: call void [[S_DOUBLE_TY_DEF_CONSTR]](ptr {{[^,]*}} [[PRIVATE_VAR_REF:%.+]])190 191// Provide pointer to destructor function, which will destroy private variables at the end of the task.192// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds nuw [[KMP_TASK_T_TY]], ptr [[TASK]], i{{.+}} 0, i{{.+}} 3193// CHECK: store ptr [[DESTRUCTORS:@.+]], ptr [[DESTRUCTORS_REF]],194 195// Start task.196// 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:@.+]])197// CHECK:  call {{.*}}void @__kmpc_end_master(198// CHECK-NEXT:  br label {{%?}}[[EXIT]]199// CHECK:       [[EXIT]]200 201// No destructors must be called for private copies of s_arr and var.202// 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//205 206// 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)207// CHECK: [[PRIVATES:%.+]] = load ptr, ptr208// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 0209// CHECK: [[ARG3:%.+]] = load ptr, ptr %{{.+}},210// CHECK: store ptr [[PRIV_S_VAR]], ptr [[ARG3]],211// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 1212// CHECK: [[ARG1:%.+]] = load ptr, ptr {{.+}},213// CHECK: store ptr [[PRIV_VAR]], ptr [[ARG1]],214// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 2215// CHECK: [[ARG2:%.+]] = load ptr, ptr %{{.+}},216// CHECK: store ptr [[PRIV_T_VAR]], ptr [[ARG2]],217// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 3218// CHECK: [[ARG4:%.+]] = load ptr, ptr %{{.+}},219// CHECK: store ptr [[PRIV_VEC]], ptr [[ARG4]],220// CHECK: ret void221 222// CHECK: define internal noundef i32 [[TASK_ENTRY]](i32 noundef %0, ptr noalias noundef %1)223 224// CHECK: %__context225// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca ptr,226// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca ptr,227// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca ptr,228// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca ptr,229// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca ptr,230// CHECK: store ptr [[PRIVATES_MAP_FN]], ptr [[MAP_FN_ADDR:%.+]],231// CHECK: [[MAP_FN:%.+]] = load ptr, ptr [[MAP_FN_ADDR]],232// 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]])233// CHECK: [[PRIV_VAR:%.+]] = load ptr, ptr [[PRIV_VAR_ADDR]],234// CHECK: [[PRIV_T_VAR:%.+]] = load ptr, ptr [[PRIV_T_VAR_ADDR]],235// CHECK: [[PRIV_S_ARR:%.+]] = load ptr, ptr [[PRIV_S_ARR_ADDR]],236// CHECK: [[PRIV_VEC:%.+]] = load ptr, ptr [[PRIV_VEC_ADDR]],237// CHECK: [[PRIV_SIVAR:%.+]] = load ptr, ptr [[PRIV_SIVAR_ADDR]],238 239// Privates actually are used.240// CHECK-DAG: [[PRIV_VAR]]241// CHECK-DAG: [[PRIV_T_VAR]]242// CHECK-DAG: [[PRIV_S_ARR]]243// CHECK-DAG: [[PRIV_VEC]]244// CHECK-DAG: [[PRIV_SIVAR]]245 246// CHECK: ret247 248// CHECK: define internal void [[MAIN_DUP]](ptr noundef %0, ptr noundef %1, i32 noundef %2)249// CHECK: getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr %{{.+}}, i32 0, i32 1250// CHECK: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr %{{.+}}, i32 0, i32 0251// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], ptr %{{.+}}, i32 0, i32 0252// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i64 2253// CHECK: br label %254 255// CHECK: phi ptr256// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR]](ptr257// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i64 1258// CHECK: icmp eq ptr %259// CHECK: br i1 %260 261// CHECK: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr %{{.+}}, i32 0, i32 1262// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR]](ptr263// CHECK: ret void264 265// CHECK: define internal noundef i32 [[DESTRUCTORS]](i32 noundef %0, ptr noalias noundef %1)266// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1267// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 0268// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 1269// CHECK: call void @_ZN1SIdED1Ev(ptr {{[^,]*}} [[PRIVATE_VAR_REF]])270// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], ptr [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0271// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i{{.+}} 2272// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i{{.+}} -1273// CHECK: call void @_ZN1SIdED1Ev(ptr {{[^,]*}} [[PRIVATE_S_ARR_ELEM_REF]])274// CHECK: icmp eq275// CHECK: br i1276// CHECK: ret i32277 278// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],279// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32,280// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],281// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]],282// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]],283 284// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]](ptr {{[^,]*}} [[TEST]])285 286// Do not store original variables in capture struct.287// CHECK-NOT: getelementptr inbounds nuw [[CAP_TMAIN_TY]],288 289// Allocate task.290// Returns struct kmp_task_t {291//         [[KMP_TASK_T_TY]] task_data;292//         [[KMP_TASK_TMAIN_TY]] privates;293//       };294// CHECK: [[RES:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[LOC]], i32 [[GTID:%.+]], i32 9, i64 256, i64 1, ptr [[TASK_ENTRY:@[^ ]+]])295 296// CHECK: [[TASK:%.+]] = getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0297 298// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).299// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2300 301// Constructors for s_arr and var.302// a_arr;303// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2304// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], ptr [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0305// CHECK: getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i{{.+}} 2306// CHECK: call void [[S_INT_TY_DEF_CONSTR]](ptr {{[^,]*}} [[S_ARR_CUR:%.+]])307// CHECK: getelementptr inbounds [[S_INT_TY]], ptr [[S_ARR_CUR]], i{{.+}} 1308// CHECK: icmp eq309// CHECK: br i1310 311// var;312// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3313// CHECK: call void [[S_INT_TY_DEF_CONSTR]](ptr {{[^,]*}} [[PRIVATE_VAR_REF:%.+]])314 315// Provide pointer to destructor function, which will destroy private variables at the end of the task.316// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds nuw [[KMP_TASK_T_TY]], ptr [[TASK]], i{{.+}} 0, i{{.+}} 3317// CHECK: store ptr [[DESTRUCTORS:@.+]], ptr [[DESTRUCTORS_REF]],318 319// Start task.320// 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:@.+]])321 322// No destructors must be called for private copies of s_arr and var.323// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2324// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3325//326 327// 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)328// CHECK: [[PRIVATES:%.+]] = load ptr, ptr329// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 0330// CHECK: [[ARG1:%.+]] = load ptr, ptr %{{.+}},331// CHECK: store ptr [[PRIV_T_VAR]], ptr [[ARG1]],332// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 1333// CHECK: [[ARG2:%.+]] = load ptr, ptr %{{.+}},334// CHECK: store ptr [[PRIV_VEC]], ptr [[ARG2]],335// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 2336// CHECK: [[ARG3:%.+]] = load ptr, ptr %{{.+}},337// CHECK: store ptr [[PRIV_S_VAR]], ptr [[ARG3]],338// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 3339// CHECK: [[ARG4:%.+]] = load ptr, ptr {{.+}},340// CHECK: store ptr [[PRIV_VAR]], ptr [[ARG4]],341// CHECK: ret void342 343// CHECK: define internal noundef i32 [[TASK_ENTRY]](i32 noundef %0, ptr noalias noundef %1)344 345// CHECK: %__context346// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca ptr,347// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca ptr,348// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca ptr,349// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca ptr,350// CHECK: store ptr [[PRIVATES_MAP_FN]], ptr [[MAP_FN_ADDR:%.+]],351// CHECK: [[MAP_FN:%.+]] = load ptr, ptr [[MAP_FN_ADDR]],352// CHECK: call void [[MAP_FN]](ptr %{{.+}}, ptr [[PRIV_T_VAR_ADDR]], ptr [[PRIV_VEC_ADDR]], ptr [[PRIV_S_ARR_ADDR]], ptr [[PRIV_VAR_ADDR]])353// CHECK: [[PRIV_T_VAR:%.+]] = load ptr, ptr [[PRIV_T_VAR_ADDR]],354// CHECK: [[PRIV_VEC:%.+]] = load ptr, ptr [[PRIV_VEC_ADDR]],355// CHECK: [[PRIV_S_ARR:%.+]] = load ptr, ptr [[PRIV_S_ARR_ADDR]],356// CHECK: [[PRIV_VAR:%.+]] = load ptr, ptr [[PRIV_VAR_ADDR]],357 358// Privates actually are used.359// CHECK-DAG: [[PRIV_VAR]]360// CHECK-DAG: [[PRIV_T_VAR]]361// CHECK-DAG: [[PRIV_S_ARR]]362// CHECK-DAG: [[PRIV_VEC]]363 364// CHECK: ret365 366// CHECK: define internal void [[TMAIN_DUP]](ptr noundef %0, ptr noundef %1, i32 noundef %2)367// CHECK: getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr %{{.+}}, i32 0, i32 2368// CHECK: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr %{{.+}}, i32 0, i32 2369// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], ptr %{{.+}}, i32 0, i32 0370// CHECK: getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i64 2371// CHECK: br label %372 373// CHECK: phi ptr374// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]](ptr375// CHECK: getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i64 1376// CHECK: icmp eq ptr %377// CHECK: br i1 %378 379// CHECK: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr %{{.+}}, i32 0, i32 3380// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]](ptr381// CHECK: ret void382 383// CHECK: define internal noundef i32 [[DESTRUCTORS]](i32 noundef %0, ptr noalias noundef %1)384// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2385// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2386// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3387// CHECK: call void @_ZN1SIiED1Ev(ptr {{[^,]*}} [[PRIVATE_VAR_REF]])388// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], ptr [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0389// CHECK: getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i{{.+}} 2390// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i{{.+}} -1391// CHECK: call void @_ZN1SIiED1Ev(ptr {{[^,]*}} [[PRIVATE_S_ARR_ELEM_REF]])392// CHECK: icmp eq393// CHECK: br i1394// CHECK: ret i32395 396#endif397#else398// ARRAY-LABEL: array_func399struct St {400  int a, b;401  St() : a(0), b(0) {}402  St &operator=(const St &) { return *this; };403  ~St() {}404};405 406void array_func(int n, float a[n], St s[2]) {407// ARRAY: call ptr @__kmpc_omp_task_alloc(408// ARRAY: call void @__kmpc_taskloop(409// ARRAY: store ptr %{{.+}}, ptr %{{.+}},410// ARRAY: store ptr %{{.+}}, ptr %{{.+}},411#pragma omp parallel master taskloop private(a, s)412  for (int i = 0; i < 10; ++i)413    ;414}415#endif416 417