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
37*e2cfbfccSJohannes 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
43*e2cfbfccSJohannes Doerfert // CHECK1-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB1:[0-9]+]], i1 false, i1 true, i1 true)
44*e2cfbfccSJohannes Doerfert // CHECK1-NEXT:    [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP1]], -1
45*e2cfbfccSJohannes Doerfert // CHECK1-NEXT:    br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]]
46*e2cfbfccSJohannes Doerfert // CHECK1:       user_code.entry:
47*e2cfbfccSJohannes Doerfert // CHECK1-NEXT:    [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]])
48*e2cfbfccSJohannes Doerfert // CHECK1-NEXT:    call void @_Z3usePi(i32* [[TMP0]]) #[[ATTR5:[0-9]+]]
49*e2cfbfccSJohannes Doerfert // CHECK1-NEXT:    call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB1]], i32 [[TMP2]], i32 2)
50*e2cfbfccSJohannes Doerfert // CHECK1-NEXT:    [[TMP3:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0
51*e2cfbfccSJohannes Doerfert // CHECK1-NEXT:    [[TMP4:%.*]] = bitcast i32* [[TMP0]] to i8*
52*e2cfbfccSJohannes Doerfert // CHECK1-NEXT:    store i8* [[TMP4]], i8** [[TMP3]], align 8
53*e2cfbfccSJohannes Doerfert // CHECK1-NEXT:    [[TMP5:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**
54*e2cfbfccSJohannes Doerfert // 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)
55*e2cfbfccSJohannes Doerfert // CHECK1-NEXT:    call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i1 false, i1 true)
56*e2cfbfccSJohannes Doerfert // CHECK1-NEXT:    ret void
57*e2cfbfccSJohannes Doerfert // CHECK1:       worker.exit:
58a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    ret void
59a2dbfb6bSGiorgis Georgakoudis //
60a2dbfb6bSGiorgis Georgakoudis //
61a2dbfb6bSGiorgis Georgakoudis // CHECK1-LABEL: define {{[^@]+}}@_Z3usePi
62*e2cfbfccSJohannes 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)
69a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0
70a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP2:%.*]] = bitcast i32** [[C_ADDR]] to i8*
71a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    store i8* [[TMP2]], i8** [[TMP1]], align 8
72a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP3:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**
73df729e2bSJohannes Doerfert // 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*e2cfbfccSJohannes Doerfert // 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
82df729e2bSJohannes Doerfert // 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
85df729e2bSJohannes Doerfert // CHECK1-NEXT:    store i32* [[C]], i32** [[C_ADDR]], align 8
86df729e2bSJohannes Doerfert // CHECK1-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 8
87*e2cfbfccSJohannes Doerfert // 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
92*e2cfbfccSJohannes 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
104df729e2bSJohannes Doerfert // CHECK1-NEXT:    [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32**
105df729e2bSJohannes Doerfert // CHECK1-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 8
106*e2cfbfccSJohannes Doerfert // 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*e2cfbfccSJohannes Doerfert // 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
115a2dbfb6bSGiorgis 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
118a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    store i32** [[C]], i32*** [[C_ADDR]], align 8
119a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP0:%.*]] = load i32**, i32*** [[C_ADDR]], align 8
120a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP1:%.*]] = load i32*, i32** [[TMP0]], align 8
121*e2cfbfccSJohannes Doerfert // CHECK1-NEXT:    call void @_Z4workPi(i32* [[TMP1]]) #[[ATTR5]]
122a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    ret void
123a2dbfb6bSGiorgis Georgakoudis //
124a2dbfb6bSGiorgis Georgakoudis //
125a2dbfb6bSGiorgis Georgakoudis // CHECK1-LABEL: define {{[^@]+}}@_Z4workPi
126*e2cfbfccSJohannes 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*e2cfbfccSJohannes Doerfert // 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*e2cfbfccSJohannes Doerfert // 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
151*e2cfbfccSJohannes 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
163a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32***
164a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP5:%.*]] = load i32**, i32*** [[TMP4]], align 8
165*e2cfbfccSJohannes Doerfert // 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
170*e2cfbfccSJohannes 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
176*e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB1:[0-9]+]], i1 false, i1 true, i1 true)
177*e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP1]], -1
178*e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]]
179*e2cfbfccSJohannes Doerfert // CHECK2:       user_code.entry:
180*e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]])
181*e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    call void @_Z3usePi(i32* [[TMP0]]) #[[ATTR5:[0-9]+]]
182*e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB1]], i32 [[TMP2]], i32 2)
183*e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    [[TMP3:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i32 0, i32 0
184*e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    [[TMP4:%.*]] = bitcast i32* [[TMP0]] to i8*
185*e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    store i8* [[TMP4]], i8** [[TMP3]], align 4
186*e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    [[TMP5:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**
187*e2cfbfccSJohannes Doerfert // 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)
188*e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i1 false, i1 true)
189*e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    ret void
190*e2cfbfccSJohannes Doerfert // CHECK2:       worker.exit:
191a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    ret void
192a2dbfb6bSGiorgis Georgakoudis //
193a2dbfb6bSGiorgis Georgakoudis //
194a2dbfb6bSGiorgis Georgakoudis // CHECK2-LABEL: define {{[^@]+}}@_Z3usePi
195*e2cfbfccSJohannes 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)
202a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i32 0, i32 0
203a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP2:%.*]] = bitcast i32** [[C_ADDR]] to i8*
204a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    store i8* [[TMP2]], i8** [[TMP1]], align 4
205a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP3:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**
206df729e2bSJohannes Doerfert // 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*e2cfbfccSJohannes Doerfert // 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
215df729e2bSJohannes Doerfert // 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
218df729e2bSJohannes Doerfert // CHECK2-NEXT:    store i32* [[C]], i32** [[C_ADDR]], align 4
219df729e2bSJohannes Doerfert // CHECK2-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 4
220*e2cfbfccSJohannes Doerfert // 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
225*e2cfbfccSJohannes 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
237df729e2bSJohannes Doerfert // CHECK2-NEXT:    [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32**
238df729e2bSJohannes Doerfert // CHECK2-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 4
239*e2cfbfccSJohannes Doerfert // 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*e2cfbfccSJohannes Doerfert // 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
248a2dbfb6bSGiorgis 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
251a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    store i32** [[C]], i32*** [[C_ADDR]], align 4
252a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP0:%.*]] = load i32**, i32*** [[C_ADDR]], align 4
253a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP1:%.*]] = load i32*, i32** [[TMP0]], align 4
254*e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    call void @_Z4workPi(i32* [[TMP1]]) #[[ATTR5]]
255a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    ret void
256a2dbfb6bSGiorgis Georgakoudis //
257a2dbfb6bSGiorgis Georgakoudis //
258a2dbfb6bSGiorgis Georgakoudis // CHECK2-LABEL: define {{[^@]+}}@_Z4workPi
259*e2cfbfccSJohannes 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*e2cfbfccSJohannes Doerfert // 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*e2cfbfccSJohannes Doerfert // 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
284*e2cfbfccSJohannes 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
296a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32***
297a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP5:%.*]] = load i32**, i32*** [[TMP4]], align 4
298*e2cfbfccSJohannes Doerfert // 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
303*e2cfbfccSJohannes 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
309*e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB1:[0-9]+]], i1 false, i1 true, i1 true)
310*e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP1]], -1
311*e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]]
312*e2cfbfccSJohannes Doerfert // CHECK3:       user_code.entry:
313*e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]])
314*e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    call void @_Z3usePi(i32* [[TMP0]]) #[[ATTR5:[0-9]+]]
315*e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB1]], i32 [[TMP2]], i32 2)
316*e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    [[TMP3:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i32 0, i32 0
317*e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    [[TMP4:%.*]] = bitcast i32* [[TMP0]] to i8*
318*e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    store i8* [[TMP4]], i8** [[TMP3]], align 4
319*e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    [[TMP5:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**
320*e2cfbfccSJohannes Doerfert // 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)
321*e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i1 false, i1 true)
322*e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    ret void
323*e2cfbfccSJohannes Doerfert // CHECK3:       worker.exit:
324a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    ret void
325a2dbfb6bSGiorgis Georgakoudis //
326a2dbfb6bSGiorgis Georgakoudis //
327a2dbfb6bSGiorgis Georgakoudis // CHECK3-LABEL: define {{[^@]+}}@_Z3usePi
328*e2cfbfccSJohannes 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)
335a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i32 0, i32 0
336a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP2:%.*]] = bitcast i32** [[C_ADDR]] to i8*
337a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    store i8* [[TMP2]], i8** [[TMP1]], align 4
338a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP3:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**
339df729e2bSJohannes Doerfert // 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*e2cfbfccSJohannes Doerfert // 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
348df729e2bSJohannes Doerfert // 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
351df729e2bSJohannes Doerfert // CHECK3-NEXT:    store i32* [[C]], i32** [[C_ADDR]], align 4
352df729e2bSJohannes Doerfert // CHECK3-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 4
353*e2cfbfccSJohannes Doerfert // 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
358*e2cfbfccSJohannes 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
370df729e2bSJohannes Doerfert // CHECK3-NEXT:    [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32**
371df729e2bSJohannes Doerfert // CHECK3-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 4
372*e2cfbfccSJohannes Doerfert // 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*e2cfbfccSJohannes Doerfert // 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
381a2dbfb6bSGiorgis 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
384a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    store i32** [[C]], i32*** [[C_ADDR]], align 4
385a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP0:%.*]] = load i32**, i32*** [[C_ADDR]], align 4
386a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP1:%.*]] = load i32*, i32** [[TMP0]], align 4
387*e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    call void @_Z4workPi(i32* [[TMP1]]) #[[ATTR5]]
388a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    ret void
389a2dbfb6bSGiorgis Georgakoudis //
390a2dbfb6bSGiorgis Georgakoudis //
391a2dbfb6bSGiorgis Georgakoudis // CHECK3-LABEL: define {{[^@]+}}@_Z4workPi
392*e2cfbfccSJohannes 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*e2cfbfccSJohannes Doerfert // 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*e2cfbfccSJohannes Doerfert // 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
417*e2cfbfccSJohannes 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
429a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32***
430a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP5:%.*]] = load i32**, i32*** [[TMP4]], align 4
431*e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    call void @__omp_outlined__1(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32** [[TMP5]]) #[[ATTR3]]
432a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    ret void
433a2dbfb6bSGiorgis Georgakoudis //
434