1207b08a9SGiorgis Georgakoudis // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ 2a2dbfb6bSGiorgis Georgakoudis // Test target codegen - host bc file has to be created first. 3a2dbfb6bSGiorgis Georgakoudis // RUN: %clang_cc1 -verify -fopenmp -fopenmp-cuda-mode -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc 4207b08a9SGiorgis Georgakoudis // RUN: %clang_cc1 -verify -fopenmp -fopenmp-cuda-mode -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix=CHECK1 5a2dbfb6bSGiorgis Georgakoudis // RUN: %clang_cc1 -verify -fopenmp -fopenmp-cuda-mode -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc 6207b08a9SGiorgis Georgakoudis // RUN: %clang_cc1 -verify -fopenmp -fopenmp-cuda-mode -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix=CHECK2 7207b08a9SGiorgis Georgakoudis // RUN: %clang_cc1 -verify -fopenmp -fopenmp-cuda-mode -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix=CHECK3 8a2dbfb6bSGiorgis Georgakoudis 9a2dbfb6bSGiorgis Georgakoudis // expected-no-diagnostics 10a2dbfb6bSGiorgis Georgakoudis #ifndef HEADER 11a2dbfb6bSGiorgis Georgakoudis #define HEADER 12a2dbfb6bSGiorgis Georgakoudis 13a2dbfb6bSGiorgis Georgakoudis void work(int *C) { 14a2dbfb6bSGiorgis Georgakoudis #pragma omp atomic 15a2dbfb6bSGiorgis Georgakoudis ++(*C); 16a2dbfb6bSGiorgis Georgakoudis } 17a2dbfb6bSGiorgis Georgakoudis 18a2dbfb6bSGiorgis Georgakoudis void use(int *C) { 19a2dbfb6bSGiorgis Georgakoudis #pragma omp parallel num_threads(2) 20a2dbfb6bSGiorgis Georgakoudis work(C); 21a2dbfb6bSGiorgis Georgakoudis } 22a2dbfb6bSGiorgis Georgakoudis 23a2dbfb6bSGiorgis Georgakoudis int main() { 24a2dbfb6bSGiorgis Georgakoudis int C = 0; 25a2dbfb6bSGiorgis Georgakoudis #pragma omp target map(C) 26a2dbfb6bSGiorgis Georgakoudis { 27a2dbfb6bSGiorgis Georgakoudis use(&C); 28a2dbfb6bSGiorgis Georgakoudis #pragma omp parallel num_threads(2) 29a2dbfb6bSGiorgis Georgakoudis use(&C); 30a2dbfb6bSGiorgis Georgakoudis } 31a2dbfb6bSGiorgis Georgakoudis 32a2dbfb6bSGiorgis Georgakoudis return C; 33a2dbfb6bSGiorgis Georgakoudis } 34a2dbfb6bSGiorgis Georgakoudis 35a2dbfb6bSGiorgis Georgakoudis #endif 36a2dbfb6bSGiorgis Georgakoudis // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l25 37e2cfbfccSJohannes Doerfert // CHECK1-SAME: (i32* nonnull align 4 dereferenceable(4) [[C:%.*]]) #[[ATTR0:[0-9]+]] { 38a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: entry: 39a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca i32*, align 8 40a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [1 x i8*], align 8 41a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: store i32* [[C]], i32** [[C_ADDR]], align 8 42a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 8 43e2cfbfccSJohannes Doerfert // CHECK1-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB1:[0-9]+]], i1 false, i1 true, i1 true) 44e2cfbfccSJohannes Doerfert // CHECK1-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP1]], -1 45e2cfbfccSJohannes Doerfert // CHECK1-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] 46e2cfbfccSJohannes Doerfert // CHECK1: user_code.entry: 47e2cfbfccSJohannes Doerfert // CHECK1-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) 48*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: call void @_Z3usePi(i32* [[TMP0]]) #[[ATTR5:[0-9]+]] 49e2cfbfccSJohannes Doerfert // CHECK1-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB1]], i32 [[TMP2]], i32 2) 50*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 51*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[TMP4:%.*]] = bitcast i32* [[TMP0]] to i8* 52*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: store i8* [[TMP4]], i8** [[TMP3]], align 8 53*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[TMP5:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** 54*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP2]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32*)* @__omp_outlined__ to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined___wrapper to i8*), i8** [[TMP5]], i64 1) 55e2cfbfccSJohannes Doerfert // CHECK1-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i1 false, i1 true) 56e2cfbfccSJohannes Doerfert // CHECK1-NEXT: ret void 57e2cfbfccSJohannes Doerfert // CHECK1: worker.exit: 58a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: ret void 59a2dbfb6bSGiorgis Georgakoudis // 60a2dbfb6bSGiorgis Georgakoudis // 61a2dbfb6bSGiorgis Georgakoudis // CHECK1-LABEL: define {{[^@]+}}@_Z3usePi 62e2cfbfccSJohannes Doerfert // CHECK1-SAME: (i32* [[C:%.*]]) #[[ATTR1:[0-9]+]] { 63a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: entry: 64a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca i32*, align 8 65a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [1 x i8*], align 8 66df729e2bSJohannes Doerfert // CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB2:[0-9]+]]) 67a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: store i32* [[C]], i32** [[C_ADDR]], align 8 68df729e2bSJohannes Doerfert // CHECK1-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB2]], i32 [[TMP0]], i32 2) 69*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 70*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[TMP2:%.*]] = bitcast i32** [[C_ADDR]] to i8* 71*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: store i8* [[TMP2]], i8** [[TMP1]], align 8 72*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[TMP3:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** 73*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB2]], i32 [[TMP0]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32**)* @__omp_outlined__1 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__1_wrapper to i8*), i8** [[TMP3]], i64 1) 74a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: ret void 75a2dbfb6bSGiorgis Georgakoudis // 76a2dbfb6bSGiorgis Georgakoudis // 77a2dbfb6bSGiorgis Georgakoudis // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined__ 78*ac90dfc4SGiorgis Georgakoudis // CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[C:%.*]]) #[[ATTR0]] { 79df729e2bSJohannes Doerfert // CHECK1-NEXT: entry: 80df729e2bSJohannes Doerfert // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 81df729e2bSJohannes Doerfert // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 82*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca i32*, align 8 83df729e2bSJohannes Doerfert // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 84df729e2bSJohannes Doerfert // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 85*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: store i32* [[C]], i32** [[C_ADDR]], align 8 86*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 8 87*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: call void @_Z3usePi(i32* [[TMP0]]) #[[ATTR5]] 88df729e2bSJohannes Doerfert // CHECK1-NEXT: ret void 89df729e2bSJohannes Doerfert // 90df729e2bSJohannes Doerfert // 91df729e2bSJohannes Doerfert // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined___wrapper 92e2cfbfccSJohannes Doerfert // CHECK1-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR2:[0-9]+]] { 93df729e2bSJohannes Doerfert // CHECK1-NEXT: entry: 94df729e2bSJohannes Doerfert // CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i16, align 2 95df729e2bSJohannes Doerfert // CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 96df729e2bSJohannes Doerfert // CHECK1-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 97df729e2bSJohannes Doerfert // CHECK1-NEXT: [[GLOBAL_ARGS:%.*]] = alloca i8**, align 8 98df729e2bSJohannes Doerfert // CHECK1-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 99df729e2bSJohannes Doerfert // CHECK1-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2 100df729e2bSJohannes Doerfert // CHECK1-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4 101df729e2bSJohannes Doerfert // CHECK1-NEXT: call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]]) 102df729e2bSJohannes Doerfert // CHECK1-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 8 103df729e2bSJohannes Doerfert // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 0 104*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32** 105*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 8 106*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: call void @__omp_outlined__(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]]) #[[ATTR3:[0-9]+]] 107df729e2bSJohannes Doerfert // CHECK1-NEXT: ret void 108df729e2bSJohannes Doerfert // 109df729e2bSJohannes Doerfert // 110df729e2bSJohannes Doerfert // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined__1 111*ac90dfc4SGiorgis Georgakoudis // CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32** nonnull align 8 dereferenceable(8) [[C:%.*]]) #[[ATTR0]] { 112a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: entry: 113a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 114a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 115*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca i32**, align 8 116a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 117a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 118*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: store i32** [[C]], i32*** [[C_ADDR]], align 8 119*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[TMP0:%.*]] = load i32**, i32*** [[C_ADDR]], align 8 120*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[TMP1:%.*]] = load i32*, i32** [[TMP0]], align 8 121*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: call void @_Z4workPi(i32* [[TMP1]]) #[[ATTR5]] 122a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: ret void 123a2dbfb6bSGiorgis Georgakoudis // 124a2dbfb6bSGiorgis Georgakoudis // 125a2dbfb6bSGiorgis Georgakoudis // CHECK1-LABEL: define {{[^@]+}}@_Z4workPi 126e2cfbfccSJohannes Doerfert // CHECK1-SAME: (i32* [[C:%.*]]) #[[ATTR1]] { 127a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: entry: 128a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca i32*, align 8 129a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i32, align 4 130a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[ATOMIC_TEMP1:%.*]] = alloca i32, align 4 131a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: store i32* [[C]], i32** [[C_ADDR]], align 8 132a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 8 133a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[TMP1:%.*]] = bitcast i32* [[TMP0]] to i8* 134a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[TMP2:%.*]] = bitcast i32* [[ATOMIC_TEMP]] to i8* 135*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: call void @__atomic_load(i64 4, i8* [[TMP1]], i8* [[TMP2]], i32 0) #[[ATTR5]] 136a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: br label [[ATOMIC_CONT:%.*]] 137a2dbfb6bSGiorgis Georgakoudis // CHECK1: atomic_cont: 138a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[TMP3:%.*]] = load i32, i32* [[ATOMIC_TEMP]], align 4 139a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP3]], 1 140a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: store i32 [[ADD]], i32* [[ATOMIC_TEMP1]], align 4 141a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[TMP4:%.*]] = bitcast i32* [[TMP0]] to i8* 142a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[TMP5:%.*]] = bitcast i32* [[ATOMIC_TEMP]] to i8* 143a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[TMP6:%.*]] = bitcast i32* [[ATOMIC_TEMP1]] to i8* 144*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[CALL:%.*]] = call zeroext i1 @__atomic_compare_exchange(i64 4, i8* [[TMP4]], i8* [[TMP5]], i8* [[TMP6]], i32 0, i32 0) #[[ATTR5]] 145a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: br i1 [[CALL]], label [[ATOMIC_EXIT:%.*]], label [[ATOMIC_CONT]] 146a2dbfb6bSGiorgis Georgakoudis // CHECK1: atomic_exit: 147a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: ret void 148a2dbfb6bSGiorgis Georgakoudis // 149a2dbfb6bSGiorgis Georgakoudis // 150df729e2bSJohannes Doerfert // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined__1_wrapper 151e2cfbfccSJohannes Doerfert // CHECK1-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR2]] { 152a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: entry: 153a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i16, align 2 154a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 155a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 156a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[GLOBAL_ARGS:%.*]] = alloca i8**, align 8 157a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 158a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2 159a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4 160a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]]) 161a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 8 162a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 0 163*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32*** 164*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: [[TMP5:%.*]] = load i32**, i32*** [[TMP4]], align 8 165*ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT: call void @__omp_outlined__1(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32** [[TMP5]]) #[[ATTR3]] 166a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT: ret void 167a2dbfb6bSGiorgis Georgakoudis // 168a2dbfb6bSGiorgis Georgakoudis // 169a2dbfb6bSGiorgis Georgakoudis // CHECK2-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l25 170e2cfbfccSJohannes Doerfert // CHECK2-SAME: (i32* nonnull align 4 dereferenceable(4) [[C:%.*]]) #[[ATTR0:[0-9]+]] { 171a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: entry: 172a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[C_ADDR:%.*]] = alloca i32*, align 4 173a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [1 x i8*], align 4 174a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: store i32* [[C]], i32** [[C_ADDR]], align 4 175a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 4 176e2cfbfccSJohannes Doerfert // CHECK2-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB1:[0-9]+]], i1 false, i1 true, i1 true) 177e2cfbfccSJohannes Doerfert // CHECK2-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP1]], -1 178e2cfbfccSJohannes Doerfert // CHECK2-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] 179e2cfbfccSJohannes Doerfert // CHECK2: user_code.entry: 180e2cfbfccSJohannes Doerfert // CHECK2-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) 181*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: call void @_Z3usePi(i32* [[TMP0]]) #[[ATTR5:[0-9]+]] 182e2cfbfccSJohannes Doerfert // CHECK2-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB1]], i32 [[TMP2]], i32 2) 183*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i32 0, i32 0 184*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[TMP4:%.*]] = bitcast i32* [[TMP0]] to i8* 185*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: store i8* [[TMP4]], i8** [[TMP3]], align 4 186*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[TMP5:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** 187*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP2]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32*)* @__omp_outlined__ to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined___wrapper to i8*), i8** [[TMP5]], i32 1) 188e2cfbfccSJohannes Doerfert // CHECK2-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i1 false, i1 true) 189e2cfbfccSJohannes Doerfert // CHECK2-NEXT: ret void 190e2cfbfccSJohannes Doerfert // CHECK2: worker.exit: 191a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: ret void 192a2dbfb6bSGiorgis Georgakoudis // 193a2dbfb6bSGiorgis Georgakoudis // 194a2dbfb6bSGiorgis Georgakoudis // CHECK2-LABEL: define {{[^@]+}}@_Z3usePi 195e2cfbfccSJohannes Doerfert // CHECK2-SAME: (i32* [[C:%.*]]) #[[ATTR1:[0-9]+]] { 196a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: entry: 197a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[C_ADDR:%.*]] = alloca i32*, align 4 198a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [1 x i8*], align 4 199df729e2bSJohannes Doerfert // CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB2:[0-9]+]]) 200a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: store i32* [[C]], i32** [[C_ADDR]], align 4 201df729e2bSJohannes Doerfert // CHECK2-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB2]], i32 [[TMP0]], i32 2) 202*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i32 0, i32 0 203*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[TMP2:%.*]] = bitcast i32** [[C_ADDR]] to i8* 204*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: store i8* [[TMP2]], i8** [[TMP1]], align 4 205*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[TMP3:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** 206*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB2]], i32 [[TMP0]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32**)* @__omp_outlined__1 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__1_wrapper to i8*), i8** [[TMP3]], i32 1) 207a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: ret void 208a2dbfb6bSGiorgis Georgakoudis // 209a2dbfb6bSGiorgis Georgakoudis // 210a2dbfb6bSGiorgis Georgakoudis // CHECK2-LABEL: define {{[^@]+}}@__omp_outlined__ 211*ac90dfc4SGiorgis Georgakoudis // CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[C:%.*]]) #[[ATTR0]] { 212df729e2bSJohannes Doerfert // CHECK2-NEXT: entry: 213df729e2bSJohannes Doerfert // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 4 214df729e2bSJohannes Doerfert // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 4 215*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[C_ADDR:%.*]] = alloca i32*, align 4 216df729e2bSJohannes Doerfert // CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 4 217df729e2bSJohannes Doerfert // CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 4 218*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: store i32* [[C]], i32** [[C_ADDR]], align 4 219*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 4 220*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: call void @_Z3usePi(i32* [[TMP0]]) #[[ATTR5]] 221df729e2bSJohannes Doerfert // CHECK2-NEXT: ret void 222df729e2bSJohannes Doerfert // 223df729e2bSJohannes Doerfert // 224df729e2bSJohannes Doerfert // CHECK2-LABEL: define {{[^@]+}}@__omp_outlined___wrapper 225e2cfbfccSJohannes Doerfert // CHECK2-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR2:[0-9]+]] { 226df729e2bSJohannes Doerfert // CHECK2-NEXT: entry: 227df729e2bSJohannes Doerfert // CHECK2-NEXT: [[DOTADDR:%.*]] = alloca i16, align 2 228df729e2bSJohannes Doerfert // CHECK2-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 229df729e2bSJohannes Doerfert // CHECK2-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 230df729e2bSJohannes Doerfert // CHECK2-NEXT: [[GLOBAL_ARGS:%.*]] = alloca i8**, align 4 231df729e2bSJohannes Doerfert // CHECK2-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 232df729e2bSJohannes Doerfert // CHECK2-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2 233df729e2bSJohannes Doerfert // CHECK2-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4 234df729e2bSJohannes Doerfert // CHECK2-NEXT: call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]]) 235df729e2bSJohannes Doerfert // CHECK2-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 4 236df729e2bSJohannes Doerfert // CHECK2-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i32 0 237*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32** 238*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 4 239*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: call void @__omp_outlined__(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]]) #[[ATTR3:[0-9]+]] 240df729e2bSJohannes Doerfert // CHECK2-NEXT: ret void 241df729e2bSJohannes Doerfert // 242df729e2bSJohannes Doerfert // 243df729e2bSJohannes Doerfert // CHECK2-LABEL: define {{[^@]+}}@__omp_outlined__1 244*ac90dfc4SGiorgis Georgakoudis // CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32** nonnull align 4 dereferenceable(4) [[C:%.*]]) #[[ATTR0]] { 245a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: entry: 246a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 4 247a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 4 248*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[C_ADDR:%.*]] = alloca i32**, align 4 249a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 4 250a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 4 251*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: store i32** [[C]], i32*** [[C_ADDR]], align 4 252*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[TMP0:%.*]] = load i32**, i32*** [[C_ADDR]], align 4 253*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[TMP0]], align 4 254*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: call void @_Z4workPi(i32* [[TMP1]]) #[[ATTR5]] 255a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: ret void 256a2dbfb6bSGiorgis Georgakoudis // 257a2dbfb6bSGiorgis Georgakoudis // 258a2dbfb6bSGiorgis Georgakoudis // CHECK2-LABEL: define {{[^@]+}}@_Z4workPi 259e2cfbfccSJohannes Doerfert // CHECK2-SAME: (i32* [[C:%.*]]) #[[ATTR1]] { 260a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: entry: 261a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[C_ADDR:%.*]] = alloca i32*, align 4 262a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i32, align 4 263a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[ATOMIC_TEMP1:%.*]] = alloca i32, align 4 264a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: store i32* [[C]], i32** [[C_ADDR]], align 4 265a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 4 266a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[TMP1:%.*]] = bitcast i32* [[TMP0]] to i8* 267a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[TMP2:%.*]] = bitcast i32* [[ATOMIC_TEMP]] to i8* 268*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: call void @__atomic_load(i32 4, i8* [[TMP1]], i8* [[TMP2]], i32 0) #[[ATTR5]] 269a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: br label [[ATOMIC_CONT:%.*]] 270a2dbfb6bSGiorgis Georgakoudis // CHECK2: atomic_cont: 271a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[TMP3:%.*]] = load i32, i32* [[ATOMIC_TEMP]], align 4 272a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP3]], 1 273a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: store i32 [[ADD]], i32* [[ATOMIC_TEMP1]], align 4 274a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[TMP4:%.*]] = bitcast i32* [[TMP0]] to i8* 275a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[TMP5:%.*]] = bitcast i32* [[ATOMIC_TEMP]] to i8* 276a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[TMP6:%.*]] = bitcast i32* [[ATOMIC_TEMP1]] to i8* 277*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[CALL:%.*]] = call zeroext i1 @__atomic_compare_exchange(i32 4, i8* [[TMP4]], i8* [[TMP5]], i8* [[TMP6]], i32 0, i32 0) #[[ATTR5]] 278a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: br i1 [[CALL]], label [[ATOMIC_EXIT:%.*]], label [[ATOMIC_CONT]] 279a2dbfb6bSGiorgis Georgakoudis // CHECK2: atomic_exit: 280a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: ret void 281a2dbfb6bSGiorgis Georgakoudis // 282a2dbfb6bSGiorgis Georgakoudis // 283df729e2bSJohannes Doerfert // CHECK2-LABEL: define {{[^@]+}}@__omp_outlined__1_wrapper 284e2cfbfccSJohannes Doerfert // CHECK2-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR2]] { 285a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: entry: 286a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[DOTADDR:%.*]] = alloca i16, align 2 287a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 288a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 289a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[GLOBAL_ARGS:%.*]] = alloca i8**, align 4 290a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 291a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2 292a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4 293a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]]) 294a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 4 295a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i32 0 296*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32*** 297*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: [[TMP5:%.*]] = load i32**, i32*** [[TMP4]], align 4 298*ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT: call void @__omp_outlined__1(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32** [[TMP5]]) #[[ATTR3]] 299a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT: ret void 300a2dbfb6bSGiorgis Georgakoudis // 301a2dbfb6bSGiorgis Georgakoudis // 302a2dbfb6bSGiorgis Georgakoudis // CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l25 303e2cfbfccSJohannes Doerfert // CHECK3-SAME: (i32* nonnull align 4 dereferenceable(4) [[C:%.*]]) #[[ATTR0:[0-9]+]] { 304a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: entry: 305a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[C_ADDR:%.*]] = alloca i32*, align 4 306a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [1 x i8*], align 4 307a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: store i32* [[C]], i32** [[C_ADDR]], align 4 308a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 4 309e2cfbfccSJohannes Doerfert // CHECK3-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB1:[0-9]+]], i1 false, i1 true, i1 true) 310e2cfbfccSJohannes Doerfert // CHECK3-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP1]], -1 311e2cfbfccSJohannes Doerfert // CHECK3-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] 312e2cfbfccSJohannes Doerfert // CHECK3: user_code.entry: 313e2cfbfccSJohannes Doerfert // CHECK3-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) 314*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: call void @_Z3usePi(i32* [[TMP0]]) #[[ATTR5:[0-9]+]] 315e2cfbfccSJohannes Doerfert // CHECK3-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB1]], i32 [[TMP2]], i32 2) 316*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i32 0, i32 0 317*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[TMP4:%.*]] = bitcast i32* [[TMP0]] to i8* 318*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: store i8* [[TMP4]], i8** [[TMP3]], align 4 319*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[TMP5:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** 320*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP2]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32*)* @__omp_outlined__ to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined___wrapper to i8*), i8** [[TMP5]], i32 1) 321e2cfbfccSJohannes Doerfert // CHECK3-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i1 false, i1 true) 322e2cfbfccSJohannes Doerfert // CHECK3-NEXT: ret void 323e2cfbfccSJohannes Doerfert // CHECK3: worker.exit: 324a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: ret void 325a2dbfb6bSGiorgis Georgakoudis // 326a2dbfb6bSGiorgis Georgakoudis // 327a2dbfb6bSGiorgis Georgakoudis // CHECK3-LABEL: define {{[^@]+}}@_Z3usePi 328e2cfbfccSJohannes Doerfert // CHECK3-SAME: (i32* [[C:%.*]]) #[[ATTR1:[0-9]+]] { 329a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: entry: 330a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[C_ADDR:%.*]] = alloca i32*, align 4 331a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [1 x i8*], align 4 332df729e2bSJohannes Doerfert // CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB2:[0-9]+]]) 333a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: store i32* [[C]], i32** [[C_ADDR]], align 4 334df729e2bSJohannes Doerfert // CHECK3-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB2]], i32 [[TMP0]], i32 2) 335*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i32 0, i32 0 336*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[TMP2:%.*]] = bitcast i32** [[C_ADDR]] to i8* 337*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: store i8* [[TMP2]], i8** [[TMP1]], align 4 338*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[TMP3:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** 339*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB2]], i32 [[TMP0]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32**)* @__omp_outlined__1 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__1_wrapper to i8*), i8** [[TMP3]], i32 1) 340a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: ret void 341a2dbfb6bSGiorgis Georgakoudis // 342a2dbfb6bSGiorgis Georgakoudis // 343a2dbfb6bSGiorgis Georgakoudis // CHECK3-LABEL: define {{[^@]+}}@__omp_outlined__ 344*ac90dfc4SGiorgis Georgakoudis // CHECK3-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[C:%.*]]) #[[ATTR0]] { 345df729e2bSJohannes Doerfert // CHECK3-NEXT: entry: 346df729e2bSJohannes Doerfert // CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 4 347df729e2bSJohannes Doerfert // CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 4 348*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[C_ADDR:%.*]] = alloca i32*, align 4 349df729e2bSJohannes Doerfert // CHECK3-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 4 350df729e2bSJohannes Doerfert // CHECK3-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 4 351*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: store i32* [[C]], i32** [[C_ADDR]], align 4 352*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 4 353*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: call void @_Z3usePi(i32* [[TMP0]]) #[[ATTR5]] 354df729e2bSJohannes Doerfert // CHECK3-NEXT: ret void 355df729e2bSJohannes Doerfert // 356df729e2bSJohannes Doerfert // 357df729e2bSJohannes Doerfert // CHECK3-LABEL: define {{[^@]+}}@__omp_outlined___wrapper 358e2cfbfccSJohannes Doerfert // CHECK3-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR2:[0-9]+]] { 359df729e2bSJohannes Doerfert // CHECK3-NEXT: entry: 360df729e2bSJohannes Doerfert // CHECK3-NEXT: [[DOTADDR:%.*]] = alloca i16, align 2 361df729e2bSJohannes Doerfert // CHECK3-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 362df729e2bSJohannes Doerfert // CHECK3-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 363df729e2bSJohannes Doerfert // CHECK3-NEXT: [[GLOBAL_ARGS:%.*]] = alloca i8**, align 4 364df729e2bSJohannes Doerfert // CHECK3-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 365df729e2bSJohannes Doerfert // CHECK3-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2 366df729e2bSJohannes Doerfert // CHECK3-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4 367df729e2bSJohannes Doerfert // CHECK3-NEXT: call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]]) 368df729e2bSJohannes Doerfert // CHECK3-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 4 369df729e2bSJohannes Doerfert // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i32 0 370*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32** 371*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 4 372*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: call void @__omp_outlined__(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]]) #[[ATTR3:[0-9]+]] 373df729e2bSJohannes Doerfert // CHECK3-NEXT: ret void 374df729e2bSJohannes Doerfert // 375df729e2bSJohannes Doerfert // 376df729e2bSJohannes Doerfert // CHECK3-LABEL: define {{[^@]+}}@__omp_outlined__1 377*ac90dfc4SGiorgis Georgakoudis // CHECK3-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32** nonnull align 4 dereferenceable(4) [[C:%.*]]) #[[ATTR0]] { 378a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: entry: 379a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 4 380a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 4 381*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[C_ADDR:%.*]] = alloca i32**, align 4 382a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 4 383a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 4 384*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: store i32** [[C]], i32*** [[C_ADDR]], align 4 385*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[TMP0:%.*]] = load i32**, i32*** [[C_ADDR]], align 4 386*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[TMP1:%.*]] = load i32*, i32** [[TMP0]], align 4 387*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: call void @_Z4workPi(i32* [[TMP1]]) #[[ATTR5]] 388a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: ret void 389a2dbfb6bSGiorgis Georgakoudis // 390a2dbfb6bSGiorgis Georgakoudis // 391a2dbfb6bSGiorgis Georgakoudis // CHECK3-LABEL: define {{[^@]+}}@_Z4workPi 392e2cfbfccSJohannes Doerfert // CHECK3-SAME: (i32* [[C:%.*]]) #[[ATTR1]] { 393a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: entry: 394a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[C_ADDR:%.*]] = alloca i32*, align 4 395a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i32, align 4 396a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[ATOMIC_TEMP1:%.*]] = alloca i32, align 4 397a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: store i32* [[C]], i32** [[C_ADDR]], align 4 398a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 4 399a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[TMP1:%.*]] = bitcast i32* [[TMP0]] to i8* 400a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[TMP2:%.*]] = bitcast i32* [[ATOMIC_TEMP]] to i8* 401*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: call void @__atomic_load(i32 4, i8* [[TMP1]], i8* [[TMP2]], i32 0) #[[ATTR5]] 402a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: br label [[ATOMIC_CONT:%.*]] 403a2dbfb6bSGiorgis Georgakoudis // CHECK3: atomic_cont: 404a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[TMP3:%.*]] = load i32, i32* [[ATOMIC_TEMP]], align 4 405a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP3]], 1 406a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: store i32 [[ADD]], i32* [[ATOMIC_TEMP1]], align 4 407a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[TMP4:%.*]] = bitcast i32* [[TMP0]] to i8* 408a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[TMP5:%.*]] = bitcast i32* [[ATOMIC_TEMP]] to i8* 409a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[TMP6:%.*]] = bitcast i32* [[ATOMIC_TEMP1]] to i8* 410*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[CALL:%.*]] = call zeroext i1 @__atomic_compare_exchange(i32 4, i8* [[TMP4]], i8* [[TMP5]], i8* [[TMP6]], i32 0, i32 0) #[[ATTR5]] 411a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: br i1 [[CALL]], label [[ATOMIC_EXIT:%.*]], label [[ATOMIC_CONT]] 412a2dbfb6bSGiorgis Georgakoudis // CHECK3: atomic_exit: 413a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: ret void 414a2dbfb6bSGiorgis Georgakoudis // 415a2dbfb6bSGiorgis Georgakoudis // 416df729e2bSJohannes Doerfert // CHECK3-LABEL: define {{[^@]+}}@__omp_outlined__1_wrapper 417e2cfbfccSJohannes Doerfert // CHECK3-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR2]] { 418a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: entry: 419a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[DOTADDR:%.*]] = alloca i16, align 2 420a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 421a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 422a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[GLOBAL_ARGS:%.*]] = alloca i8**, align 4 423a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 424a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2 425a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4 426a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]]) 427a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 4 428a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i32 0 429*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32*** 430*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: [[TMP5:%.*]] = load i32**, i32*** [[TMP4]], align 4 431*ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT: call void @__omp_outlined__1(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32** [[TMP5]]) #[[ATTR3]] 432a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT: ret void 433a2dbfb6bSGiorgis Georgakoudis // 434