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.
3*532dc62bSNikita Popov // RUN: %clang_cc1 -no-opaque-pointers -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
4*532dc62bSNikita Popov // RUN: %clang_cc1 -no-opaque-pointers -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
5*532dc62bSNikita Popov // RUN: %clang_cc1 -no-opaque-pointers -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
6*532dc62bSNikita Popov // RUN: %clang_cc1 -no-opaque-pointers -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
7*532dc62bSNikita Popov // RUN: %clang_cc1 -no-opaque-pointers -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
371b1c8d83Shyeongyu kim // CHECK1-SAME: (i32* noundef 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
43423d34f7SShilei Tian // CHECK1-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB1:[0-9]+]], i8 1, 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]])
4853d5757eSJoseph Huber // CHECK1-NEXT:    call void @_Z3usePi(i32* noundef [[TMP0]]) #[[ATTR7:[0-9]+]]
49ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP3:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0
50ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP4:%.*]] = bitcast i32* [[TMP0]] to i8*
51ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    store i8* [[TMP4]], i8** [[TMP3]], align 8
52ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP5:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**
53bc9c4d72SJoseph Huber // CHECK1-NEXT:    call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP2]], i32 1, i32 2, 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)
54423d34f7SShilei Tian // CHECK1-NEXT:    call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true)
55e2cfbfccSJohannes Doerfert // CHECK1-NEXT:    ret void
56e2cfbfccSJohannes Doerfert // CHECK1:       worker.exit:
57a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    ret void
58a2dbfb6bSGiorgis Georgakoudis //
59a2dbfb6bSGiorgis Georgakoudis //
60a2dbfb6bSGiorgis Georgakoudis // CHECK1-LABEL: define {{[^@]+}}@_Z3usePi
611b1c8d83Shyeongyu kim // CHECK1-SAME: (i32* noundef [[C:%.*]]) #[[ATTR1:[0-9]+]] {
62a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:  entry:
63a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[C_ADDR:%.*]] = alloca i32*, align 8
64a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[CAPTURED_VARS_ADDRS:%.*]] = alloca [1 x i8*], align 8
65df729e2bSJohannes Doerfert // CHECK1-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB2:[0-9]+]])
66a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    store i32* [[C]], i32** [[C_ADDR]], align 8
67ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0
68ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP2:%.*]] = bitcast i32** [[C_ADDR]] to i8*
69ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    store i8* [[TMP2]], i8** [[TMP1]], align 8
70ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP3:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**
71bc9c4d72SJoseph Huber // CHECK1-NEXT:    call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB2]], i32 [[TMP0]], i32 1, i32 2, 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)
72a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    ret void
73a2dbfb6bSGiorgis Georgakoudis //
74a2dbfb6bSGiorgis Georgakoudis //
75a2dbfb6bSGiorgis Georgakoudis // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined__
7653d5757eSJoseph Huber // CHECK1-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], i32* noundef nonnull align 4 dereferenceable(4) [[C:%.*]]) #[[ATTR2:[0-9]+]] {
77df729e2bSJohannes Doerfert // CHECK1-NEXT:  entry:
78df729e2bSJohannes Doerfert // CHECK1-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
79df729e2bSJohannes Doerfert // CHECK1-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
80ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    [[C_ADDR:%.*]] = alloca i32*, align 8
81df729e2bSJohannes Doerfert // CHECK1-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
82df729e2bSJohannes Doerfert // CHECK1-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
83ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    store i32* [[C]], i32** [[C_ADDR]], align 8
84ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 8
8553d5757eSJoseph Huber // CHECK1-NEXT:    call void @_Z3usePi(i32* noundef [[TMP0]]) #[[ATTR7]]
86df729e2bSJohannes Doerfert // CHECK1-NEXT:    ret void
87df729e2bSJohannes Doerfert //
88df729e2bSJohannes Doerfert //
89df729e2bSJohannes Doerfert // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined___wrapper
9053d5757eSJoseph Huber // CHECK1-SAME: (i16 noundef zeroext [[TMP0:%.*]], i32 noundef [[TMP1:%.*]]) #[[ATTR3:[0-9]+]] {
91df729e2bSJohannes Doerfert // CHECK1-NEXT:  entry:
92df729e2bSJohannes Doerfert // CHECK1-NEXT:    [[DOTADDR:%.*]] = alloca i16, align 2
93df729e2bSJohannes Doerfert // CHECK1-NEXT:    [[DOTADDR1:%.*]] = alloca i32, align 4
94df729e2bSJohannes Doerfert // CHECK1-NEXT:    [[DOTZERO_ADDR:%.*]] = alloca i32, align 4
95df729e2bSJohannes Doerfert // CHECK1-NEXT:    [[GLOBAL_ARGS:%.*]] = alloca i8**, align 8
96df729e2bSJohannes Doerfert // CHECK1-NEXT:    store i16 [[TMP0]], i16* [[DOTADDR]], align 2
97df729e2bSJohannes Doerfert // CHECK1-NEXT:    store i32 [[TMP1]], i32* [[DOTADDR1]], align 4
98f7de6962Shsmahesha // CHECK1-NEXT:    store i32 0, i32* [[DOTZERO_ADDR]], align 4
99df729e2bSJohannes Doerfert // CHECK1-NEXT:    call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]])
100df729e2bSJohannes Doerfert // CHECK1-NEXT:    [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 8
101df729e2bSJohannes Doerfert // CHECK1-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 0
102ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32**
103ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 8
10453d5757eSJoseph Huber // CHECK1-NEXT:    call void @__omp_outlined__(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]]) #[[ATTR4:[0-9]+]]
105df729e2bSJohannes Doerfert // CHECK1-NEXT:    ret void
106df729e2bSJohannes Doerfert //
107df729e2bSJohannes Doerfert //
108df729e2bSJohannes Doerfert // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined__1
10953d5757eSJoseph Huber // CHECK1-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], i32** noundef nonnull align 8 dereferenceable(8) [[C:%.*]]) #[[ATTR2]] {
110a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:  entry:
111a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
112a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
113ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    [[C_ADDR:%.*]] = alloca i32**, align 8
114a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
115a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
116ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    store i32** [[C]], i32*** [[C_ADDR]], align 8
117ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP0:%.*]] = load i32**, i32*** [[C_ADDR]], align 8
118ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP1:%.*]] = load i32*, i32** [[TMP0]], align 8
11953d5757eSJoseph Huber // CHECK1-NEXT:    call void @_Z4workPi(i32* noundef [[TMP1]]) #[[ATTR7]]
120a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    ret void
121a2dbfb6bSGiorgis Georgakoudis //
122a2dbfb6bSGiorgis Georgakoudis //
123a2dbfb6bSGiorgis Georgakoudis // CHECK1-LABEL: define {{[^@]+}}@_Z4workPi
1241b1c8d83Shyeongyu kim // CHECK1-SAME: (i32* noundef [[C:%.*]]) #[[ATTR1]] {
125a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:  entry:
126a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[C_ADDR:%.*]] = alloca i32*, align 8
127a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca i32, align 4
128a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[ATOMIC_TEMP1:%.*]] = alloca i32, align 4
129a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    store i32* [[C]], i32** [[C_ADDR]], align 8
130a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 8
131a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP1:%.*]] = bitcast i32* [[TMP0]] to i8*
132a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP2:%.*]] = bitcast i32* [[ATOMIC_TEMP]] to i8*
13353d5757eSJoseph Huber // CHECK1-NEXT:    call void @__atomic_load(i64 noundef 4, i8* noundef [[TMP1]], i8* noundef [[TMP2]], i32 noundef 0) #[[ATTR7]]
134a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    br label [[ATOMIC_CONT:%.*]]
135a2dbfb6bSGiorgis Georgakoudis // CHECK1:       atomic_cont:
136a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP3:%.*]] = load i32, i32* [[ATOMIC_TEMP]], align 4
137a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 1
138a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    store i32 [[ADD]], i32* [[ATOMIC_TEMP1]], align 4
139a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP4:%.*]] = bitcast i32* [[TMP0]] to i8*
140a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP5:%.*]] = bitcast i32* [[ATOMIC_TEMP]] to i8*
141a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP6:%.*]] = bitcast i32* [[ATOMIC_TEMP1]] to i8*
14253d5757eSJoseph Huber // CHECK1-NEXT:    [[CALL:%.*]] = call noundef zeroext i1 @__atomic_compare_exchange(i64 noundef 4, i8* noundef [[TMP4]], i8* noundef [[TMP5]], i8* noundef [[TMP6]], i32 noundef 0, i32 noundef 0) #[[ATTR7]]
143a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    br i1 [[CALL]], label [[ATOMIC_EXIT:%.*]], label [[ATOMIC_CONT]]
144a2dbfb6bSGiorgis Georgakoudis // CHECK1:       atomic_exit:
145a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    ret void
146a2dbfb6bSGiorgis Georgakoudis //
147a2dbfb6bSGiorgis Georgakoudis //
148df729e2bSJohannes Doerfert // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined__1_wrapper
14953d5757eSJoseph Huber // CHECK1-SAME: (i16 noundef zeroext [[TMP0:%.*]], i32 noundef [[TMP1:%.*]]) #[[ATTR3]] {
150a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:  entry:
151a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[DOTADDR:%.*]] = alloca i16, align 2
152a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[DOTADDR1:%.*]] = alloca i32, align 4
153a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[DOTZERO_ADDR:%.*]] = alloca i32, align 4
154a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[GLOBAL_ARGS:%.*]] = alloca i8**, align 8
155a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    store i16 [[TMP0]], i16* [[DOTADDR]], align 2
156a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    store i32 [[TMP1]], i32* [[DOTADDR1]], align 4
157f7de6962Shsmahesha // CHECK1-NEXT:    store i32 0, i32* [[DOTZERO_ADDR]], align 4
158a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]])
159a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 8
160a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 0
161ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32***
162ac90dfc4SGiorgis Georgakoudis // CHECK1-NEXT:    [[TMP5:%.*]] = load i32**, i32*** [[TMP4]], align 8
16353d5757eSJoseph Huber // CHECK1-NEXT:    call void @__omp_outlined__1(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32** [[TMP5]]) #[[ATTR4]]
164a2dbfb6bSGiorgis Georgakoudis // CHECK1-NEXT:    ret void
165a2dbfb6bSGiorgis Georgakoudis //
166a2dbfb6bSGiorgis Georgakoudis //
167a2dbfb6bSGiorgis Georgakoudis // CHECK2-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l25
1681b1c8d83Shyeongyu kim // CHECK2-SAME: (i32* noundef nonnull align 4 dereferenceable(4) [[C:%.*]]) #[[ATTR0:[0-9]+]] {
169a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:  entry:
170a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[C_ADDR:%.*]] = alloca i32*, align 4
171a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[CAPTURED_VARS_ADDRS:%.*]] = alloca [1 x i8*], align 4
172a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    store i32* [[C]], i32** [[C_ADDR]], align 4
173a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 4
174423d34f7SShilei Tian // CHECK2-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB1:[0-9]+]], i8 1, i1 true, i1 true)
175e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP1]], -1
176e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]]
177e2cfbfccSJohannes Doerfert // CHECK2:       user_code.entry:
178e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]])
17953d5757eSJoseph Huber // CHECK2-NEXT:    call void @_Z3usePi(i32* noundef [[TMP0]]) #[[ATTR7:[0-9]+]]
180ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP3:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i32 0, i32 0
181ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP4:%.*]] = bitcast i32* [[TMP0]] to i8*
182ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    store i8* [[TMP4]], i8** [[TMP3]], align 4
183ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP5:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**
184bc9c4d72SJoseph Huber // CHECK2-NEXT:    call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP2]], i32 1, i32 2, 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)
185423d34f7SShilei Tian // CHECK2-NEXT:    call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true)
186e2cfbfccSJohannes Doerfert // CHECK2-NEXT:    ret void
187e2cfbfccSJohannes Doerfert // CHECK2:       worker.exit:
188a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    ret void
189a2dbfb6bSGiorgis Georgakoudis //
190a2dbfb6bSGiorgis Georgakoudis //
191a2dbfb6bSGiorgis Georgakoudis // CHECK2-LABEL: define {{[^@]+}}@_Z3usePi
1921b1c8d83Shyeongyu kim // CHECK2-SAME: (i32* noundef [[C:%.*]]) #[[ATTR1:[0-9]+]] {
193a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:  entry:
194a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[C_ADDR:%.*]] = alloca i32*, align 4
195a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[CAPTURED_VARS_ADDRS:%.*]] = alloca [1 x i8*], align 4
196df729e2bSJohannes Doerfert // CHECK2-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB2:[0-9]+]])
197a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    store i32* [[C]], i32** [[C_ADDR]], align 4
198ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i32 0, i32 0
199ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP2:%.*]] = bitcast i32** [[C_ADDR]] to i8*
200ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    store i8* [[TMP2]], i8** [[TMP1]], align 4
201ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP3:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**
202bc9c4d72SJoseph Huber // CHECK2-NEXT:    call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB2]], i32 [[TMP0]], i32 1, i32 2, 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)
203a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    ret void
204a2dbfb6bSGiorgis Georgakoudis //
205a2dbfb6bSGiorgis Georgakoudis //
206a2dbfb6bSGiorgis Georgakoudis // CHECK2-LABEL: define {{[^@]+}}@__omp_outlined__
20753d5757eSJoseph Huber // CHECK2-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], i32* noundef nonnull align 4 dereferenceable(4) [[C:%.*]]) #[[ATTR2:[0-9]+]] {
208df729e2bSJohannes Doerfert // CHECK2-NEXT:  entry:
209df729e2bSJohannes Doerfert // CHECK2-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 4
210df729e2bSJohannes Doerfert // CHECK2-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 4
211ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    [[C_ADDR:%.*]] = alloca i32*, align 4
212df729e2bSJohannes Doerfert // CHECK2-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 4
213df729e2bSJohannes Doerfert // CHECK2-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 4
214ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    store i32* [[C]], i32** [[C_ADDR]], align 4
215ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 4
21653d5757eSJoseph Huber // CHECK2-NEXT:    call void @_Z3usePi(i32* noundef [[TMP0]]) #[[ATTR7]]
217df729e2bSJohannes Doerfert // CHECK2-NEXT:    ret void
218df729e2bSJohannes Doerfert //
219df729e2bSJohannes Doerfert //
220df729e2bSJohannes Doerfert // CHECK2-LABEL: define {{[^@]+}}@__omp_outlined___wrapper
22153d5757eSJoseph Huber // CHECK2-SAME: (i16 noundef zeroext [[TMP0:%.*]], i32 noundef [[TMP1:%.*]]) #[[ATTR3:[0-9]+]] {
222df729e2bSJohannes Doerfert // CHECK2-NEXT:  entry:
223df729e2bSJohannes Doerfert // CHECK2-NEXT:    [[DOTADDR:%.*]] = alloca i16, align 2
224df729e2bSJohannes Doerfert // CHECK2-NEXT:    [[DOTADDR1:%.*]] = alloca i32, align 4
225df729e2bSJohannes Doerfert // CHECK2-NEXT:    [[DOTZERO_ADDR:%.*]] = alloca i32, align 4
226df729e2bSJohannes Doerfert // CHECK2-NEXT:    [[GLOBAL_ARGS:%.*]] = alloca i8**, align 4
227df729e2bSJohannes Doerfert // CHECK2-NEXT:    store i16 [[TMP0]], i16* [[DOTADDR]], align 2
228df729e2bSJohannes Doerfert // CHECK2-NEXT:    store i32 [[TMP1]], i32* [[DOTADDR1]], align 4
229f7de6962Shsmahesha // CHECK2-NEXT:    store i32 0, i32* [[DOTZERO_ADDR]], align 4
230df729e2bSJohannes Doerfert // CHECK2-NEXT:    call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]])
231df729e2bSJohannes Doerfert // CHECK2-NEXT:    [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 4
232df729e2bSJohannes Doerfert // CHECK2-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i32 0
233ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32**
234ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 4
23553d5757eSJoseph Huber // CHECK2-NEXT:    call void @__omp_outlined__(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]]) #[[ATTR4:[0-9]+]]
236df729e2bSJohannes Doerfert // CHECK2-NEXT:    ret void
237df729e2bSJohannes Doerfert //
238df729e2bSJohannes Doerfert //
239df729e2bSJohannes Doerfert // CHECK2-LABEL: define {{[^@]+}}@__omp_outlined__1
24053d5757eSJoseph Huber // CHECK2-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], i32** noundef nonnull align 4 dereferenceable(4) [[C:%.*]]) #[[ATTR2]] {
241a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:  entry:
242a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 4
243a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 4
244ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    [[C_ADDR:%.*]] = alloca i32**, align 4
245a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 4
246a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 4
247ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    store i32** [[C]], i32*** [[C_ADDR]], align 4
248ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP0:%.*]] = load i32**, i32*** [[C_ADDR]], align 4
249ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP1:%.*]] = load i32*, i32** [[TMP0]], align 4
25053d5757eSJoseph Huber // CHECK2-NEXT:    call void @_Z4workPi(i32* noundef [[TMP1]]) #[[ATTR7]]
251a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    ret void
252a2dbfb6bSGiorgis Georgakoudis //
253a2dbfb6bSGiorgis Georgakoudis //
254a2dbfb6bSGiorgis Georgakoudis // CHECK2-LABEL: define {{[^@]+}}@_Z4workPi
2551b1c8d83Shyeongyu kim // CHECK2-SAME: (i32* noundef [[C:%.*]]) #[[ATTR1]] {
256a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:  entry:
257a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[C_ADDR:%.*]] = alloca i32*, align 4
258a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca i32, align 4
259a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[ATOMIC_TEMP1:%.*]] = alloca i32, align 4
260a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    store i32* [[C]], i32** [[C_ADDR]], align 4
261a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 4
262a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP1:%.*]] = bitcast i32* [[TMP0]] to i8*
263a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP2:%.*]] = bitcast i32* [[ATOMIC_TEMP]] to i8*
26453d5757eSJoseph Huber // CHECK2-NEXT:    call void @__atomic_load(i32 noundef 4, i8* noundef [[TMP1]], i8* noundef [[TMP2]], i32 noundef 0) #[[ATTR7]]
265a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    br label [[ATOMIC_CONT:%.*]]
266a2dbfb6bSGiorgis Georgakoudis // CHECK2:       atomic_cont:
267a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP3:%.*]] = load i32, i32* [[ATOMIC_TEMP]], align 4
268a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 1
269a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    store i32 [[ADD]], i32* [[ATOMIC_TEMP1]], align 4
270a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP4:%.*]] = bitcast i32* [[TMP0]] to i8*
271a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP5:%.*]] = bitcast i32* [[ATOMIC_TEMP]] to i8*
272a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP6:%.*]] = bitcast i32* [[ATOMIC_TEMP1]] to i8*
27353d5757eSJoseph Huber // CHECK2-NEXT:    [[CALL:%.*]] = call noundef zeroext i1 @__atomic_compare_exchange(i32 noundef 4, i8* noundef [[TMP4]], i8* noundef [[TMP5]], i8* noundef [[TMP6]], i32 noundef 0, i32 noundef 0) #[[ATTR7]]
274a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    br i1 [[CALL]], label [[ATOMIC_EXIT:%.*]], label [[ATOMIC_CONT]]
275a2dbfb6bSGiorgis Georgakoudis // CHECK2:       atomic_exit:
276a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    ret void
277a2dbfb6bSGiorgis Georgakoudis //
278a2dbfb6bSGiorgis Georgakoudis //
279df729e2bSJohannes Doerfert // CHECK2-LABEL: define {{[^@]+}}@__omp_outlined__1_wrapper
28053d5757eSJoseph Huber // CHECK2-SAME: (i16 noundef zeroext [[TMP0:%.*]], i32 noundef [[TMP1:%.*]]) #[[ATTR3]] {
281a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:  entry:
282a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[DOTADDR:%.*]] = alloca i16, align 2
283a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[DOTADDR1:%.*]] = alloca i32, align 4
284a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[DOTZERO_ADDR:%.*]] = alloca i32, align 4
285a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[GLOBAL_ARGS:%.*]] = alloca i8**, align 4
286a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    store i16 [[TMP0]], i16* [[DOTADDR]], align 2
287a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    store i32 [[TMP1]], i32* [[DOTADDR1]], align 4
288f7de6962Shsmahesha // CHECK2-NEXT:    store i32 0, i32* [[DOTZERO_ADDR]], align 4
289a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]])
290a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 4
291a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i32 0
292ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32***
293ac90dfc4SGiorgis Georgakoudis // CHECK2-NEXT:    [[TMP5:%.*]] = load i32**, i32*** [[TMP4]], align 4
29453d5757eSJoseph Huber // CHECK2-NEXT:    call void @__omp_outlined__1(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32** [[TMP5]]) #[[ATTR4]]
295a2dbfb6bSGiorgis Georgakoudis // CHECK2-NEXT:    ret void
296a2dbfb6bSGiorgis Georgakoudis //
297a2dbfb6bSGiorgis Georgakoudis //
298a2dbfb6bSGiorgis Georgakoudis // CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l25
2991b1c8d83Shyeongyu kim // CHECK3-SAME: (i32* noundef nonnull align 4 dereferenceable(4) [[C:%.*]]) #[[ATTR0:[0-9]+]] {
300a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:  entry:
301a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[C_ADDR:%.*]] = alloca i32*, align 4
302a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[CAPTURED_VARS_ADDRS:%.*]] = alloca [1 x i8*], align 4
303a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    store i32* [[C]], i32** [[C_ADDR]], align 4
304a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 4
305423d34f7SShilei Tian // CHECK3-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB1:[0-9]+]], i8 1, i1 true, i1 true)
306e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP1]], -1
307e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]]
308e2cfbfccSJohannes Doerfert // CHECK3:       user_code.entry:
309e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]])
31053d5757eSJoseph Huber // CHECK3-NEXT:    call void @_Z3usePi(i32* noundef [[TMP0]]) #[[ATTR7:[0-9]+]]
311ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP3:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i32 0, i32 0
312ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP4:%.*]] = bitcast i32* [[TMP0]] to i8*
313ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    store i8* [[TMP4]], i8** [[TMP3]], align 4
314ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP5:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**
315bc9c4d72SJoseph Huber // CHECK3-NEXT:    call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP2]], i32 1, i32 2, 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)
316423d34f7SShilei Tian // CHECK3-NEXT:    call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true)
317e2cfbfccSJohannes Doerfert // CHECK3-NEXT:    ret void
318e2cfbfccSJohannes Doerfert // CHECK3:       worker.exit:
319a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    ret void
320a2dbfb6bSGiorgis Georgakoudis //
321a2dbfb6bSGiorgis Georgakoudis //
322a2dbfb6bSGiorgis Georgakoudis // CHECK3-LABEL: define {{[^@]+}}@_Z3usePi
3231b1c8d83Shyeongyu kim // CHECK3-SAME: (i32* noundef [[C:%.*]]) #[[ATTR1:[0-9]+]] {
324a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:  entry:
325a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[C_ADDR:%.*]] = alloca i32*, align 4
326a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[CAPTURED_VARS_ADDRS:%.*]] = alloca [1 x i8*], align 4
327df729e2bSJohannes Doerfert // CHECK3-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB2:[0-9]+]])
328a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    store i32* [[C]], i32** [[C_ADDR]], align 4
329ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[CAPTURED_VARS_ADDRS]], i32 0, i32 0
330ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP2:%.*]] = bitcast i32** [[C_ADDR]] to i8*
331ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    store i8* [[TMP2]], i8** [[TMP1]], align 4
332ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP3:%.*]] = bitcast [1 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**
333bc9c4d72SJoseph Huber // CHECK3-NEXT:    call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB2]], i32 [[TMP0]], i32 1, i32 2, 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)
334a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    ret void
335a2dbfb6bSGiorgis Georgakoudis //
336a2dbfb6bSGiorgis Georgakoudis //
337a2dbfb6bSGiorgis Georgakoudis // CHECK3-LABEL: define {{[^@]+}}@__omp_outlined__
33853d5757eSJoseph Huber // CHECK3-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], i32* noundef nonnull align 4 dereferenceable(4) [[C:%.*]]) #[[ATTR2:[0-9]+]] {
339df729e2bSJohannes Doerfert // CHECK3-NEXT:  entry:
340df729e2bSJohannes Doerfert // CHECK3-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 4
341df729e2bSJohannes Doerfert // CHECK3-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 4
342ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    [[C_ADDR:%.*]] = alloca i32*, align 4
343df729e2bSJohannes Doerfert // CHECK3-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 4
344df729e2bSJohannes Doerfert // CHECK3-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 4
345ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    store i32* [[C]], i32** [[C_ADDR]], align 4
346ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 4
34753d5757eSJoseph Huber // CHECK3-NEXT:    call void @_Z3usePi(i32* noundef [[TMP0]]) #[[ATTR7]]
348df729e2bSJohannes Doerfert // CHECK3-NEXT:    ret void
349df729e2bSJohannes Doerfert //
350df729e2bSJohannes Doerfert //
351df729e2bSJohannes Doerfert // CHECK3-LABEL: define {{[^@]+}}@__omp_outlined___wrapper
35253d5757eSJoseph Huber // CHECK3-SAME: (i16 noundef zeroext [[TMP0:%.*]], i32 noundef [[TMP1:%.*]]) #[[ATTR3:[0-9]+]] {
353df729e2bSJohannes Doerfert // CHECK3-NEXT:  entry:
354df729e2bSJohannes Doerfert // CHECK3-NEXT:    [[DOTADDR:%.*]] = alloca i16, align 2
355df729e2bSJohannes Doerfert // CHECK3-NEXT:    [[DOTADDR1:%.*]] = alloca i32, align 4
356df729e2bSJohannes Doerfert // CHECK3-NEXT:    [[DOTZERO_ADDR:%.*]] = alloca i32, align 4
357df729e2bSJohannes Doerfert // CHECK3-NEXT:    [[GLOBAL_ARGS:%.*]] = alloca i8**, align 4
358df729e2bSJohannes Doerfert // CHECK3-NEXT:    store i16 [[TMP0]], i16* [[DOTADDR]], align 2
359df729e2bSJohannes Doerfert // CHECK3-NEXT:    store i32 [[TMP1]], i32* [[DOTADDR1]], align 4
360f7de6962Shsmahesha // CHECK3-NEXT:    store i32 0, i32* [[DOTZERO_ADDR]], align 4
361df729e2bSJohannes Doerfert // CHECK3-NEXT:    call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]])
362df729e2bSJohannes Doerfert // CHECK3-NEXT:    [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 4
363df729e2bSJohannes Doerfert // CHECK3-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i32 0
364ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32**
365ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 4
36653d5757eSJoseph Huber // CHECK3-NEXT:    call void @__omp_outlined__(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]]) #[[ATTR4:[0-9]+]]
367df729e2bSJohannes Doerfert // CHECK3-NEXT:    ret void
368df729e2bSJohannes Doerfert //
369df729e2bSJohannes Doerfert //
370df729e2bSJohannes Doerfert // CHECK3-LABEL: define {{[^@]+}}@__omp_outlined__1
37153d5757eSJoseph Huber // CHECK3-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], i32** noundef nonnull align 4 dereferenceable(4) [[C:%.*]]) #[[ATTR2]] {
372a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:  entry:
373a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 4
374a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 4
375ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    [[C_ADDR:%.*]] = alloca i32**, align 4
376a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 4
377a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 4
378ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    store i32** [[C]], i32*** [[C_ADDR]], align 4
379ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP0:%.*]] = load i32**, i32*** [[C_ADDR]], align 4
380ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP1:%.*]] = load i32*, i32** [[TMP0]], align 4
38153d5757eSJoseph Huber // CHECK3-NEXT:    call void @_Z4workPi(i32* noundef [[TMP1]]) #[[ATTR7]]
382a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    ret void
383a2dbfb6bSGiorgis Georgakoudis //
384a2dbfb6bSGiorgis Georgakoudis //
385a2dbfb6bSGiorgis Georgakoudis // CHECK3-LABEL: define {{[^@]+}}@_Z4workPi
3861b1c8d83Shyeongyu kim // CHECK3-SAME: (i32* noundef [[C:%.*]]) #[[ATTR1]] {
387a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:  entry:
388a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[C_ADDR:%.*]] = alloca i32*, align 4
389a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca i32, align 4
390a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[ATOMIC_TEMP1:%.*]] = alloca i32, align 4
391a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    store i32* [[C]], i32** [[C_ADDR]], align 4
392a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C_ADDR]], align 4
393a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP1:%.*]] = bitcast i32* [[TMP0]] to i8*
394a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP2:%.*]] = bitcast i32* [[ATOMIC_TEMP]] to i8*
39553d5757eSJoseph Huber // CHECK3-NEXT:    call void @__atomic_load(i32 noundef 4, i8* noundef [[TMP1]], i8* noundef [[TMP2]], i32 noundef 0) #[[ATTR7]]
396a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    br label [[ATOMIC_CONT:%.*]]
397a2dbfb6bSGiorgis Georgakoudis // CHECK3:       atomic_cont:
398a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP3:%.*]] = load i32, i32* [[ATOMIC_TEMP]], align 4
399a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 1
400a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    store i32 [[ADD]], i32* [[ATOMIC_TEMP1]], align 4
401a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP4:%.*]] = bitcast i32* [[TMP0]] to i8*
402a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP5:%.*]] = bitcast i32* [[ATOMIC_TEMP]] to i8*
403a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP6:%.*]] = bitcast i32* [[ATOMIC_TEMP1]] to i8*
40453d5757eSJoseph Huber // CHECK3-NEXT:    [[CALL:%.*]] = call noundef zeroext i1 @__atomic_compare_exchange(i32 noundef 4, i8* noundef [[TMP4]], i8* noundef [[TMP5]], i8* noundef [[TMP6]], i32 noundef 0, i32 noundef 0) #[[ATTR7]]
405a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    br i1 [[CALL]], label [[ATOMIC_EXIT:%.*]], label [[ATOMIC_CONT]]
406a2dbfb6bSGiorgis Georgakoudis // CHECK3:       atomic_exit:
407a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    ret void
408a2dbfb6bSGiorgis Georgakoudis //
409a2dbfb6bSGiorgis Georgakoudis //
410df729e2bSJohannes Doerfert // CHECK3-LABEL: define {{[^@]+}}@__omp_outlined__1_wrapper
41153d5757eSJoseph Huber // CHECK3-SAME: (i16 noundef zeroext [[TMP0:%.*]], i32 noundef [[TMP1:%.*]]) #[[ATTR3]] {
412a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:  entry:
413a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[DOTADDR:%.*]] = alloca i16, align 2
414a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[DOTADDR1:%.*]] = alloca i32, align 4
415a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[DOTZERO_ADDR:%.*]] = alloca i32, align 4
416a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[GLOBAL_ARGS:%.*]] = alloca i8**, align 4
417a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    store i16 [[TMP0]], i16* [[DOTADDR]], align 2
418a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    store i32 [[TMP1]], i32* [[DOTADDR1]], align 4
419f7de6962Shsmahesha // CHECK3-NEXT:    store i32 0, i32* [[DOTZERO_ADDR]], align 4
420a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]])
421a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 4
422a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i32 0
423ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32***
424ac90dfc4SGiorgis Georgakoudis // CHECK3-NEXT:    [[TMP5:%.*]] = load i32**, i32*** [[TMP4]], align 4
42553d5757eSJoseph Huber // CHECK3-NEXT:    call void @__omp_outlined__1(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32** [[TMP5]]) #[[ATTR4]]
426a2dbfb6bSGiorgis Georgakoudis // CHECK3-NEXT:    ret void
427a2dbfb6bSGiorgis Georgakoudis //
428