1 // 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 _
3 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK
4 // RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
5 // RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK
7 // expected-no-diagnostics
11 enum omp_allocator_handle_t
{
12 omp_null_allocator
= 0,
13 omp_default_mem_alloc
= 1,
14 omp_large_cap_mem_alloc
= 2,
15 omp_const_mem_alloc
= 3,
16 omp_high_bw_mem_alloc
= 4,
17 omp_low_lat_mem_alloc
= 5,
18 omp_cgroup_mem_alloc
= 6,
19 omp_pteam_mem_alloc
= 7,
20 omp_thread_mem_alloc
= 8,
21 KMP_ALLOCATOR_MAX_HANDLE
= __UINTPTR_MAX__
24 typedef enum omp_alloctrait_key_t
{ omp_atk_sync_hint
= 1,
25 omp_atk_alignment
= 2,
27 omp_atk_pool_size
= 4,
32 } omp_alloctrait_key_t
;
33 typedef enum omp_alloctrait_value_t
{
37 omp_atv_contended
= 3,
38 omp_atv_uncontended
= 4,
39 omp_atv_sequential
= 5,
45 omp_atv_default_mem_fb
= 11,
47 omp_atv_abort_fb
= 13,
48 omp_atv_allocator_fb
= 14,
49 omp_atv_environment
= 15,
52 omp_atv_interleaved
= 18
53 } omp_alloctrait_value_t
;
55 typedef struct omp_alloctrait_t
{
56 omp_alloctrait_key_t key
;
57 __UINTPTR_TYPE__ value
;
60 // Just map the traits variable as a firstprivate variable.
63 omp_alloctrait_t traits
[10];
64 omp_allocator_handle_t my_allocator
;
66 #pragma omp target teams loop uses_allocators(omp_null_allocator, omp_thread_mem_alloc, my_allocator(traits))
67 for (int i
= 0; i
< 10; ++i
)
72 // Destroy allocator upon exit from the region.
75 // CHECK-64-LABEL: define {{[^@]+}}@_Z3foov
76 // CHECK-64-SAME: () #[[ATTR0:[0-9]+]] {
77 // CHECK-64-NEXT: entry:
78 // CHECK-64-NEXT: [[TRAITS:%.*]] = alloca [10 x %struct.omp_alloctrait_t], align 8
79 // CHECK-64-NEXT: [[MY_ALLOCATOR:%.*]] = alloca i64, align 8
80 // CHECK-64-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8
81 // CHECK-64-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8
82 // CHECK-64-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8
83 // CHECK-64-NEXT: [[TMP:%.*]] = alloca i32, align 4
84 // CHECK-64-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0
85 // CHECK-64-NEXT: store ptr [[TRAITS]], ptr [[TMP0]], align 8
86 // CHECK-64-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0
87 // CHECK-64-NEXT: store ptr [[TRAITS]], ptr [[TMP1]], align 8
88 // CHECK-64-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0
89 // CHECK-64-NEXT: store ptr null, ptr [[TMP2]], align 8
90 // CHECK-64-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0
91 // CHECK-64-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0
92 // CHECK-64-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8
93 // CHECK-64-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0
94 // CHECK-64-NEXT: store i32 2, ptr [[TMP5]], align 4
95 // CHECK-64-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1
96 // CHECK-64-NEXT: store i32 1, ptr [[TMP6]], align 4
97 // CHECK-64-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2
98 // CHECK-64-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8
99 // CHECK-64-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3
100 // CHECK-64-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8
101 // CHECK-64-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4
102 // CHECK-64-NEXT: store ptr @.offload_sizes, ptr [[TMP9]], align 8
103 // CHECK-64-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5
104 // CHECK-64-NEXT: store ptr @.offload_maptypes, ptr [[TMP10]], align 8
105 // CHECK-64-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6
106 // CHECK-64-NEXT: store ptr null, ptr [[TMP11]], align 8
107 // CHECK-64-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7
108 // CHECK-64-NEXT: store ptr null, ptr [[TMP12]], align 8
109 // CHECK-64-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8
110 // CHECK-64-NEXT: store i64 10, ptr [[TMP13]], align 8
111 // CHECK-64-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9
112 // CHECK-64-NEXT: store i64 0, ptr [[TMP14]], align 8
113 // CHECK-64-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10
114 // CHECK-64-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4
115 // CHECK-64-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11
116 // CHECK-64-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4
117 // CHECK-64-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12
118 // CHECK-64-NEXT: store i32 0, ptr [[TMP17]], align 4
119 // CHECK-64-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB1:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3foov_l73.region_id, ptr [[KERNEL_ARGS]])
120 // CHECK-64-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0
121 // CHECK-64-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]]
122 // CHECK-64: omp_offload.failed:
123 // CHECK-64-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3foov_l73(ptr [[TRAITS]]) #[[ATTR2:[0-9]+]]
124 // CHECK-64-NEXT: br label [[OMP_OFFLOAD_CONT]]
125 // CHECK-64: omp_offload.cont:
126 // CHECK-64-NEXT: ret void
127 // CHECK-64-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3foov_l73
128 // CHECK-64-SAME: (ptr noundef nonnull align 8 dereferenceable(160) [[TRAITS:%.*]]) #[[ATTR1:[0-9]+]] {
129 // CHECK-64-NEXT: entry:
130 // CHECK-64-NEXT: [[TRAITS_ADDR:%.*]] = alloca ptr, align 8
131 // CHECK-64-NEXT: [[MY_ALLOCATOR:%.*]] = alloca i64, align 8
132 // CHECK-64-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
133 // CHECK-64-NEXT: store ptr [[TRAITS]], ptr [[TRAITS_ADDR]], align 8
134 // CHECK-64-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TRAITS_ADDR]], align 8
135 // CHECK-64-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8
136 // CHECK-64-NEXT: [[TMP3:%.*]] = call ptr @__kmpc_init_allocator(i32 [[TMP0]], ptr null, i32 10, ptr [[TMP2]])
137 // CHECK-64-NEXT: [[CONV:%.*]] = ptrtoint ptr [[TMP3]] to i64
138 // CHECK-64-NEXT: store i64 [[CONV]], ptr [[MY_ALLOCATOR]], align 8
139 // CHECK-64-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB1]], i32 0, ptr @.omp_outlined.)
140 // CHECK-64-NEXT: [[TMP4:%.*]] = load i64, ptr [[MY_ALLOCATOR]], align 8
141 // CHECK-64-NEXT: [[CONV1:%.*]] = inttoptr i64 [[TMP4]] to ptr
142 // CHECK-64-NEXT: call void @__kmpc_destroy_allocator(i32 [[TMP0]], ptr [[CONV1]])
143 // CHECK-64-NEXT: ret void
144 // CHECK-64-LABEL: define {{[^@]+}}@.omp_outlined.
145 // CHECK-64-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] {
146 // CHECK-64-NEXT: entry:
147 // CHECK-64-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
148 // CHECK-64-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
149 // CHECK-64-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
150 // CHECK-64-NEXT: [[TMP:%.*]] = alloca i32, align 4
151 // CHECK-64-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4
152 // CHECK-64-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4
153 // CHECK-64-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
154 // CHECK-64-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
155 // CHECK-64-NEXT: [[I:%.*]] = alloca i32, align 4
156 // CHECK-64-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
157 // CHECK-64-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
158 // CHECK-64-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4
159 // CHECK-64-NEXT: store i32 9, ptr [[DOTOMP_COMB_UB]], align 4
160 // CHECK-64-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
161 // CHECK-64-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
162 // CHECK-64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
163 // CHECK-64-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4
164 // CHECK-64-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
165 // CHECK-64-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4
166 // CHECK-64-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 9
167 // CHECK-64-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
168 // CHECK-64: cond.true:
169 // CHECK-64-NEXT: br label [[COND_END:%.*]]
170 // CHECK-64: cond.false:
171 // CHECK-64-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4
172 // CHECK-64-NEXT: br label [[COND_END]]
173 // CHECK-64: cond.end:
174 // CHECK-64-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ]
175 // CHECK-64-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4
176 // CHECK-64-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4
177 // CHECK-64-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4
178 // CHECK-64-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
179 // CHECK-64: omp.inner.for.cond:
180 // CHECK-64-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
181 // CHECK-64-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4
182 // CHECK-64-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]]
183 // CHECK-64-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
184 // CHECK-64: omp.inner.for.body:
185 // CHECK-64-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4
186 // CHECK-64-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
187 // CHECK-64-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4
188 // CHECK-64-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64
189 // CHECK-64-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @.omp_outlined..1, i64 [[TMP8]], i64 [[TMP10]])
190 // CHECK-64-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
191 // CHECK-64: omp.inner.for.inc:
192 // CHECK-64-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
193 // CHECK-64-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4
194 // CHECK-64-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]]
195 // CHECK-64-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4
196 // CHECK-64-NEXT: br label [[OMP_INNER_FOR_COND]]
197 // CHECK-64: omp.inner.for.end:
198 // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
199 // CHECK-64: omp.loop.exit:
200 // CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3:[0-9]+]], i32 [[TMP1]])
201 // CHECK-64-NEXT: ret void
202 // CHECK-64-LABEL: define {{[^@]+}}@.omp_outlined..1
203 // CHECK-64-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] {
204 // CHECK-64-NEXT: entry:
205 // CHECK-64-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
206 // CHECK-64-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
207 // CHECK-64-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8
208 // CHECK-64-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8
209 // CHECK-64-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
210 // CHECK-64-NEXT: [[TMP:%.*]] = alloca i32, align 4
211 // CHECK-64-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
212 // CHECK-64-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
213 // CHECK-64-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
214 // CHECK-64-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
215 // CHECK-64-NEXT: [[I:%.*]] = alloca i32, align 4
216 // CHECK-64-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
217 // CHECK-64-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
218 // CHECK-64-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8
219 // CHECK-64-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8
220 // CHECK-64-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
221 // CHECK-64-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4
222 // CHECK-64-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8
223 // CHECK-64-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32
224 // CHECK-64-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8
225 // CHECK-64-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32
226 // CHECK-64-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4
227 // CHECK-64-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4
228 // CHECK-64-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
229 // CHECK-64-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
230 // CHECK-64-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
231 // CHECK-64-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4
232 // CHECK-64-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
233 // CHECK-64-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
234 // CHECK-64-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 9
235 // CHECK-64-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
236 // CHECK-64: cond.true:
237 // CHECK-64-NEXT: br label [[COND_END:%.*]]
238 // CHECK-64: cond.false:
239 // CHECK-64-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
240 // CHECK-64-NEXT: br label [[COND_END]]
241 // CHECK-64: cond.end:
242 // CHECK-64-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ]
243 // CHECK-64-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
244 // CHECK-64-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
245 // CHECK-64-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4
246 // CHECK-64-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
247 // CHECK-64: omp.inner.for.cond:
248 // CHECK-64-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
249 // CHECK-64-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
250 // CHECK-64-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]]
251 // CHECK-64-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
252 // CHECK-64: omp.inner.for.body:
253 // CHECK-64-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
254 // CHECK-64-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1
255 // CHECK-64-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
256 // CHECK-64-NEXT: store i32 [[ADD]], ptr [[I]], align 4
257 // CHECK-64-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
258 // CHECK-64: omp.body.continue:
259 // CHECK-64-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
260 // CHECK-64: omp.inner.for.inc:
261 // CHECK-64-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
262 // CHECK-64-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1
263 // CHECK-64-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4
264 // CHECK-64-NEXT: br label [[OMP_INNER_FOR_COND]]
265 // CHECK-64: omp.inner.for.end:
266 // CHECK-64-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
267 // CHECK-64: omp.loop.exit:
268 // CHECK-64-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]])
269 // CHECK-64-NEXT: ret void
270 // CHECK-64-LABEL: define {{[^@]+}}@.omp_offloading.requires_reg
271 // CHECK-64-SAME: () #[[ATTR3:[0-9]+]] {
272 // CHECK-64-NEXT: entry:
273 // CHECK-64-NEXT: call void @__tgt_register_requires(i64 1)
274 // CHECK-64-NEXT: ret void
275 // CHECK-LABEL: define {{[^@]+}}@_Z3foov
276 // CHECK-SAME: () #[[ATTR0:[0-9]+]] {
277 // CHECK-NEXT: entry:
278 // CHECK-NEXT: [[TRAITS:%.*]] = alloca [10 x %struct.omp_alloctrait_t], align 8
279 // CHECK-NEXT: [[MY_ALLOCATOR:%.*]] = alloca i64, align 8
280 // CHECK-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8
281 // CHECK-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8
282 // CHECK-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8
283 // CHECK-NEXT: [[TMP:%.*]] = alloca i32, align 4
284 // CHECK-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8
285 // CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0
286 // CHECK-NEXT: store ptr [[TRAITS]], ptr [[TMP0]], align 8
287 // CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0
288 // CHECK-NEXT: store ptr [[TRAITS]], ptr [[TMP1]], align 8
289 // CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0
290 // CHECK-NEXT: store ptr null, ptr [[TMP2]], align 8
291 // CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0
292 // CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0
293 // CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0
294 // CHECK-NEXT: store i32 2, ptr [[TMP5]], align 4
295 // CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1
296 // CHECK-NEXT: store i32 1, ptr [[TMP6]], align 4
297 // CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2
298 // CHECK-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8
299 // CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3
300 // CHECK-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8
301 // CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4
302 // CHECK-NEXT: store ptr @.offload_sizes, ptr [[TMP9]], align 8
303 // CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5
304 // CHECK-NEXT: store ptr @.offload_maptypes, ptr [[TMP10]], align 8
305 // CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6
306 // CHECK-NEXT: store ptr null, ptr [[TMP11]], align 8
307 // CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7
308 // CHECK-NEXT: store ptr null, ptr [[TMP12]], align 8
309 // CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8
310 // CHECK-NEXT: store i64 10, ptr [[TMP13]], align 8
311 // CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9
312 // CHECK-NEXT: store i64 0, ptr [[TMP14]], align 8
313 // CHECK-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10
314 // CHECK-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4
315 // CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11
316 // CHECK-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4
317 // CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12
318 // CHECK-NEXT: store i32 0, ptr [[TMP17]], align 4
319 // CHECK-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB1:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3foov_l66.region_id, ptr [[KERNEL_ARGS]])
320 // CHECK-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0
321 // CHECK-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]]
322 // CHECK: omp_offload.failed:
323 // CHECK-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3foov_l66(ptr [[TRAITS]]) #[[ATTR2:[0-9]+]]
324 // CHECK-NEXT: br label [[OMP_OFFLOAD_CONT]]
325 // CHECK: omp_offload.cont:
326 // CHECK-NEXT: ret void
329 // CHECK-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3foov_l66
330 // CHECK-SAME: (ptr noundef nonnull align 8 dereferenceable(160) [[TRAITS:%.*]]) #[[ATTR1:[0-9]+]] {
331 // CHECK-NEXT: entry:
332 // CHECK-NEXT: [[TRAITS_ADDR:%.*]] = alloca ptr, align 8
333 // CHECK-NEXT: [[MY_ALLOCATOR:%.*]] = alloca i64, align 8
334 // CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
335 // CHECK-NEXT: store ptr [[TRAITS]], ptr [[TRAITS_ADDR]], align 8
336 // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TRAITS_ADDR]], align 8
337 // CHECK-NEXT: [[TMP2:%.*]] = call ptr @__kmpc_init_allocator(i32 [[TMP0]], ptr null, i32 10, ptr [[TMP1]])
338 // CHECK-NEXT: [[CONV:%.*]] = ptrtoint ptr [[TMP2]] to i64
339 // CHECK-NEXT: store i64 [[CONV]], ptr [[MY_ALLOCATOR]], align 8
340 // CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB1]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3foov_l66.omp_outlined)
341 // CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[MY_ALLOCATOR]], align 8
342 // CHECK-NEXT: [[CONV1:%.*]] = inttoptr i64 [[TMP3]] to ptr
343 // CHECK-NEXT: call void @__kmpc_destroy_allocator(i32 [[TMP0]], ptr [[CONV1]])
344 // CHECK-NEXT: ret void
347 // CHECK-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3foov_l66.omp_outlined
348 // CHECK-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] {
349 // CHECK-NEXT: entry:
350 // CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
351 // CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
352 // CHECK-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
353 // CHECK-NEXT: [[TMP:%.*]] = alloca i32, align 4
354 // CHECK-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4
355 // CHECK-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4
356 // CHECK-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
357 // CHECK-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
358 // CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
359 // CHECK-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
360 // CHECK-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
361 // CHECK-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4
362 // CHECK-NEXT: store i32 9, ptr [[DOTOMP_COMB_UB]], align 4
363 // CHECK-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
364 // CHECK-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
365 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
366 // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4
367 // CHECK-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
368 // CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4
369 // CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 9
370 // CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
372 // CHECK-NEXT: br label [[COND_END:%.*]]
373 // CHECK: cond.false:
374 // CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4
375 // CHECK-NEXT: br label [[COND_END]]
377 // CHECK-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ]
378 // CHECK-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4
379 // CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4
380 // CHECK-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4
381 // CHECK-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
382 // CHECK: omp.inner.for.cond:
383 // CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
384 // CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4
385 // CHECK-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]]
386 // CHECK-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
387 // CHECK: omp.inner.for.body:
388 // CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4
389 // CHECK-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
390 // CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4
391 // CHECK-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64
392 // CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3foov_l66.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]])
393 // CHECK-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
394 // CHECK: omp.inner.for.inc:
395 // CHECK-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
396 // CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4
397 // CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]]
398 // CHECK-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4
399 // CHECK-NEXT: br label [[OMP_INNER_FOR_COND]]
400 // CHECK: omp.inner.for.end:
401 // CHECK-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
402 // CHECK: omp.loop.exit:
403 // CHECK-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3:[0-9]+]], i32 [[TMP1]])
404 // CHECK-NEXT: ret void
407 // CHECK-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3foov_l66.omp_outlined.omp_outlined
408 // CHECK-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] {
409 // CHECK-NEXT: entry:
410 // CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
411 // CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
412 // CHECK-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8
413 // CHECK-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8
414 // CHECK-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
415 // CHECK-NEXT: [[TMP:%.*]] = alloca i32, align 4
416 // CHECK-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
417 // CHECK-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
418 // CHECK-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
419 // CHECK-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
420 // CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
421 // CHECK-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
422 // CHECK-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
423 // CHECK-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8
424 // CHECK-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8
425 // CHECK-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
426 // CHECK-NEXT: store i32 9, ptr [[DOTOMP_UB]], align 4
427 // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8
428 // CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32
429 // CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8
430 // CHECK-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32
431 // CHECK-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4
432 // CHECK-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4
433 // CHECK-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
434 // CHECK-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
435 // CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
436 // CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4
437 // CHECK-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB3]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
438 // CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
439 // CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 9
440 // CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
442 // CHECK-NEXT: br label [[COND_END:%.*]]
443 // CHECK: cond.false:
444 // CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
445 // CHECK-NEXT: br label [[COND_END]]
447 // CHECK-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ]
448 // CHECK-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
449 // CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
450 // CHECK-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4
451 // CHECK-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
452 // CHECK: omp.inner.for.cond:
453 // CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
454 // CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
455 // CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]]
456 // CHECK-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
457 // CHECK: omp.inner.for.body:
458 // CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
459 // CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1
460 // CHECK-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
461 // CHECK-NEXT: store i32 [[ADD]], ptr [[I]], align 4
462 // CHECK-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
463 // CHECK: omp.body.continue:
464 // CHECK-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
465 // CHECK: omp.inner.for.inc:
466 // CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
467 // CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1
468 // CHECK-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4
469 // CHECK-NEXT: br label [[OMP_INNER_FOR_COND]]
470 // CHECK: omp.inner.for.end:
471 // CHECK-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
472 // CHECK: omp.loop.exit:
473 // CHECK-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB3]], i32 [[TMP3]])
474 // CHECK-NEXT: ret void
477 // CHECK-LABEL: define {{[^@]+}}@.omp_offloading.requires_reg
478 // CHECK-SAME: () #[[ATTR3:[0-9]+]] {
479 // CHECK-NEXT: entry:
480 // CHECK-NEXT: call void @__tgt_register_requires(i64 1)
481 // CHECK-NEXT: ret void