brintos

brintos / llvm-project-archived public Read only

0
0
Text · 25.5 KiB · 58384d8 Raw
532 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// RUN: %clang_cc1 -verify -Wno-vla -fopenmp -x c++ -std=c++11 -DLOOP -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LOOP %s8 9// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s10// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s11// 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 %s12// 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 %s13// 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 %s14// 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 %s15// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd -x c++ -std=c++11 -DLOOP -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=SIMD-ONLY0 %s16// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}17// expected-no-diagnostics18 19#if !defined(ARRAY) && !defined(LOOP)20#ifndef HEADER21#define HEADER22 23template <class T>24struct S {25  T f;26  S(T a) : f(a) {}27  S() : f() {}28  S(const S &s, T t = T()) : f(s.f + t) {}29  operator T() { return T(); }30  ~S() {}31};32 33volatile double g;34 35// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { ptr, ptr, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32, ptr }36// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }37// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]38// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { ptr, ptr, ptr, ptr, ptr }39// CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] }40// CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 }41// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { ptr, ptr, ptr, ptr }42// CHECK-DAG: [[PRIVATES_TMAIN_TY:%.+]] = type { i32, [2 x i32], [2 x [[S_INT_TY]]], [[S_INT_TY]], [104 x i8] }43// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [{{[0-9]+}} x i8], [[PRIVATES_TMAIN_TY]] }44template <typename T>45T tmain() {46  S<T> ttt;47  S<T> test;48  T t_var __attribute__((aligned(128))) = T();49  T vec[] = {1, 2};50  S<T> s_arr[] = {1, 2};51  S<T> var(3);52#pragma omp master taskloop lastprivate(t_var, vec, s_arr, s_arr, var, var)53  for (int i = 0; i < 10; ++i) {54    vec[0] = t_var;55    s_arr[0] = var;56  }57  return T();58}59 60int main() {61  static int sivar;62#ifdef LAMBDA63  // LAMBDA: [[G:@.+]] ={{.*}} global double64  // LAMBDA: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,65  // LAMBDA-LABEL: @main66  // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](67  [&]() {68  // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](69  // LAMBDA: [[RES:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 96, i64 16, ptr [[TASK_ENTRY:@[^ ]+]])70// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i{{.+}} 0, i{{.+}} 171 72// LAMBDA: call void @__kmpc_taskloop(ptr @{{.+}}, i32 %{{.+}}, ptr [[RES]], i32 1, ptr %{{.+}}, ptr %{{.+}}, i64 %{{.+}}, i32 1, i32 0, i64 0, ptr [[MAIN_DUP:@.+]])73// LAMBDA: ret74#pragma omp master taskloop lastprivate(g, sivar)75  for (int i = 0; i < 10; ++i) {76    // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]]({{.+}} [[ARG_PTR:%.+]])77    // LAMBDA: store ptr [[ARG_PTR]], ptr [[ARG_PTR_REF:%.+]],78    // LAMBDA: [[ARG_PTR:%.+]] = load ptr, ptr [[ARG_PTR_REF]]79    // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 080    // LAMBDA: [[G_REF:%.+]] = load ptr, ptr [[G_PTR_REF]]81    // LAMBDA: store double 2.0{{.+}}, ptr [[G_REF]]82 83    // LAMBDA: store ptr %{{.+}}, ptr %{{.+}},84    // LAMBDA: define internal noundef i32 [[TASK_ENTRY]](i32 noundef %0, ptr noalias noundef %1)85    g = 1;86    sivar = 11;87    // LAMBDA: store double 1.0{{.+}}, ptr %{{.+}},88    // LAMBDA: store i{{[0-9]+}} 11, ptr %{{.+}},89    // LAMBDA: call void [[INNER_LAMBDA]]({{.+}}90    // LAMBDA: icmp ne i32 %{{.+}}, 091    // LAMBDA: br i192    // LAMBDA: load double, ptr %93    // LAMBDA: store volatile double %94    // LAMBDA: load i32, ptr %95    // LAMBDA: store i32 %96    // LAMBDA: ret97    [&]() {98      g = 2;99      sivar = 22;100    }();101  }102  }();103  return 0;104#elif defined(BLOCKS)105  // BLOCKS: [[G:@.+]] ={{.*}} global double106  // BLOCKS: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,107  // BLOCKS-LABEL: @main108  // BLOCKS: call void {{%.+}}(ptr109  ^{110  // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(ptr111  // BLOCKS: [[RES:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 96, i64 16, ptr [[TASK_ENTRY:@[^ ]+]])112  // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i{{.+}} 0, i{{.+}} 1113  // BLOCKS: call void @__kmpc_taskloop(ptr @{{.+}}, i32 %{{.+}}, ptr [[RES]], i32 1, ptr %{{.+}}, ptr %{{.+}}, i64 %{{.+}}, i32 1, i32 0, i64 0, ptr [[MAIN_DUP:@.+]])114  // BLOCKS: ret115#pragma omp master taskloop lastprivate(g, sivar)116  for (int i = 0; i < 10; ++i) {117    // BLOCKS: define {{.+}} void {{@.+}}(ptr118    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}119    // BLOCKS: store double 2.0{{.+}}, ptr120    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}121    // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}122    // BLOCKS: store i{{[0-9]+}} 22, ptr123    // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}124    // BLOCKS: ret125 126    // BLOCKS: store ptr %{{.+}}, ptr %{{.+}},127    // BLOCKS: store ptr %{{.+}}, ptr %{{.+}},128    // BLOCKS: define internal noundef i32 [[TASK_ENTRY]](i32 noundef %0, ptr noalias noundef %1)129    g = 1;130    sivar = 11;131    // BLOCKS: store double 1.0{{.+}}, ptr %{{.+}},132    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}133    // BLOCKS: store i{{[0-9]+}} 11, ptr %{{.+}},134    // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}135    // BLOCKS: call void {{%.+}}(ptr136    // BLOCKS: icmp ne i32 %{{.+}}, 0137    // BLOCKS: br i1138    // BLOCKS: load double, ptr %139    // BLOCKS: store volatile double %140    // BLOCKS: load i32, ptr %141    // BLOCKS: store i32 %142    ^{143      g = 2;144      sivar = 22;145    }();146  }147  }();148  return 0;149#else150  S<double> ttt;151  S<double> test;152  int t_var = 0;153  int vec[] = {1, 2};154  S<double> s_arr[] = {1, 2};155  S<double> var(3);156#pragma omp master taskloop lastprivate(var, t_var, s_arr, vec, s_arr, var, sivar)157  for (int i = 0; i < 10; ++i) {158    vec[0] = t_var;159    s_arr[0] = var;160    sivar = 33;161  }162  return tmain<int>();163#endif164}165 166// CHECK: [[SIVAR:.+]] = internal global i{{[0-9]+}} 0,167// CHECK: define{{.*}} i{{[0-9]+}} @main()168// CHECK: alloca [[S_DOUBLE_TY]],169// CHECK: [[TEST:%.+]] = alloca [[S_DOUBLE_TY]],170// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32,171// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],172// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]],173// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]],174// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[LOC:@.+]])175 176// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR:@.+]](ptr {{[^,]*}} [[TEST]])177 178// CHECK:       [[RES:%.+]] = call {{.*}}i32 @__kmpc_master(179// CHECK-NEXT:  [[IS_MASTER:%.+]] = icmp ne i32 [[RES]], 0180// CHECK-NEXT:  br i1 [[IS_MASTER]], label {{%?}}[[THEN:.+]], label {{%?}}[[EXIT:.+]]181// CHECK:       [[THEN]]182// Store original variables in capture struct.183// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds nuw [[CAP_MAIN_TY]], ptr %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0184// CHECK: store ptr [[VEC_ADDR]], ptr [[VEC_REF]],185// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds nuw [[CAP_MAIN_TY]], ptr %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1186// CHECK: store ptr [[T_VAR_ADDR]], ptr [[T_VAR_REF]],187// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds nuw [[CAP_MAIN_TY]], ptr %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2188// CHECK: store ptr [[S_ARR_ADDR]], ptr [[S_ARR_REF]],189// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds nuw [[CAP_MAIN_TY]], ptr %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3190// CHECK: store ptr [[VAR_ADDR]], ptr [[VAR_REF]],191// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds nuw [[CAP_MAIN_TY]], ptr %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4192// CHECK: store ptr [[SIVAR]], ptr [[SIVAR_REF]],193 194// Allocate task.195// Returns struct kmp_task_t {196//         [[KMP_TASK_T]] task_data;197//         [[KMP_TASK_MAIN_TY]] privates;198//       };199// CHECK: [[RES:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[LOC]], i32 [[GTID]], i32 9, i64 120, i64 40, ptr [[TASK_ENTRY:@[^ ]+]])200 201// Fill kmp_task_t->shareds by copying from original capture argument.202// CHECK: [[TASK:%.+]] = getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0203// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds nuw [[KMP_TASK_T_TY]], ptr [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0204// CHECK: [[SHAREDS_REF:%.+]] = load ptr, ptr [[SHAREDS_REF_ADDR]],205// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[SHAREDS_REF]], ptr align 8 %{{.+}}, i64 40, i1 false)206 207// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).208// Also copy address of private copy to the corresponding shareds reference.209// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 1210 211// Constructors for s_arr and var.212// s_arr;213// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0214// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]](ptr {{[^,]*}} [[S_ARR_CUR:%[^,]+]])215// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr [[S_ARR_CUR]], i{{.+}} 1216// CHECK: icmp eq217// CHECK: br i1218 219// var;220// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 1221// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]](ptr {{[^,]*}} [[PRIVATE_VAR_REF]])222 223// t_var;224// vec;225// sivar;226 227// Provide pointer to destructor function, which will destroy private variables at the end of the task.228// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds nuw [[KMP_TASK_T_TY]], ptr [[TASK]], i{{.+}} 0, i{{.+}} 3229// CHECK: store ptr [[DESTRUCTORS:@.+]], ptr [[DESTRUCTORS_REF]],230 231// Start task.232// 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:@.+]])233// CHECK:  call {{.*}}void @__kmpc_end_master(234// CHECK-NEXT:  br label {{%?}}[[EXIT]]235// CHECK:       [[EXIT]]236 237// CHECK: = call noundef i{{.+}} [[TMAIN_INT:@.+]]()238 239// No destructors must be called for private copies of s_arr and var.240// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2241// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3242// CHECK: call void [[S_DOUBLE_TY_DESTR:@.+]](ptr243// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2244// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3245// CHECK: ret246//247 248// 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)249// CHECK: [[PRIVATES:%.+]] = load ptr, ptr250// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 0251// CHECK: [[ARG3:%.+]] = load ptr, ptr %{{.+}},252// CHECK: store ptr [[PRIV_S_VAR]], ptr [[ARG3]],253// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 1254// CHECK: [[ARG1:%.+]] = load ptr, ptr {{.+}},255// CHECK: store ptr [[PRIV_VAR]], ptr [[ARG1]],256// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 2257// CHECK: [[ARG2:%.+]] = load ptr, ptr %{{.+}},258// CHECK: store ptr [[PRIV_T_VAR]], ptr [[ARG2]],259// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 3260// CHECK: [[ARG4:%.+]] = load ptr, ptr %{{.+}},261// CHECK: store ptr [[PRIV_VEC]], ptr [[ARG4]],262// CHECK: [[PRIV_SIVAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i32 0, i32 4263// CHECK: [[ARG5:%.+]] = load ptr, ptr %{{.+}},264// CHECK: store ptr [[PRIV_SIVAR]], ptr [[ARG5]],265// CHECK: ret void266 267// CHECK: define internal noundef i32 [[TASK_ENTRY]](i32 noundef %0, ptr noalias noundef %1)268 269// CHECK: %__context270// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca ptr,271// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca ptr,272// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca ptr,273// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca ptr,274// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca ptr,275// CHECK: store ptr [[PRIVATES_MAP_FN]], ptr [[MAP_FN_ADDR:%.+]],276// CHECK: [[MAP_FN:%.+]] = load ptr, ptr [[MAP_FN_ADDR]],277 278// 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]])279 280// CHECK: [[PRIV_VAR:%.+]] = load ptr, ptr [[PRIV_VAR_ADDR]],281// CHECK: [[PRIV_T_VAR:%.+]] = load ptr, ptr [[PRIV_T_VAR_ADDR]],282// CHECK: [[PRIV_S_ARR:%.+]] = load ptr, ptr [[PRIV_S_ARR_ADDR]],283// CHECK: [[PRIV_VEC:%.+]] = load ptr, ptr [[PRIV_VEC_ADDR]],284// CHECK: [[PRIV_SIVAR:%.+]] = load ptr, ptr [[PRIV_SIVAR_ADDR]],285 286// Privates actually are used.287// CHECK-DAG: [[PRIV_VAR]]288// CHECK-DAG: [[PRIV_T_VAR]]289// CHECK-DAG: [[PRIV_S_ARR]]290// CHECK-DAG: [[PRIV_VEC]]291// CHECK-DAG: [[PRIV_SIVAR]]292 293// CHECK:     icmp ne i32 %{{.+}}, 0294// CHECK-NEXT: br i1295// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align {{[0-9]+}} %296// CHECK: load i32, ptr %297// CHECK: store i32 %{{.+}}, ptr %298// CHECK: phi ptr299// CHECK: phi ptr300// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align {{[0-9]+}} %301// CHECK: icmp eq ptr %302// CHECK-NEXT: br i1303// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align {{[0-9]+}} %304// CHECK: load i32, ptr %305// CHECK: store i32 %{{.+}}, ptr %306// CHECK: br label307// CHECK: ret308 309// CHECK: define internal void [[MAIN_DUP]](ptr noundef %0, ptr noundef %1, i32 noundef %2)310// CHECK: getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr %{{.+}}, i32 0, i32 0311// CHECK: getelementptr inbounds nuw [[KMP_TASK_T_TY]], ptr %{{.+}}, i32 0, i32 8312// CHECK: load i32, ptr %313// CHECK: store i32 %{{.+}}, ptr %314// CHECK: getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr %{{.+}}, i32 0, i32 1315// CHECK: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr %{{.+}}, i32 0, i32 0316// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], ptr %{{.+}}, i32 0, i32 0317// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i64 2318// CHECK: br label %319 320// CHECK: phi ptr321// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]](ptr322// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i64 1323// CHECK: icmp eq ptr %324// CHECK: br i1 %325 326// CHECK: getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr %{{.+}}, i32 0, i32 1327// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]](ptr328// CHECK: ret void329 330// CHECK: define internal noundef i32 [[DESTRUCTORS]](i32 noundef %0, ptr noalias noundef %1)331// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_MAIN_TY]], ptr [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1332// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 0333// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_MAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 1334// CHECK: call {{.*}} [[S_DOUBLE_TY_DESTR]](ptr {{[^,]*}} [[PRIVATE_VAR_REF]])335// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], ptr [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0336// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i{{.+}} 2337// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], ptr %{{.+}}, i{{.+}} -1338// CHECK: call {{.*}} [[S_DOUBLE_TY_DESTR]](ptr {{[^,]*}} [[PRIVATE_S_ARR_ELEM_REF]])339// CHECK: icmp eq340// CHECK: br i1341// CHECK: ret i32342 343// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()344// CHECK: alloca [[S_INT_TY]],345// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],346// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, align 128347// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],348// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]],349// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]],350// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[LOC:@.+]])351 352// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]](ptr {{[^,]*}} [[TEST]])353 354// Store original variables in capture struct.355// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds nuw [[CAP_TMAIN_TY]], ptr %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0356// CHECK: store ptr [[VEC_ADDR]], ptr [[VEC_REF]],357// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds nuw [[CAP_TMAIN_TY]], ptr %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1358// CHECK: store ptr [[T_VAR_ADDR]], ptr [[T_VAR_REF]],359// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds nuw [[CAP_TMAIN_TY]], ptr %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2360// CHECK: store ptr [[S_ARR_ADDR]], ptr [[S_ARR_REF]],361// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds nuw [[CAP_TMAIN_TY]], ptr %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3362// CHECK: store ptr [[VAR_ADDR]], ptr [[VAR_REF]],363 364// Allocate task.365// Returns struct kmp_task_t {366//         [[KMP_TASK_T_TY]] task_data;367//         [[KMP_TASK_TMAIN_TY]] privates;368//       };369// CHECK: [[RES:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[LOC]], i32 [[GTID]], i32 9, i64 256, i64 32, ptr [[TASK_ENTRY:@[^ ]+]])370 371// Fill kmp_task_t->shareds by copying from original capture argument.372// CHECK: [[TASK:%.+]] = getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0373// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds nuw [[KMP_TASK_T_TY]], ptr [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0374// CHECK: [[SHAREDS_REF:%.+]] = load ptr, ptr [[SHAREDS_REF_ADDR]],375// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[SHAREDS_REF]], ptr align 8 %{{.+}}, i64 32, i1 false)376 377// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).378// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr [[RES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2379 380// t_var;381// vec;382 383// Constructors for s_arr and var.384// a_arr;385// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2386// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], ptr [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0387// CHECK: getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i{{.+}} 2388// CHECK: call {{.*}} [[S_INT_TY_CONSTR]](ptr {{[^,]*}} [[S_ARR_CUR:%[^,]+]])389// CHECK: getelementptr inbounds [[S_INT_TY]], ptr [[S_ARR_CUR]], i{{.+}} 1390// CHECK: icmp eq391// CHECK: br i1392 393// var;394// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3395// CHECK: call {{.*}} [[S_INT_TY_CONSTR]](ptr {{[^,]*}} [[PRIVATE_VAR_REF]])396 397// Provide pointer to destructor function, which will destroy private variables at the end of the task.398// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds nuw [[KMP_TASK_T_TY]], ptr [[TASK]], i{{.+}} 0, i{{.+}} 3399// CHECK: store ptr [[DESTRUCTORS:@.+]], ptr [[DESTRUCTORS_REF]],400 401// Start task.402// 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:@.+]])403 404// No destructors must be called for private copies of s_arr and var.405// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2406// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3407// CHECK: call void [[S_INT_TY_DESTR:@.+]](ptr noundef408// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2409// CHECK-NOT: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3410// CHECK: ret411//412 413// 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)414// CHECK: [[PRIVATES:%.+]] = load ptr, ptr415// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 0416// CHECK: [[ARG1:%.+]] = load ptr, ptr %{{.+}},417// CHECK: store ptr [[PRIV_T_VAR]], ptr [[ARG1]],418// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 1419// CHECK: [[ARG2:%.+]] = load ptr, ptr %{{.+}},420// CHECK: store ptr [[PRIV_VEC]], ptr [[ARG2]],421// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 2422// CHECK: [[ARG3:%.+]] = load ptr, ptr %{{.+}},423// CHECK: store ptr [[PRIV_S_VAR]], ptr [[ARG3]],424// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i32 0, i32 3425// CHECK: [[ARG4:%.+]] = load ptr, ptr {{.+}},426// CHECK: store ptr [[PRIV_VAR]], ptr [[ARG4]],427// CHECK: ret void428 429// CHECK: define internal noundef i32 [[TASK_ENTRY]](i32 noundef %0, ptr noalias noundef %1)430// CHECK: %__context431// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca ptr,432// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca ptr,433// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca ptr,434// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca ptr,435// CHECK: store ptr [[PRIVATES_MAP_FN]], ptr [[MAP_FN_ADDR:%.+]],436// CHECK: [[MAP_FN:%.+]] = load ptr, ptr [[MAP_FN_ADDR]],437// CHECK: call void [[MAP_FN]](ptr %{{.+}}, ptr [[PRIV_T_VAR_ADDR]], ptr [[PRIV_VEC_ADDR]], ptr [[PRIV_S_ARR_ADDR]], ptr [[PRIV_VAR_ADDR]])438// CHECK: [[PRIV_T_VAR:%.+]] = load ptr, ptr [[PRIV_T_VAR_ADDR]],439// CHECK: [[PRIV_VEC:%.+]] = load ptr, ptr [[PRIV_VEC_ADDR]],440// CHECK: [[PRIV_S_ARR:%.+]] = load ptr, ptr [[PRIV_S_ARR_ADDR]],441// CHECK: [[PRIV_VAR:%.+]] = load ptr, ptr [[PRIV_VAR_ADDR]],442 443// Privates actually are used.444// CHECK-DAG: [[PRIV_VAR]]445// CHECK-DAG: [[PRIV_T_VAR]]446// CHECK-DAG: [[PRIV_S_ARR]]447// CHECK-DAG: [[PRIV_VEC]]448 449// CHECK:     icmp ne i32 %{{.+}}, 0450// CHECK-NEXT: br i1451// CHECK: load i32, ptr %452// CHECK: store i32 %{{.+}}, ptr %453// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align {{[0-9]+}} %454// CHECK: phi ptr455// CHECK: phi ptr456// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align {{[0-9]+}} %457// CHECK: icmp eq ptr %458// CHECK-NEXT: br i1459// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align {{[0-9]+}} %460// CHECK: br label461// CHECK: ret462 463// CHECK: define internal void [[TMAIN_DUP]](ptr noundef %0, ptr noundef %1, i32 noundef %2)464// CHECK: getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr %{{.+}}, i32 0, i32 0465// CHECK: getelementptr inbounds nuw [[KMP_TASK_T_TY]], ptr %{{.+}}, i32 0, i32 8466// CHECK: load i32, ptr %467// CHECK: store i32 %{{.+}}, ptr %468// CHECK: getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr %{{.+}}, i32 0, i32 2469// CHECK: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr %{{.+}}, i32 0, i32 2470// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], ptr %{{.+}}, i32 0, i32 0471// CHECK: getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i64 2472// CHECK: br label %473 474// CHECK: phi ptr475// CHECK: call {{.*}} [[S_INT_TY_CONSTR]](ptr476// CHECK: getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i64 1477// CHECK: icmp eq ptr %478// CHECK: br i1 %479 480// CHECK: getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr %{{.+}}, i32 0, i32 3481// CHECK: call {{.*}} [[S_INT_TY_CONSTR]](ptr482// CHECK: ret void483 484// CHECK: define internal noundef i32 [[DESTRUCTORS]](i32 noundef %0, ptr noalias noundef %1)485// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds nuw [[KMP_TASK_TMAIN_TY]], ptr [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2486// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 2487// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds nuw [[PRIVATES_TMAIN_TY]], ptr [[PRIVATES]], i{{.+}} 0, i{{.+}} 3488// CHECK: call void [[S_INT_TY_DESTR]](ptr {{[^,]*}} [[PRIVATE_VAR_REF]])489// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], ptr [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0490// CHECK: getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i{{.+}} 2491// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], ptr %{{.+}}, i{{.+}} -1492// CHECK: call void [[S_INT_TY_DESTR]](ptr {{[^,]*}} [[PRIVATE_S_ARR_ELEM_REF]])493// CHECK: icmp eq494// CHECK: br i1495// CHECK: ret i32496 497#endif498#elif defined(ARRAY)499// ARRAY-LABEL: array_func500struct St {501  int a, b;502  St() : a(0), b(0) {}503  St(const St &) {}504  ~St() {}505};506 507void array_func(int n, float a[n], St s[2]) {508// ARRAY: call ptr @__kmpc_omp_task_alloc(509// ARRAY: call void @__kmpc_taskloop(510// ARRAY: store ptr %{{.+}}, ptr %{{.+}},511// ARRAY: store ptr %{{.+}}, ptr %{{.+}},512// ARRAY: icmp ne i32 %{{.+}}, 0513// ARRAY: store ptr %{{.+}}, ptr %{{.+}},514// ARRAY: store ptr %{{.+}}, ptr %{{.+}},515#pragma omp master taskloop lastprivate(a, s)516  for (int i = 0; i < 10; ++i)517    ;518}519#else520 521// LOOP-LABEL: loop522void loop() {523// LOOP: call ptr @__kmpc_omp_task_alloc(524// LOOP: call void @__kmpc_taskloop(525  int i;526#pragma omp master taskloop lastprivate(i)527  for (i = 0; i < 10; ++i)528    ;529}530#endif531 532