xref: /llvm-project/clang/test/OpenMP/sections_lastprivate_codegen.cpp (revision 94473f4db6a6f5f12d7c4081455b5b596094eac5)
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 _
2 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1
3 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
4 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK1
5 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK3
6 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK4
7 // RUN: %clang_cc1 -verify -fopenmp -DOMP5 -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK5
8 // RUN: %clang_cc1 -fopenmp -DOMP5 -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
9 // RUN: %clang_cc1 -fopenmp -DOMP5 -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK5
10 // RUN: %clang_cc1 -verify -fopenmp -DOMP5 -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK3
11 // RUN: %clang_cc1 -verify -fopenmp -DOMP5 -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK4
12 
13 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}"
14 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
15 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}"
16 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}"
17 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}"
18 // RUN: %clang_cc1 -verify -fopenmp-simd -DOMP5 -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}"
19 // RUN: %clang_cc1 -fopenmp-simd -DOMP5 -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
20 // RUN: %clang_cc1 -fopenmp-simd -DOMP5 -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}"
21 // RUN: %clang_cc1 -verify -fopenmp-simd -DOMP5 -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}"
22 // RUN: %clang_cc1 -verify -fopenmp-simd -DOMP5 -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}"
23 // expected-no-diagnostics
24 #ifndef HEADER
25 #define HEADER
26 
27 #ifdef OMP5
28 #define CONDITIONAL conditional :
29 #else
30 #define CONDITIONAL
31 #endif //OMP5
32 
33 template <class T>
34 struct S {
35   T f;
36   S(T a) : f(a) {}
37   S() : f() {}
38   S<T> &operator=(const S<T> &);
39   operator T() { return T(); }
40   ~S() {}
41 };
42 
43 volatile int g = 1212;
44 
45 template <typename T>
46 T tmain() {
47   S<T> test;
48   T t_var = T();
49   T vec[] = {1, 2};
50   S<T> s_arr[] = {1, 2};
51   S<T> var(3);
52 #pragma omp parallel
53 #pragma omp sections lastprivate(t_var, vec, s_arr, var)
54   {
55     vec[0] = t_var;
56 #pragma omp section
57     s_arr[0] = var;
58   }
59   return T();
60 }
61 
62 namespace A {
63 double x;
64 }
65 namespace B {
66 using A::x;
67 }
68 
69 int main() {
70   static int sivar;
71 #ifdef LAMBDA
72   [&]() {
73 #pragma omp parallel
74 #pragma omp sections lastprivate(g, sivar)
75   {
76 
77 
78 
79     {
80       g = 1;
81       sivar = 13;
82     }
83     // Check for final copying of private values back to original vars.
84     // Actual copying.
85 
86     // original g=private_g;
87 
88     // original sivar = private sivar;
89 #pragma omp section
90     [&]() {
91       g = 2;
92       sivar = 23;
93     }();
94   }
95   }();
96   return 0;
97 #elif defined(BLOCKS)
98   ^{
99 #pragma omp parallel
100 #pragma omp sections lastprivate(g, sivar)
101   {
102 
103 
104     {
105       g = 1;
106       sivar = 17;
107     }
108     // Check for final copying of private values back to original vars.
109     // Actual copying.
110 
111     // original g=private_g;
112 
113     // original sivar = private sivar;
114 #pragma omp section
115     ^{
116       g = 2;
117       sivar = 29;
118     }();
119   }
120   }();
121   return 0;
122 #else
123   S<float> test;
124   int t_var = 0;
125   int vec[] = {1, 2};
126   S<float> s_arr[] = {1, 2};
127   S<float> var(3);
128 #pragma omp parallel
129 #pragma omp sections lastprivate(t_var, vec, s_arr, var, sivar)
130   {
131     {
132     vec[0] = t_var;
133     s_arr[0] = var;
134     sivar = 31;
135     }
136   }
137 #pragma omp parallel
138 #pragma omp sections lastprivate(CONDITIONAL A::x, B::x)
139   {
140     A::x++;
141 #pragma omp section
142     ;
143   }
144   return tmain<int>();
145 #endif
146 }
147 
148 
149 
150 
151 
152 
153 // <Skip loop body>
154 
155 
156 
157 
158 // Check for default initialization.
159 
160 // <Skip loop body>
161 
162 
163 
164 // Check for final copying of private values back to original vars.
165 // Actual copying.
166 
167 // original x=private_x;
168 
169 
170 
171 
172 // Check for default initialization.
173 // <Skip loop body>
174 
175 // Check for final copying of private values back to original vars.
176 // Actual copying.
177 
178 // original t_var=private_t_var;
179 
180 // original vec[]=private_vec[];
181 
182 // original s_arr[]=private_s_arr[];
183 
184 // CHK: [[SIVAR_REF:%.+]] = getelementptr [[S_INT_TY]], ptr [[S_ARR_BEGIN]], i{{[0-9]+}} 4
185 // CHK: store iptr [[SIVAR]], i{{[0-9]+}} [[SIVAR_REF]]
186 
187 
188 // original var=private_var;
189 #endif
190 
191 // CHECK1-LABEL: define {{[^@]+}}@main
192 // CHECK1-SAME: () #[[ATTR0:[0-9]+]] {
193 // CHECK1-NEXT:  entry:
194 // CHECK1-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
195 // CHECK1-NEXT:    [[TEST:%.*]] = alloca [[STRUCT_S:%.*]], align 4
196 // CHECK1-NEXT:    [[T_VAR:%.*]] = alloca i32, align 4
197 // CHECK1-NEXT:    [[VEC:%.*]] = alloca [2 x i32], align 4
198 // CHECK1-NEXT:    [[S_ARR:%.*]] = alloca [2 x %struct.S], align 4
199 // CHECK1-NEXT:    [[VAR:%.*]] = alloca [[STRUCT_S]], align 4
200 // CHECK1-NEXT:    store i32 0, ptr [[RETVAL]], align 4
201 // CHECK1-NEXT:    call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]])
202 // CHECK1-NEXT:    store i32 0, ptr [[T_VAR]], align 4
203 // CHECK1-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false)
204 // CHECK1-NEXT:    call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00)
205 // CHECK1-NEXT:    [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1
206 // CHECK1-NEXT:    call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00)
207 // CHECK1-NEXT:    call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], float noundef 3.000000e+00)
208 // CHECK1-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3:[0-9]+]], i32 5, ptr @main.omp_outlined, ptr [[T_VAR]], ptr [[VEC]], ptr [[S_ARR]], ptr [[VAR]], ptr @_ZZ4mainE5sivar)
209 // CHECK1-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 0, ptr @main.omp_outlined.1)
210 // CHECK1-NEXT:    [[CALL:%.*]] = call noundef i32 @_Z5tmainIiET_v()
211 // CHECK1-NEXT:    store i32 [[CALL]], ptr [[RETVAL]], align 4
212 // CHECK1-NEXT:    call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR4:[0-9]+]]
213 // CHECK1-NEXT:    [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0
214 // CHECK1-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN]], i64 2
215 // CHECK1-NEXT:    br label [[ARRAYDESTROY_BODY:%.*]]
216 // CHECK1:       arraydestroy.body:
217 // CHECK1-NEXT:    [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP0]], [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
218 // CHECK1-NEXT:    [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
219 // CHECK1-NEXT:    call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
220 // CHECK1-NEXT:    [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN]]
221 // CHECK1-NEXT:    br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]]
222 // CHECK1:       arraydestroy.done1:
223 // CHECK1-NEXT:    call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) #[[ATTR4]]
224 // CHECK1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[RETVAL]], align 4
225 // CHECK1-NEXT:    ret i32 [[TMP1]]
226 //
227 //
228 // CHECK1-LABEL: define {{[^@]+}}@_ZN1SIfEC1Ev
229 // CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] align 2 {
230 // CHECK1-NEXT:  entry:
231 // CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
232 // CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
233 // CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
234 // CHECK1-NEXT:    call void @_ZN1SIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]])
235 // CHECK1-NEXT:    ret void
236 //
237 //
238 // CHECK1-LABEL: define {{[^@]+}}@_ZN1SIfEC1Ef
239 // CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], float noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
240 // CHECK1-NEXT:  entry:
241 // CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
242 // CHECK1-NEXT:    [[A_ADDR:%.*]] = alloca float, align 4
243 // CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
244 // CHECK1-NEXT:    store float [[A]], ptr [[A_ADDR]], align 4
245 // CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
246 // CHECK1-NEXT:    [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4
247 // CHECK1-NEXT:    call void @_ZN1SIfEC2Ef(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], float noundef [[TMP0]])
248 // CHECK1-NEXT:    ret void
249 //
250 //
251 // CHECK1-LABEL: define {{[^@]+}}@main.omp_outlined
252 // CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[T_VAR:%.*]], ptr noundef nonnull align 4 dereferenceable(8) [[VEC:%.*]], ptr noundef nonnull align 4 dereferenceable(8) [[S_ARR:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[VAR:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[SIVAR:%.*]]) #[[ATTR3:[0-9]+]] {
253 // CHECK1-NEXT:  entry:
254 // CHECK1-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
255 // CHECK1-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
256 // CHECK1-NEXT:    [[T_VAR_ADDR:%.*]] = alloca ptr, align 8
257 // CHECK1-NEXT:    [[VEC_ADDR:%.*]] = alloca ptr, align 8
258 // CHECK1-NEXT:    [[S_ARR_ADDR:%.*]] = alloca ptr, align 8
259 // CHECK1-NEXT:    [[VAR_ADDR:%.*]] = alloca ptr, align 8
260 // CHECK1-NEXT:    [[SIVAR_ADDR:%.*]] = alloca ptr, align 8
261 // CHECK1-NEXT:    [[DOTOMP_SECTIONS_LB_:%.*]] = alloca i32, align 4
262 // CHECK1-NEXT:    [[DOTOMP_SECTIONS_UB_:%.*]] = alloca i32, align 4
263 // CHECK1-NEXT:    [[DOTOMP_SECTIONS_ST_:%.*]] = alloca i32, align 4
264 // CHECK1-NEXT:    [[DOTOMP_SECTIONS_IL_:%.*]] = alloca i32, align 4
265 // CHECK1-NEXT:    [[DOTOMP_SECTIONS_IV_:%.*]] = alloca i32, align 4
266 // CHECK1-NEXT:    [[T_VAR1:%.*]] = alloca i32, align 4
267 // CHECK1-NEXT:    [[VEC2:%.*]] = alloca [2 x i32], align 4
268 // CHECK1-NEXT:    [[S_ARR3:%.*]] = alloca [2 x %struct.S], align 4
269 // CHECK1-NEXT:    [[VAR4:%.*]] = alloca [[STRUCT_S:%.*]], align 4
270 // CHECK1-NEXT:    [[SIVAR5:%.*]] = alloca i32, align 4
271 // CHECK1-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
272 // CHECK1-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
273 // CHECK1-NEXT:    store ptr [[T_VAR]], ptr [[T_VAR_ADDR]], align 8
274 // CHECK1-NEXT:    store ptr [[VEC]], ptr [[VEC_ADDR]], align 8
275 // CHECK1-NEXT:    store ptr [[S_ARR]], ptr [[S_ARR_ADDR]], align 8
276 // CHECK1-NEXT:    store ptr [[VAR]], ptr [[VAR_ADDR]], align 8
277 // CHECK1-NEXT:    store ptr [[SIVAR]], ptr [[SIVAR_ADDR]], align 8
278 // CHECK1-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[T_VAR_ADDR]], align 8
279 // CHECK1-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[VEC_ADDR]], align 8
280 // CHECK1-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[S_ARR_ADDR]], align 8
281 // CHECK1-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[VAR_ADDR]], align 8
282 // CHECK1-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[SIVAR_ADDR]], align 8
283 // CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_LB_]], align 4
284 // CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_UB_]], align 4
285 // CHECK1-NEXT:    store i32 1, ptr [[DOTOMP_SECTIONS_ST_]], align 4
286 // CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_IL_]], align 4
287 // CHECK1-NEXT:    [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR3]], i32 0, i32 0
288 // CHECK1-NEXT:    [[ARRAYCTOR_END:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN]], i64 2
289 // CHECK1-NEXT:    br label [[ARRAYCTOR_LOOP:%.*]]
290 // CHECK1:       arrayctor.loop:
291 // CHECK1-NEXT:    [[ARRAYCTOR_CUR:%.*]] = phi ptr [ [[ARRAY_BEGIN]], [[ENTRY:%.*]] ], [ [[ARRAYCTOR_NEXT:%.*]], [[ARRAYCTOR_LOOP]] ]
292 // CHECK1-NEXT:    call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYCTOR_CUR]])
293 // CHECK1-NEXT:    [[ARRAYCTOR_NEXT]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYCTOR_CUR]], i64 1
294 // CHECK1-NEXT:    [[ARRAYCTOR_DONE:%.*]] = icmp eq ptr [[ARRAYCTOR_NEXT]], [[ARRAYCTOR_END]]
295 // CHECK1-NEXT:    br i1 [[ARRAYCTOR_DONE]], label [[ARRAYCTOR_CONT:%.*]], label [[ARRAYCTOR_LOOP]]
296 // CHECK1:       arrayctor.cont:
297 // CHECK1-NEXT:    call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]])
298 // CHECK1-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
299 // CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4
300 // CHECK1-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP6]], i32 34, ptr [[DOTOMP_SECTIONS_IL_]], ptr [[DOTOMP_SECTIONS_LB_]], ptr [[DOTOMP_SECTIONS_UB_]], ptr [[DOTOMP_SECTIONS_ST_]], i32 1, i32 1)
301 // CHECK1-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_UB_]], align 4
302 // CHECK1-NEXT:    [[TMP8:%.*]] = icmp slt i32 [[TMP7]], 0
303 // CHECK1-NEXT:    [[TMP9:%.*]] = select i1 [[TMP8]], i32 [[TMP7]], i32 0
304 // CHECK1-NEXT:    store i32 [[TMP9]], ptr [[DOTOMP_SECTIONS_UB_]], align 4
305 // CHECK1-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_LB_]], align 4
306 // CHECK1-NEXT:    store i32 [[TMP10]], ptr [[DOTOMP_SECTIONS_IV_]], align 4
307 // CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
308 // CHECK1:       omp.inner.for.cond:
309 // CHECK1-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
310 // CHECK1-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_UB_]], align 4
311 // CHECK1-NEXT:    [[CMP:%.*]] = icmp sle i32 [[TMP11]], [[TMP12]]
312 // CHECK1-NEXT:    br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
313 // CHECK1:       omp.inner.for.body:
314 // CHECK1-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
315 // CHECK1-NEXT:    switch i32 [[TMP13]], label [[DOTOMP_SECTIONS_EXIT:%.*]] [
316 // CHECK1-NEXT:      i32 0, label [[DOTOMP_SECTIONS_CASE:%.*]]
317 // CHECK1-NEXT:    ]
318 // CHECK1:       .omp.sections.case:
319 // CHECK1-NEXT:    [[TMP14:%.*]] = load i32, ptr [[T_VAR1]], align 4
320 // CHECK1-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i32], ptr [[VEC2]], i64 0, i64 0
321 // CHECK1-NEXT:    store i32 [[TMP14]], ptr [[ARRAYIDX]], align 4
322 // CHECK1-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR3]], i64 0, i64 0
323 // CHECK1-NEXT:    [[CALL:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN1SIfEaSERKS0_(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYIDX6]], ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]])
324 // CHECK1-NEXT:    store i32 31, ptr [[SIVAR5]], align 4
325 // CHECK1-NEXT:    br label [[DOTOMP_SECTIONS_EXIT]]
326 // CHECK1:       .omp.sections.exit:
327 // CHECK1-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
328 // CHECK1:       omp.inner.for.inc:
329 // CHECK1-NEXT:    [[TMP15:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
330 // CHECK1-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP15]], 1
331 // CHECK1-NEXT:    store i32 [[INC]], ptr [[DOTOMP_SECTIONS_IV_]], align 4
332 // CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND]]
333 // CHECK1:       omp.inner.for.end:
334 // CHECK1-NEXT:    [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
335 // CHECK1-NEXT:    [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4
336 // CHECK1-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]])
337 // CHECK1-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IL_]], align 4
338 // CHECK1-NEXT:    [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0
339 // CHECK1-NEXT:    br i1 [[TMP19]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]]
340 // CHECK1:       .omp.lastprivate.then:
341 // CHECK1-NEXT:    [[TMP20:%.*]] = load i32, ptr [[T_VAR1]], align 4
342 // CHECK1-NEXT:    store i32 [[TMP20]], ptr [[TMP0]], align 4
343 // CHECK1-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[TMP1]], ptr align 4 [[VEC2]], i64 8, i1 false)
344 // CHECK1-NEXT:    [[ARRAY_BEGIN7:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[TMP2]], i32 0, i32 0
345 // CHECK1-NEXT:    [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN7]], i64 2
346 // CHECK1-NEXT:    [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN7]], [[TMP21]]
347 // CHECK1-NEXT:    br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE9:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
348 // CHECK1:       omp.arraycpy.body:
349 // CHECK1-NEXT:    [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi ptr [ [[S_ARR3]], [[DOTOMP_LASTPRIVATE_THEN]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
350 // CHECK1-NEXT:    [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi ptr [ [[ARRAY_BEGIN7]], [[DOTOMP_LASTPRIVATE_THEN]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
351 // CHECK1-NEXT:    [[CALL8:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN1SIfEaSERKS0_(ptr noundef nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr noundef nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]])
352 // CHECK1-NEXT:    [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S]], ptr [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
353 // CHECK1-NEXT:    [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[STRUCT_S]], ptr [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
354 // CHECK1-NEXT:    [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq ptr [[OMP_ARRAYCPY_DEST_ELEMENT]], [[TMP21]]
355 // CHECK1-NEXT:    br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYCPY_DONE9]], label [[OMP_ARRAYCPY_BODY]]
356 // CHECK1:       omp.arraycpy.done9:
357 // CHECK1-NEXT:    [[CALL10:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN1SIfEaSERKS0_(ptr noundef nonnull align 4 dereferenceable(4) [[TMP3]], ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]])
358 // CHECK1-NEXT:    [[TMP22:%.*]] = load i32, ptr [[SIVAR5]], align 4
359 // CHECK1-NEXT:    store i32 [[TMP22]], ptr [[TMP4]], align 4
360 // CHECK1-NEXT:    br label [[DOTOMP_LASTPRIVATE_DONE]]
361 // CHECK1:       .omp.lastprivate.done:
362 // CHECK1-NEXT:    call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]]) #[[ATTR4]]
363 // CHECK1-NEXT:    [[ARRAY_BEGIN11:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR3]], i32 0, i32 0
364 // CHECK1-NEXT:    [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN11]], i64 2
365 // CHECK1-NEXT:    br label [[ARRAYDESTROY_BODY:%.*]]
366 // CHECK1:       arraydestroy.body:
367 // CHECK1-NEXT:    [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP23]], [[DOTOMP_LASTPRIVATE_DONE]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
368 // CHECK1-NEXT:    [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
369 // CHECK1-NEXT:    call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
370 // CHECK1-NEXT:    [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN11]]
371 // CHECK1-NEXT:    br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE12:%.*]], label [[ARRAYDESTROY_BODY]]
372 // CHECK1:       arraydestroy.done12:
373 // CHECK1-NEXT:    [[TMP24:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
374 // CHECK1-NEXT:    [[TMP25:%.*]] = load i32, ptr [[TMP24]], align 4
375 // CHECK1-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB2:[0-9]+]], i32 [[TMP25]])
376 // CHECK1-NEXT:    ret void
377 //
378 //
379 // CHECK1-LABEL: define {{[^@]+}}@_ZN1SIfED1Ev
380 // CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
381 // CHECK1-NEXT:  entry:
382 // CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
383 // CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
384 // CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
385 // CHECK1-NEXT:    call void @_ZN1SIfED2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR4]]
386 // CHECK1-NEXT:    ret void
387 //
388 //
389 // CHECK1-LABEL: define {{[^@]+}}@main.omp_outlined.1
390 // CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR3]] {
391 // CHECK1-NEXT:  entry:
392 // CHECK1-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
393 // CHECK1-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
394 // CHECK1-NEXT:    [[DOTOMP_SECTIONS_LB_:%.*]] = alloca i32, align 4
395 // CHECK1-NEXT:    [[DOTOMP_SECTIONS_UB_:%.*]] = alloca i32, align 4
396 // CHECK1-NEXT:    [[DOTOMP_SECTIONS_ST_:%.*]] = alloca i32, align 4
397 // CHECK1-NEXT:    [[DOTOMP_SECTIONS_IL_:%.*]] = alloca i32, align 4
398 // CHECK1-NEXT:    [[DOTOMP_SECTIONS_IV_:%.*]] = alloca i32, align 4
399 // CHECK1-NEXT:    [[X:%.*]] = alloca double, align 8
400 // CHECK1-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
401 // CHECK1-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
402 // CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_LB_]], align 4
403 // CHECK1-NEXT:    store i32 1, ptr [[DOTOMP_SECTIONS_UB_]], align 4
404 // CHECK1-NEXT:    store i32 1, ptr [[DOTOMP_SECTIONS_ST_]], align 4
405 // CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_IL_]], align 4
406 // CHECK1-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
407 // CHECK1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4
408 // CHECK1-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 34, ptr [[DOTOMP_SECTIONS_IL_]], ptr [[DOTOMP_SECTIONS_LB_]], ptr [[DOTOMP_SECTIONS_UB_]], ptr [[DOTOMP_SECTIONS_ST_]], i32 1, i32 1)
409 // CHECK1-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_UB_]], align 4
410 // CHECK1-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 1
411 // CHECK1-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 1
412 // CHECK1-NEXT:    store i32 [[TMP4]], ptr [[DOTOMP_SECTIONS_UB_]], align 4
413 // CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_LB_]], align 4
414 // CHECK1-NEXT:    store i32 [[TMP5]], ptr [[DOTOMP_SECTIONS_IV_]], align 4
415 // CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
416 // CHECK1:       omp.inner.for.cond:
417 // CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
418 // CHECK1-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_UB_]], align 4
419 // CHECK1-NEXT:    [[CMP:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]]
420 // CHECK1-NEXT:    br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
421 // CHECK1:       omp.inner.for.body:
422 // CHECK1-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
423 // CHECK1-NEXT:    switch i32 [[TMP8]], label [[DOTOMP_SECTIONS_EXIT:%.*]] [
424 // CHECK1-NEXT:      i32 0, label [[DOTOMP_SECTIONS_CASE:%.*]]
425 // CHECK1-NEXT:      i32 1, label [[DOTOMP_SECTIONS_CASE1:%.*]]
426 // CHECK1-NEXT:    ]
427 // CHECK1:       .omp.sections.case:
428 // CHECK1-NEXT:    [[TMP9:%.*]] = load double, ptr [[X]], align 8
429 // CHECK1-NEXT:    [[INC:%.*]] = fadd double [[TMP9]], 1.000000e+00
430 // CHECK1-NEXT:    store double [[INC]], ptr [[X]], align 8
431 // CHECK1-NEXT:    br label [[DOTOMP_SECTIONS_EXIT]]
432 // CHECK1:       .omp.sections.case1:
433 // CHECK1-NEXT:    br label [[DOTOMP_SECTIONS_EXIT]]
434 // CHECK1:       .omp.sections.exit:
435 // CHECK1-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
436 // CHECK1:       omp.inner.for.inc:
437 // CHECK1-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
438 // CHECK1-NEXT:    [[INC2:%.*]] = add nsw i32 [[TMP10]], 1
439 // CHECK1-NEXT:    store i32 [[INC2]], ptr [[DOTOMP_SECTIONS_IV_]], align 4
440 // CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND]]
441 // CHECK1:       omp.inner.for.end:
442 // CHECK1-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]])
443 // CHECK1-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IL_]], align 4
444 // CHECK1-NEXT:    [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0
445 // CHECK1-NEXT:    br i1 [[TMP12]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]]
446 // CHECK1:       .omp.lastprivate.then:
447 // CHECK1-NEXT:    [[TMP13:%.*]] = load double, ptr [[X]], align 8
448 // CHECK1-NEXT:    store double [[TMP13]], ptr @_ZN1A1xE, align 8
449 // CHECK1-NEXT:    br label [[DOTOMP_LASTPRIVATE_DONE]]
450 // CHECK1:       .omp.lastprivate.done:
451 // CHECK1-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP1]])
452 // CHECK1-NEXT:    ret void
453 //
454 //
455 // CHECK1-LABEL: define {{[^@]+}}@_Z5tmainIiET_v
456 // CHECK1-SAME: () #[[ATTR1]] {
457 // CHECK1-NEXT:  entry:
458 // CHECK1-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
459 // CHECK1-NEXT:    [[TEST:%.*]] = alloca [[STRUCT_S_0:%.*]], align 4
460 // CHECK1-NEXT:    [[T_VAR:%.*]] = alloca i32, align 4
461 // CHECK1-NEXT:    [[VEC:%.*]] = alloca [2 x i32], align 4
462 // CHECK1-NEXT:    [[S_ARR:%.*]] = alloca [2 x %struct.S.0], align 4
463 // CHECK1-NEXT:    [[VAR:%.*]] = alloca [[STRUCT_S_0]], align 4
464 // CHECK1-NEXT:    call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]])
465 // CHECK1-NEXT:    store i32 0, ptr [[T_VAR]], align 4
466 // CHECK1-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false)
467 // CHECK1-NEXT:    call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1)
468 // CHECK1-NEXT:    [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1
469 // CHECK1-NEXT:    call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2)
470 // CHECK1-NEXT:    call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3)
471 // CHECK1-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 4, ptr @_Z5tmainIiET_v.omp_outlined, ptr [[T_VAR]], ptr [[VEC]], ptr [[S_ARR]], ptr [[VAR]])
472 // CHECK1-NEXT:    store i32 0, ptr [[RETVAL]], align 4
473 // CHECK1-NEXT:    call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR4]]
474 // CHECK1-NEXT:    [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0
475 // CHECK1-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN]], i64 2
476 // CHECK1-NEXT:    br label [[ARRAYDESTROY_BODY:%.*]]
477 // CHECK1:       arraydestroy.body:
478 // CHECK1-NEXT:    [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP0]], [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
479 // CHECK1-NEXT:    [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
480 // CHECK1-NEXT:    call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
481 // CHECK1-NEXT:    [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN]]
482 // CHECK1-NEXT:    br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]]
483 // CHECK1:       arraydestroy.done1:
484 // CHECK1-NEXT:    call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) #[[ATTR4]]
485 // CHECK1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[RETVAL]], align 4
486 // CHECK1-NEXT:    ret i32 [[TMP1]]
487 //
488 //
489 // CHECK1-LABEL: define {{[^@]+}}@_ZN1SIfEC2Ev
490 // CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
491 // CHECK1-NEXT:  entry:
492 // CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
493 // CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
494 // CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
495 // CHECK1-NEXT:    [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0
496 // CHECK1-NEXT:    store float 0.000000e+00, ptr [[F]], align 4
497 // CHECK1-NEXT:    ret void
498 //
499 //
500 // CHECK1-LABEL: define {{[^@]+}}@_ZN1SIfED2Ev
501 // CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
502 // CHECK1-NEXT:  entry:
503 // CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
504 // CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
505 // CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
506 // CHECK1-NEXT:    ret void
507 //
508 //
509 // CHECK1-LABEL: define {{[^@]+}}@_ZN1SIfEC2Ef
510 // CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], float noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
511 // CHECK1-NEXT:  entry:
512 // CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
513 // CHECK1-NEXT:    [[A_ADDR:%.*]] = alloca float, align 4
514 // CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
515 // CHECK1-NEXT:    store float [[A]], ptr [[A_ADDR]], align 4
516 // CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
517 // CHECK1-NEXT:    [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0
518 // CHECK1-NEXT:    [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4
519 // CHECK1-NEXT:    store float [[TMP0]], ptr [[F]], align 4
520 // CHECK1-NEXT:    ret void
521 //
522 //
523 // CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiEC1Ev
524 // CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
525 // CHECK1-NEXT:  entry:
526 // CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
527 // CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
528 // CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
529 // CHECK1-NEXT:    call void @_ZN1SIiEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]])
530 // CHECK1-NEXT:    ret void
531 //
532 //
533 // CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiEC1Ei
534 // CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
535 // CHECK1-NEXT:  entry:
536 // CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
537 // CHECK1-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
538 // CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
539 // CHECK1-NEXT:    store i32 [[A]], ptr [[A_ADDR]], align 4
540 // CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
541 // CHECK1-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
542 // CHECK1-NEXT:    call void @_ZN1SIiEC2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]])
543 // CHECK1-NEXT:    ret void
544 //
545 //
546 // CHECK1-LABEL: define {{[^@]+}}@_Z5tmainIiET_v.omp_outlined
547 // CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[T_VAR:%.*]], ptr noundef nonnull align 4 dereferenceable(8) [[VEC:%.*]], ptr noundef nonnull align 4 dereferenceable(8) [[S_ARR:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[VAR:%.*]]) #[[ATTR3]] {
548 // CHECK1-NEXT:  entry:
549 // CHECK1-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
550 // CHECK1-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
551 // CHECK1-NEXT:    [[T_VAR_ADDR:%.*]] = alloca ptr, align 8
552 // CHECK1-NEXT:    [[VEC_ADDR:%.*]] = alloca ptr, align 8
553 // CHECK1-NEXT:    [[S_ARR_ADDR:%.*]] = alloca ptr, align 8
554 // CHECK1-NEXT:    [[VAR_ADDR:%.*]] = alloca ptr, align 8
555 // CHECK1-NEXT:    [[DOTOMP_SECTIONS_LB_:%.*]] = alloca i32, align 4
556 // CHECK1-NEXT:    [[DOTOMP_SECTIONS_UB_:%.*]] = alloca i32, align 4
557 // CHECK1-NEXT:    [[DOTOMP_SECTIONS_ST_:%.*]] = alloca i32, align 4
558 // CHECK1-NEXT:    [[DOTOMP_SECTIONS_IL_:%.*]] = alloca i32, align 4
559 // CHECK1-NEXT:    [[DOTOMP_SECTIONS_IV_:%.*]] = alloca i32, align 4
560 // CHECK1-NEXT:    [[T_VAR1:%.*]] = alloca i32, align 4
561 // CHECK1-NEXT:    [[VEC2:%.*]] = alloca [2 x i32], align 4
562 // CHECK1-NEXT:    [[S_ARR3:%.*]] = alloca [2 x %struct.S.0], align 4
563 // CHECK1-NEXT:    [[VAR4:%.*]] = alloca [[STRUCT_S_0:%.*]], align 4
564 // CHECK1-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
565 // CHECK1-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
566 // CHECK1-NEXT:    store ptr [[T_VAR]], ptr [[T_VAR_ADDR]], align 8
567 // CHECK1-NEXT:    store ptr [[VEC]], ptr [[VEC_ADDR]], align 8
568 // CHECK1-NEXT:    store ptr [[S_ARR]], ptr [[S_ARR_ADDR]], align 8
569 // CHECK1-NEXT:    store ptr [[VAR]], ptr [[VAR_ADDR]], align 8
570 // CHECK1-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[T_VAR_ADDR]], align 8
571 // CHECK1-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[VEC_ADDR]], align 8
572 // CHECK1-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[S_ARR_ADDR]], align 8
573 // CHECK1-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[VAR_ADDR]], align 8
574 // CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_LB_]], align 4
575 // CHECK1-NEXT:    store i32 1, ptr [[DOTOMP_SECTIONS_UB_]], align 4
576 // CHECK1-NEXT:    store i32 1, ptr [[DOTOMP_SECTIONS_ST_]], align 4
577 // CHECK1-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_IL_]], align 4
578 // CHECK1-NEXT:    [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR3]], i32 0, i32 0
579 // CHECK1-NEXT:    [[ARRAYCTOR_END:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN]], i64 2
580 // CHECK1-NEXT:    br label [[ARRAYCTOR_LOOP:%.*]]
581 // CHECK1:       arrayctor.loop:
582 // CHECK1-NEXT:    [[ARRAYCTOR_CUR:%.*]] = phi ptr [ [[ARRAY_BEGIN]], [[ENTRY:%.*]] ], [ [[ARRAYCTOR_NEXT:%.*]], [[ARRAYCTOR_LOOP]] ]
583 // CHECK1-NEXT:    call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYCTOR_CUR]])
584 // CHECK1-NEXT:    [[ARRAYCTOR_NEXT]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYCTOR_CUR]], i64 1
585 // CHECK1-NEXT:    [[ARRAYCTOR_DONE:%.*]] = icmp eq ptr [[ARRAYCTOR_NEXT]], [[ARRAYCTOR_END]]
586 // CHECK1-NEXT:    br i1 [[ARRAYCTOR_DONE]], label [[ARRAYCTOR_CONT:%.*]], label [[ARRAYCTOR_LOOP]]
587 // CHECK1:       arrayctor.cont:
588 // CHECK1-NEXT:    call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]])
589 // CHECK1-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
590 // CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4
591 // CHECK1-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP5]], i32 34, ptr [[DOTOMP_SECTIONS_IL_]], ptr [[DOTOMP_SECTIONS_LB_]], ptr [[DOTOMP_SECTIONS_UB_]], ptr [[DOTOMP_SECTIONS_ST_]], i32 1, i32 1)
592 // CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_UB_]], align 4
593 // CHECK1-NEXT:    [[TMP7:%.*]] = icmp slt i32 [[TMP6]], 1
594 // CHECK1-NEXT:    [[TMP8:%.*]] = select i1 [[TMP7]], i32 [[TMP6]], i32 1
595 // CHECK1-NEXT:    store i32 [[TMP8]], ptr [[DOTOMP_SECTIONS_UB_]], align 4
596 // CHECK1-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_LB_]], align 4
597 // CHECK1-NEXT:    store i32 [[TMP9]], ptr [[DOTOMP_SECTIONS_IV_]], align 4
598 // CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
599 // CHECK1:       omp.inner.for.cond:
600 // CHECK1-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
601 // CHECK1-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_UB_]], align 4
602 // CHECK1-NEXT:    [[CMP:%.*]] = icmp sle i32 [[TMP10]], [[TMP11]]
603 // CHECK1-NEXT:    br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
604 // CHECK1:       omp.inner.for.body:
605 // CHECK1-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
606 // CHECK1-NEXT:    switch i32 [[TMP12]], label [[DOTOMP_SECTIONS_EXIT:%.*]] [
607 // CHECK1-NEXT:      i32 0, label [[DOTOMP_SECTIONS_CASE:%.*]]
608 // CHECK1-NEXT:      i32 1, label [[DOTOMP_SECTIONS_CASE5:%.*]]
609 // CHECK1-NEXT:    ]
610 // CHECK1:       .omp.sections.case:
611 // CHECK1-NEXT:    [[TMP13:%.*]] = load i32, ptr [[T_VAR1]], align 4
612 // CHECK1-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i32], ptr [[VEC2]], i64 0, i64 0
613 // CHECK1-NEXT:    store i32 [[TMP13]], ptr [[ARRAYIDX]], align 4
614 // CHECK1-NEXT:    br label [[DOTOMP_SECTIONS_EXIT]]
615 // CHECK1:       .omp.sections.case5:
616 // CHECK1-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR3]], i64 0, i64 0
617 // CHECK1-NEXT:    [[CALL:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN1SIiEaSERKS0_(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYIDX6]], ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]])
618 // CHECK1-NEXT:    br label [[DOTOMP_SECTIONS_EXIT]]
619 // CHECK1:       .omp.sections.exit:
620 // CHECK1-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
621 // CHECK1:       omp.inner.for.inc:
622 // CHECK1-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
623 // CHECK1-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP14]], 1
624 // CHECK1-NEXT:    store i32 [[INC]], ptr [[DOTOMP_SECTIONS_IV_]], align 4
625 // CHECK1-NEXT:    br label [[OMP_INNER_FOR_COND]]
626 // CHECK1:       omp.inner.for.end:
627 // CHECK1-NEXT:    [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
628 // CHECK1-NEXT:    [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4
629 // CHECK1-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]])
630 // CHECK1-NEXT:    [[TMP17:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IL_]], align 4
631 // CHECK1-NEXT:    [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0
632 // CHECK1-NEXT:    br i1 [[TMP18]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]]
633 // CHECK1:       .omp.lastprivate.then:
634 // CHECK1-NEXT:    [[TMP19:%.*]] = load i32, ptr [[T_VAR1]], align 4
635 // CHECK1-NEXT:    store i32 [[TMP19]], ptr [[TMP0]], align 4
636 // CHECK1-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[TMP1]], ptr align 4 [[VEC2]], i64 8, i1 false)
637 // CHECK1-NEXT:    [[ARRAY_BEGIN7:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[TMP2]], i32 0, i32 0
638 // CHECK1-NEXT:    [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN7]], i64 2
639 // CHECK1-NEXT:    [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN7]], [[TMP20]]
640 // CHECK1-NEXT:    br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE9:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
641 // CHECK1:       omp.arraycpy.body:
642 // CHECK1-NEXT:    [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi ptr [ [[S_ARR3]], [[DOTOMP_LASTPRIVATE_THEN]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
643 // CHECK1-NEXT:    [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi ptr [ [[ARRAY_BEGIN7]], [[DOTOMP_LASTPRIVATE_THEN]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
644 // CHECK1-NEXT:    [[CALL8:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN1SIiEaSERKS0_(ptr noundef nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr noundef nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]])
645 // CHECK1-NEXT:    [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S_0]], ptr [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
646 // CHECK1-NEXT:    [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[STRUCT_S_0]], ptr [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
647 // CHECK1-NEXT:    [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq ptr [[OMP_ARRAYCPY_DEST_ELEMENT]], [[TMP20]]
648 // CHECK1-NEXT:    br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYCPY_DONE9]], label [[OMP_ARRAYCPY_BODY]]
649 // CHECK1:       omp.arraycpy.done9:
650 // CHECK1-NEXT:    [[CALL10:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN1SIiEaSERKS0_(ptr noundef nonnull align 4 dereferenceable(4) [[TMP3]], ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]])
651 // CHECK1-NEXT:    br label [[DOTOMP_LASTPRIVATE_DONE]]
652 // CHECK1:       .omp.lastprivate.done:
653 // CHECK1-NEXT:    call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]]) #[[ATTR4]]
654 // CHECK1-NEXT:    [[ARRAY_BEGIN11:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR3]], i32 0, i32 0
655 // CHECK1-NEXT:    [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN11]], i64 2
656 // CHECK1-NEXT:    br label [[ARRAYDESTROY_BODY:%.*]]
657 // CHECK1:       arraydestroy.body:
658 // CHECK1-NEXT:    [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP21]], [[DOTOMP_LASTPRIVATE_DONE]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
659 // CHECK1-NEXT:    [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
660 // CHECK1-NEXT:    call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
661 // CHECK1-NEXT:    [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN11]]
662 // CHECK1-NEXT:    br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE12:%.*]], label [[ARRAYDESTROY_BODY]]
663 // CHECK1:       arraydestroy.done12:
664 // CHECK1-NEXT:    [[TMP22:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
665 // CHECK1-NEXT:    [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4
666 // CHECK1-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP23]])
667 // CHECK1-NEXT:    ret void
668 //
669 //
670 // CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiED1Ev
671 // CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
672 // CHECK1-NEXT:  entry:
673 // CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
674 // CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
675 // CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
676 // CHECK1-NEXT:    call void @_ZN1SIiED2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR4]]
677 // CHECK1-NEXT:    ret void
678 //
679 //
680 // CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiEC2Ev
681 // CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
682 // CHECK1-NEXT:  entry:
683 // CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
684 // CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
685 // CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
686 // CHECK1-NEXT:    [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S_0:%.*]], ptr [[THIS1]], i32 0, i32 0
687 // CHECK1-NEXT:    store i32 0, ptr [[F]], align 4
688 // CHECK1-NEXT:    ret void
689 //
690 //
691 // CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiEC2Ei
692 // CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
693 // CHECK1-NEXT:  entry:
694 // CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
695 // CHECK1-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
696 // CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
697 // CHECK1-NEXT:    store i32 [[A]], ptr [[A_ADDR]], align 4
698 // CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
699 // CHECK1-NEXT:    [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S_0:%.*]], ptr [[THIS1]], i32 0, i32 0
700 // CHECK1-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
701 // CHECK1-NEXT:    store i32 [[TMP0]], ptr [[F]], align 4
702 // CHECK1-NEXT:    ret void
703 //
704 //
705 // CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiED2Ev
706 // CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
707 // CHECK1-NEXT:  entry:
708 // CHECK1-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
709 // CHECK1-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
710 // CHECK1-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
711 // CHECK1-NEXT:    ret void
712 //
713 //
714 // CHECK3-LABEL: define {{[^@]+}}@main
715 // CHECK3-SAME: () #[[ATTR0:[0-9]+]] {
716 // CHECK3-NEXT:  entry:
717 // CHECK3-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
718 // CHECK3-NEXT:    [[REF_TMP:%.*]] = alloca [[CLASS_ANON:%.*]], align 8
719 // CHECK3-NEXT:    store i32 0, ptr [[RETVAL]], align 4
720 // CHECK3-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw [[CLASS_ANON]], ptr [[REF_TMP]], i32 0, i32 0
721 // CHECK3-NEXT:    store ptr @_ZZ4mainE5sivar, ptr [[TMP0]], align 8
722 // CHECK3-NEXT:    call void @"_ZZ4mainENK3$_0clEv"(ptr noundef nonnull align 8 dereferenceable(8) [[REF_TMP]])
723 // CHECK3-NEXT:    ret i32 0
724 //
725 //
726 // CHECK4-LABEL: define {{[^@]+}}@main
727 // CHECK4-SAME: () #[[ATTR0:[0-9]+]] {
728 // CHECK4-NEXT:  entry:
729 // CHECK4-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
730 // CHECK4-NEXT:    [[BLOCK:%.*]] = alloca <{ ptr, i32, i32, ptr, ptr, i32 }>, align 8
731 // CHECK4-NEXT:    store i32 0, ptr [[RETVAL]], align 4
732 // CHECK4-NEXT:    [[BLOCK_ISA:%.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, i32 }>, ptr [[BLOCK]], i32 0, i32 0
733 // CHECK4-NEXT:    store ptr @_NSConcreteStackBlock, ptr [[BLOCK_ISA]], align 8
734 // CHECK4-NEXT:    [[BLOCK_FLAGS:%.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, i32 }>, ptr [[BLOCK]], i32 0, i32 1
735 // CHECK4-NEXT:    store i32 1073741824, ptr [[BLOCK_FLAGS]], align 8
736 // CHECK4-NEXT:    [[BLOCK_RESERVED:%.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, i32 }>, ptr [[BLOCK]], i32 0, i32 2
737 // CHECK4-NEXT:    store i32 0, ptr [[BLOCK_RESERVED]], align 4
738 // CHECK4-NEXT:    [[BLOCK_INVOKE:%.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, i32 }>, ptr [[BLOCK]], i32 0, i32 3
739 // CHECK4-NEXT:    store ptr @__main_block_invoke, ptr [[BLOCK_INVOKE]], align 8
740 // CHECK4-NEXT:    [[BLOCK_DESCRIPTOR:%.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, i32 }>, ptr [[BLOCK]], i32 0, i32 4
741 // CHECK4-NEXT:    store ptr @__block_descriptor_tmp.1, ptr [[BLOCK_DESCRIPTOR]], align 8
742 // CHECK4-NEXT:    [[BLOCK_CAPTURED:%.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, i32 }>, ptr [[BLOCK]], i32 0, i32 5
743 // CHECK4-NEXT:    [[TMP0:%.*]] = load i32, ptr @_ZZ4mainE5sivar, align 4
744 // CHECK4-NEXT:    store i32 [[TMP0]], ptr [[BLOCK_CAPTURED]], align 8
745 // CHECK4-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT___BLOCK_LITERAL_GENERIC:%.*]], ptr [[BLOCK]], i32 0, i32 3
746 // CHECK4-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8
747 // CHECK4-NEXT:    call void [[TMP2]](ptr noundef [[BLOCK]])
748 // CHECK4-NEXT:    ret i32 0
749 //
750 //
751 // CHECK4-LABEL: define {{[^@]+}}@__main_block_invoke
752 // CHECK4-SAME: (ptr noundef [[DOTBLOCK_DESCRIPTOR:%.*]]) #[[ATTR1:[0-9]+]] {
753 // CHECK4-NEXT:  entry:
754 // CHECK4-NEXT:    [[DOTBLOCK_DESCRIPTOR_ADDR:%.*]] = alloca ptr, align 8
755 // CHECK4-NEXT:    [[BLOCK_ADDR:%.*]] = alloca ptr, align 8
756 // CHECK4-NEXT:    store ptr [[DOTBLOCK_DESCRIPTOR]], ptr [[DOTBLOCK_DESCRIPTOR_ADDR]], align 8
757 // CHECK4-NEXT:    store ptr [[DOTBLOCK_DESCRIPTOR]], ptr [[BLOCK_ADDR]], align 8
758 // CHECK4-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3:[0-9]+]], i32 1, ptr @__main_block_invoke.omp_outlined, ptr @_ZZ4mainE5sivar)
759 // CHECK4-NEXT:    ret void
760 //
761 //
762 // CHECK4-LABEL: define {{[^@]+}}@__main_block_invoke.omp_outlined
763 // CHECK4-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[SIVAR:%.*]]) #[[ATTR2:[0-9]+]] {
764 // CHECK4-NEXT:  entry:
765 // CHECK4-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
766 // CHECK4-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
767 // CHECK4-NEXT:    [[SIVAR_ADDR:%.*]] = alloca ptr, align 8
768 // CHECK4-NEXT:    [[DOTOMP_SECTIONS_LB_:%.*]] = alloca i32, align 4
769 // CHECK4-NEXT:    [[DOTOMP_SECTIONS_UB_:%.*]] = alloca i32, align 4
770 // CHECK4-NEXT:    [[DOTOMP_SECTIONS_ST_:%.*]] = alloca i32, align 4
771 // CHECK4-NEXT:    [[DOTOMP_SECTIONS_IL_:%.*]] = alloca i32, align 4
772 // CHECK4-NEXT:    [[DOTOMP_SECTIONS_IV_:%.*]] = alloca i32, align 4
773 // CHECK4-NEXT:    [[G:%.*]] = alloca i32, align 4
774 // CHECK4-NEXT:    [[SIVAR1:%.*]] = alloca i32, align 4
775 // CHECK4-NEXT:    [[BLOCK:%.*]] = alloca <{ ptr, i32, i32, ptr, ptr, i32, i32 }>, align 8
776 // CHECK4-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
777 // CHECK4-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
778 // CHECK4-NEXT:    store ptr [[SIVAR]], ptr [[SIVAR_ADDR]], align 8
779 // CHECK4-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[SIVAR_ADDR]], align 8
780 // CHECK4-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_LB_]], align 4
781 // CHECK4-NEXT:    store i32 1, ptr [[DOTOMP_SECTIONS_UB_]], align 4
782 // CHECK4-NEXT:    store i32 1, ptr [[DOTOMP_SECTIONS_ST_]], align 4
783 // CHECK4-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_IL_]], align 4
784 // CHECK4-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
785 // CHECK4-NEXT:    [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 4
786 // CHECK4-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP2]], i32 34, ptr [[DOTOMP_SECTIONS_IL_]], ptr [[DOTOMP_SECTIONS_LB_]], ptr [[DOTOMP_SECTIONS_UB_]], ptr [[DOTOMP_SECTIONS_ST_]], i32 1, i32 1)
787 // CHECK4-NEXT:    [[TMP3:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_UB_]], align 4
788 // CHECK4-NEXT:    [[TMP4:%.*]] = icmp slt i32 [[TMP3]], 1
789 // CHECK4-NEXT:    [[TMP5:%.*]] = select i1 [[TMP4]], i32 [[TMP3]], i32 1
790 // CHECK4-NEXT:    store i32 [[TMP5]], ptr [[DOTOMP_SECTIONS_UB_]], align 4
791 // CHECK4-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_LB_]], align 4
792 // CHECK4-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_SECTIONS_IV_]], align 4
793 // CHECK4-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
794 // CHECK4:       omp.inner.for.cond:
795 // CHECK4-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
796 // CHECK4-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_UB_]], align 4
797 // CHECK4-NEXT:    [[CMP:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]]
798 // CHECK4-NEXT:    br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
799 // CHECK4:       omp.inner.for.body:
800 // CHECK4-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
801 // CHECK4-NEXT:    switch i32 [[TMP9]], label [[DOTOMP_SECTIONS_EXIT:%.*]] [
802 // CHECK4-NEXT:      i32 0, label [[DOTOMP_SECTIONS_CASE:%.*]]
803 // CHECK4-NEXT:      i32 1, label [[DOTOMP_SECTIONS_CASE2:%.*]]
804 // CHECK4-NEXT:    ]
805 // CHECK4:       .omp.sections.case:
806 // CHECK4-NEXT:    store i32 1, ptr [[G]], align 4
807 // CHECK4-NEXT:    store i32 17, ptr [[SIVAR1]], align 4
808 // CHECK4-NEXT:    br label [[DOTOMP_SECTIONS_EXIT]]
809 // CHECK4:       .omp.sections.case2:
810 // CHECK4-NEXT:    [[BLOCK_ISA:%.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, i32, i32 }>, ptr [[BLOCK]], i32 0, i32 0
811 // CHECK4-NEXT:    store ptr @_NSConcreteStackBlock, ptr [[BLOCK_ISA]], align 8
812 // CHECK4-NEXT:    [[BLOCK_FLAGS:%.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, i32, i32 }>, ptr [[BLOCK]], i32 0, i32 1
813 // CHECK4-NEXT:    store i32 1073741824, ptr [[BLOCK_FLAGS]], align 8
814 // CHECK4-NEXT:    [[BLOCK_RESERVED:%.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, i32, i32 }>, ptr [[BLOCK]], i32 0, i32 2
815 // CHECK4-NEXT:    store i32 0, ptr [[BLOCK_RESERVED]], align 4
816 // CHECK4-NEXT:    [[BLOCK_INVOKE:%.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, i32, i32 }>, ptr [[BLOCK]], i32 0, i32 3
817 // CHECK4-NEXT:    store ptr @g_block_invoke, ptr [[BLOCK_INVOKE]], align 8
818 // CHECK4-NEXT:    [[BLOCK_DESCRIPTOR:%.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, i32, i32 }>, ptr [[BLOCK]], i32 0, i32 4
819 // CHECK4-NEXT:    store ptr @__block_descriptor_tmp, ptr [[BLOCK_DESCRIPTOR]], align 8
820 // CHECK4-NEXT:    [[BLOCK_CAPTURED:%.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, i32, i32 }>, ptr [[BLOCK]], i32 0, i32 5
821 // CHECK4-NEXT:    [[TMP10:%.*]] = load volatile i32, ptr [[G]], align 4
822 // CHECK4-NEXT:    store volatile i32 [[TMP10]], ptr [[BLOCK_CAPTURED]], align 8
823 // CHECK4-NEXT:    [[BLOCK_CAPTURED3:%.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, i32, i32 }>, ptr [[BLOCK]], i32 0, i32 6
824 // CHECK4-NEXT:    [[TMP11:%.*]] = load i32, ptr [[SIVAR1]], align 4
825 // CHECK4-NEXT:    store i32 [[TMP11]], ptr [[BLOCK_CAPTURED3]], align 4
826 // CHECK4-NEXT:    [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___BLOCK_LITERAL_GENERIC:%.*]], ptr [[BLOCK]], i32 0, i32 3
827 // CHECK4-NEXT:    [[TMP13:%.*]] = load ptr, ptr [[TMP12]], align 8
828 // CHECK4-NEXT:    call void [[TMP13]](ptr noundef [[BLOCK]])
829 // CHECK4-NEXT:    br label [[DOTOMP_SECTIONS_EXIT]]
830 // CHECK4:       .omp.sections.exit:
831 // CHECK4-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
832 // CHECK4:       omp.inner.for.inc:
833 // CHECK4-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
834 // CHECK4-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP14]], 1
835 // CHECK4-NEXT:    store i32 [[INC]], ptr [[DOTOMP_SECTIONS_IV_]], align 4
836 // CHECK4-NEXT:    br label [[OMP_INNER_FOR_COND]]
837 // CHECK4:       omp.inner.for.end:
838 // CHECK4-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP2]])
839 // CHECK4-NEXT:    [[TMP15:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IL_]], align 4
840 // CHECK4-NEXT:    [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0
841 // CHECK4-NEXT:    br i1 [[TMP16]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]]
842 // CHECK4:       .omp.lastprivate.then:
843 // CHECK4-NEXT:    [[TMP17:%.*]] = load i32, ptr [[G]], align 4
844 // CHECK4-NEXT:    store volatile i32 [[TMP17]], ptr @g, align 4
845 // CHECK4-NEXT:    [[TMP18:%.*]] = load i32, ptr [[SIVAR1]], align 4
846 // CHECK4-NEXT:    store i32 [[TMP18]], ptr [[TMP0]], align 4
847 // CHECK4-NEXT:    br label [[DOTOMP_LASTPRIVATE_DONE]]
848 // CHECK4:       .omp.lastprivate.done:
849 // CHECK4-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB2:[0-9]+]], i32 [[TMP2]])
850 // CHECK4-NEXT:    ret void
851 //
852 //
853 // CHECK4-LABEL: define {{[^@]+}}@g_block_invoke
854 // CHECK4-SAME: (ptr noundef [[DOTBLOCK_DESCRIPTOR:%.*]]) #[[ATTR1]] {
855 // CHECK4-NEXT:  entry:
856 // CHECK4-NEXT:    [[DOTBLOCK_DESCRIPTOR_ADDR:%.*]] = alloca ptr, align 8
857 // CHECK4-NEXT:    [[BLOCK_ADDR:%.*]] = alloca ptr, align 8
858 // CHECK4-NEXT:    store ptr [[DOTBLOCK_DESCRIPTOR]], ptr [[DOTBLOCK_DESCRIPTOR_ADDR]], align 8
859 // CHECK4-NEXT:    store ptr [[DOTBLOCK_DESCRIPTOR]], ptr [[BLOCK_ADDR]], align 8
860 // CHECK4-NEXT:    [[BLOCK_CAPTURE_ADDR:%.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, i32, i32 }>, ptr [[DOTBLOCK_DESCRIPTOR]], i32 0, i32 5
861 // CHECK4-NEXT:    store i32 2, ptr [[BLOCK_CAPTURE_ADDR]], align 8
862 // CHECK4-NEXT:    [[BLOCK_CAPTURE_ADDR1:%.*]] = getelementptr inbounds nuw <{ ptr, i32, i32, ptr, ptr, i32, i32 }>, ptr [[DOTBLOCK_DESCRIPTOR]], i32 0, i32 6
863 // CHECK4-NEXT:    store i32 29, ptr [[BLOCK_CAPTURE_ADDR1]], align 4
864 // CHECK4-NEXT:    ret void
865 //
866 //
867 // CHECK5-LABEL: define {{[^@]+}}@main
868 // CHECK5-SAME: () #[[ATTR0:[0-9]+]] {
869 // CHECK5-NEXT:  entry:
870 // CHECK5-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
871 // CHECK5-NEXT:    [[TEST:%.*]] = alloca [[STRUCT_S:%.*]], align 4
872 // CHECK5-NEXT:    [[T_VAR:%.*]] = alloca i32, align 4
873 // CHECK5-NEXT:    [[VEC:%.*]] = alloca [2 x i32], align 4
874 // CHECK5-NEXT:    [[S_ARR:%.*]] = alloca [2 x %struct.S], align 4
875 // CHECK5-NEXT:    [[VAR:%.*]] = alloca [[STRUCT_S]], align 4
876 // CHECK5-NEXT:    store i32 0, ptr [[RETVAL]], align 4
877 // CHECK5-NEXT:    call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]])
878 // CHECK5-NEXT:    store i32 0, ptr [[T_VAR]], align 4
879 // CHECK5-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const.main.vec, i64 8, i1 false)
880 // CHECK5-NEXT:    call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], float noundef 1.000000e+00)
881 // CHECK5-NEXT:    [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S_ARR]], i64 1
882 // CHECK5-NEXT:    call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00)
883 // CHECK5-NEXT:    call void @_ZN1SIfEC1Ef(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], float noundef 3.000000e+00)
884 // CHECK5-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3:[0-9]+]], i32 5, ptr @main.omp_outlined, ptr [[T_VAR]], ptr [[VEC]], ptr [[S_ARR]], ptr [[VAR]], ptr @_ZZ4mainE5sivar)
885 // CHECK5-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 0, ptr @main.omp_outlined.1)
886 // CHECK5-NEXT:    [[CALL:%.*]] = call noundef i32 @_Z5tmainIiET_v()
887 // CHECK5-NEXT:    store i32 [[CALL]], ptr [[RETVAL]], align 4
888 // CHECK5-NEXT:    call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR4:[0-9]+]]
889 // CHECK5-NEXT:    [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR]], i32 0, i32 0
890 // CHECK5-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN]], i64 2
891 // CHECK5-NEXT:    br label [[ARRAYDESTROY_BODY:%.*]]
892 // CHECK5:       arraydestroy.body:
893 // CHECK5-NEXT:    [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP0]], [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
894 // CHECK5-NEXT:    [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
895 // CHECK5-NEXT:    call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
896 // CHECK5-NEXT:    [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN]]
897 // CHECK5-NEXT:    br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]]
898 // CHECK5:       arraydestroy.done1:
899 // CHECK5-NEXT:    call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) #[[ATTR4]]
900 // CHECK5-NEXT:    [[TMP1:%.*]] = load i32, ptr [[RETVAL]], align 4
901 // CHECK5-NEXT:    ret i32 [[TMP1]]
902 //
903 //
904 // CHECK5-LABEL: define {{[^@]+}}@_ZN1SIfEC1Ev
905 // CHECK5-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] align 2 {
906 // CHECK5-NEXT:  entry:
907 // CHECK5-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
908 // CHECK5-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
909 // CHECK5-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
910 // CHECK5-NEXT:    call void @_ZN1SIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]])
911 // CHECK5-NEXT:    ret void
912 //
913 //
914 // CHECK5-LABEL: define {{[^@]+}}@_ZN1SIfEC1Ef
915 // CHECK5-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], float noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
916 // CHECK5-NEXT:  entry:
917 // CHECK5-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
918 // CHECK5-NEXT:    [[A_ADDR:%.*]] = alloca float, align 4
919 // CHECK5-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
920 // CHECK5-NEXT:    store float [[A]], ptr [[A_ADDR]], align 4
921 // CHECK5-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
922 // CHECK5-NEXT:    [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4
923 // CHECK5-NEXT:    call void @_ZN1SIfEC2Ef(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], float noundef [[TMP0]])
924 // CHECK5-NEXT:    ret void
925 //
926 //
927 // CHECK5-LABEL: define {{[^@]+}}@main.omp_outlined
928 // CHECK5-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[T_VAR:%.*]], ptr noundef nonnull align 4 dereferenceable(8) [[VEC:%.*]], ptr noundef nonnull align 4 dereferenceable(8) [[S_ARR:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[VAR:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[SIVAR:%.*]]) #[[ATTR3:[0-9]+]] {
929 // CHECK5-NEXT:  entry:
930 // CHECK5-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
931 // CHECK5-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
932 // CHECK5-NEXT:    [[T_VAR_ADDR:%.*]] = alloca ptr, align 8
933 // CHECK5-NEXT:    [[VEC_ADDR:%.*]] = alloca ptr, align 8
934 // CHECK5-NEXT:    [[S_ARR_ADDR:%.*]] = alloca ptr, align 8
935 // CHECK5-NEXT:    [[VAR_ADDR:%.*]] = alloca ptr, align 8
936 // CHECK5-NEXT:    [[SIVAR_ADDR:%.*]] = alloca ptr, align 8
937 // CHECK5-NEXT:    [[DOTOMP_SECTIONS_LB_:%.*]] = alloca i32, align 4
938 // CHECK5-NEXT:    [[DOTOMP_SECTIONS_UB_:%.*]] = alloca i32, align 4
939 // CHECK5-NEXT:    [[DOTOMP_SECTIONS_ST_:%.*]] = alloca i32, align 4
940 // CHECK5-NEXT:    [[DOTOMP_SECTIONS_IL_:%.*]] = alloca i32, align 4
941 // CHECK5-NEXT:    [[DOTOMP_SECTIONS_IV_:%.*]] = alloca i32, align 4
942 // CHECK5-NEXT:    [[T_VAR1:%.*]] = alloca i32, align 4
943 // CHECK5-NEXT:    [[VEC2:%.*]] = alloca [2 x i32], align 4
944 // CHECK5-NEXT:    [[S_ARR3:%.*]] = alloca [2 x %struct.S], align 4
945 // CHECK5-NEXT:    [[VAR4:%.*]] = alloca [[STRUCT_S:%.*]], align 4
946 // CHECK5-NEXT:    [[SIVAR5:%.*]] = alloca i32, align 4
947 // CHECK5-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
948 // CHECK5-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
949 // CHECK5-NEXT:    store ptr [[T_VAR]], ptr [[T_VAR_ADDR]], align 8
950 // CHECK5-NEXT:    store ptr [[VEC]], ptr [[VEC_ADDR]], align 8
951 // CHECK5-NEXT:    store ptr [[S_ARR]], ptr [[S_ARR_ADDR]], align 8
952 // CHECK5-NEXT:    store ptr [[VAR]], ptr [[VAR_ADDR]], align 8
953 // CHECK5-NEXT:    store ptr [[SIVAR]], ptr [[SIVAR_ADDR]], align 8
954 // CHECK5-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[T_VAR_ADDR]], align 8
955 // CHECK5-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[VEC_ADDR]], align 8
956 // CHECK5-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[S_ARR_ADDR]], align 8
957 // CHECK5-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[VAR_ADDR]], align 8
958 // CHECK5-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[SIVAR_ADDR]], align 8
959 // CHECK5-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_LB_]], align 4
960 // CHECK5-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_UB_]], align 4
961 // CHECK5-NEXT:    store i32 1, ptr [[DOTOMP_SECTIONS_ST_]], align 4
962 // CHECK5-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_IL_]], align 4
963 // CHECK5-NEXT:    [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR3]], i32 0, i32 0
964 // CHECK5-NEXT:    [[ARRAYCTOR_END:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN]], i64 2
965 // CHECK5-NEXT:    br label [[ARRAYCTOR_LOOP:%.*]]
966 // CHECK5:       arrayctor.loop:
967 // CHECK5-NEXT:    [[ARRAYCTOR_CUR:%.*]] = phi ptr [ [[ARRAY_BEGIN]], [[ENTRY:%.*]] ], [ [[ARRAYCTOR_NEXT:%.*]], [[ARRAYCTOR_LOOP]] ]
968 // CHECK5-NEXT:    call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYCTOR_CUR]])
969 // CHECK5-NEXT:    [[ARRAYCTOR_NEXT]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYCTOR_CUR]], i64 1
970 // CHECK5-NEXT:    [[ARRAYCTOR_DONE:%.*]] = icmp eq ptr [[ARRAYCTOR_NEXT]], [[ARRAYCTOR_END]]
971 // CHECK5-NEXT:    br i1 [[ARRAYCTOR_DONE]], label [[ARRAYCTOR_CONT:%.*]], label [[ARRAYCTOR_LOOP]]
972 // CHECK5:       arrayctor.cont:
973 // CHECK5-NEXT:    call void @_ZN1SIfEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]])
974 // CHECK5-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
975 // CHECK5-NEXT:    [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4
976 // CHECK5-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP6]], i32 34, ptr [[DOTOMP_SECTIONS_IL_]], ptr [[DOTOMP_SECTIONS_LB_]], ptr [[DOTOMP_SECTIONS_UB_]], ptr [[DOTOMP_SECTIONS_ST_]], i32 1, i32 1)
977 // CHECK5-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_UB_]], align 4
978 // CHECK5-NEXT:    [[TMP8:%.*]] = icmp slt i32 [[TMP7]], 0
979 // CHECK5-NEXT:    [[TMP9:%.*]] = select i1 [[TMP8]], i32 [[TMP7]], i32 0
980 // CHECK5-NEXT:    store i32 [[TMP9]], ptr [[DOTOMP_SECTIONS_UB_]], align 4
981 // CHECK5-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_LB_]], align 4
982 // CHECK5-NEXT:    store i32 [[TMP10]], ptr [[DOTOMP_SECTIONS_IV_]], align 4
983 // CHECK5-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
984 // CHECK5:       omp.inner.for.cond:
985 // CHECK5-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
986 // CHECK5-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_UB_]], align 4
987 // CHECK5-NEXT:    [[CMP:%.*]] = icmp sle i32 [[TMP11]], [[TMP12]]
988 // CHECK5-NEXT:    br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
989 // CHECK5:       omp.inner.for.body:
990 // CHECK5-NEXT:    [[TMP13:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
991 // CHECK5-NEXT:    switch i32 [[TMP13]], label [[DOTOMP_SECTIONS_EXIT:%.*]] [
992 // CHECK5-NEXT:      i32 0, label [[DOTOMP_SECTIONS_CASE:%.*]]
993 // CHECK5-NEXT:    ]
994 // CHECK5:       .omp.sections.case:
995 // CHECK5-NEXT:    [[TMP14:%.*]] = load i32, ptr [[T_VAR1]], align 4
996 // CHECK5-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i32], ptr [[VEC2]], i64 0, i64 0
997 // CHECK5-NEXT:    store i32 [[TMP14]], ptr [[ARRAYIDX]], align 4
998 // CHECK5-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR3]], i64 0, i64 0
999 // CHECK5-NEXT:    [[CALL:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN1SIfEaSERKS0_(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYIDX6]], ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]])
1000 // CHECK5-NEXT:    store i32 31, ptr [[SIVAR5]], align 4
1001 // CHECK5-NEXT:    br label [[DOTOMP_SECTIONS_EXIT]]
1002 // CHECK5:       .omp.sections.exit:
1003 // CHECK5-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
1004 // CHECK5:       omp.inner.for.inc:
1005 // CHECK5-NEXT:    [[TMP15:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
1006 // CHECK5-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP15]], 1
1007 // CHECK5-NEXT:    store i32 [[INC]], ptr [[DOTOMP_SECTIONS_IV_]], align 4
1008 // CHECK5-NEXT:    br label [[OMP_INNER_FOR_COND]]
1009 // CHECK5:       omp.inner.for.end:
1010 // CHECK5-NEXT:    [[TMP16:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1011 // CHECK5-NEXT:    [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4
1012 // CHECK5-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP17]])
1013 // CHECK5-NEXT:    [[TMP18:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IL_]], align 4
1014 // CHECK5-NEXT:    [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0
1015 // CHECK5-NEXT:    br i1 [[TMP19]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]]
1016 // CHECK5:       .omp.lastprivate.then:
1017 // CHECK5-NEXT:    [[TMP20:%.*]] = load i32, ptr [[T_VAR1]], align 4
1018 // CHECK5-NEXT:    store i32 [[TMP20]], ptr [[TMP0]], align 4
1019 // CHECK5-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[TMP1]], ptr align 4 [[VEC2]], i64 8, i1 false)
1020 // CHECK5-NEXT:    [[ARRAY_BEGIN7:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[TMP2]], i32 0, i32 0
1021 // CHECK5-NEXT:    [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN7]], i64 2
1022 // CHECK5-NEXT:    [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN7]], [[TMP21]]
1023 // CHECK5-NEXT:    br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE9:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
1024 // CHECK5:       omp.arraycpy.body:
1025 // CHECK5-NEXT:    [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi ptr [ [[S_ARR3]], [[DOTOMP_LASTPRIVATE_THEN]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
1026 // CHECK5-NEXT:    [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi ptr [ [[ARRAY_BEGIN7]], [[DOTOMP_LASTPRIVATE_THEN]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
1027 // CHECK5-NEXT:    [[CALL8:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN1SIfEaSERKS0_(ptr noundef nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr noundef nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]])
1028 // CHECK5-NEXT:    [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S]], ptr [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
1029 // CHECK5-NEXT:    [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[STRUCT_S]], ptr [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
1030 // CHECK5-NEXT:    [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq ptr [[OMP_ARRAYCPY_DEST_ELEMENT]], [[TMP21]]
1031 // CHECK5-NEXT:    br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYCPY_DONE9]], label [[OMP_ARRAYCPY_BODY]]
1032 // CHECK5:       omp.arraycpy.done9:
1033 // CHECK5-NEXT:    [[CALL10:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN1SIfEaSERKS0_(ptr noundef nonnull align 4 dereferenceable(4) [[TMP3]], ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]])
1034 // CHECK5-NEXT:    [[TMP22:%.*]] = load i32, ptr [[SIVAR5]], align 4
1035 // CHECK5-NEXT:    store i32 [[TMP22]], ptr [[TMP4]], align 4
1036 // CHECK5-NEXT:    br label [[DOTOMP_LASTPRIVATE_DONE]]
1037 // CHECK5:       .omp.lastprivate.done:
1038 // CHECK5-NEXT:    call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]]) #[[ATTR4]]
1039 // CHECK5-NEXT:    [[ARRAY_BEGIN11:%.*]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ARR3]], i32 0, i32 0
1040 // CHECK5-NEXT:    [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAY_BEGIN11]], i64 2
1041 // CHECK5-NEXT:    br label [[ARRAYDESTROY_BODY:%.*]]
1042 // CHECK5:       arraydestroy.body:
1043 // CHECK5-NEXT:    [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP23]], [[DOTOMP_LASTPRIVATE_DONE]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
1044 // CHECK5-NEXT:    [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
1045 // CHECK5-NEXT:    call void @_ZN1SIfED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
1046 // CHECK5-NEXT:    [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN11]]
1047 // CHECK5-NEXT:    br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE12:%.*]], label [[ARRAYDESTROY_BODY]]
1048 // CHECK5:       arraydestroy.done12:
1049 // CHECK5-NEXT:    [[TMP24:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1050 // CHECK5-NEXT:    [[TMP25:%.*]] = load i32, ptr [[TMP24]], align 4
1051 // CHECK5-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB2:[0-9]+]], i32 [[TMP25]])
1052 // CHECK5-NEXT:    ret void
1053 //
1054 //
1055 // CHECK5-LABEL: define {{[^@]+}}@_ZN1SIfED1Ev
1056 // CHECK5-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
1057 // CHECK5-NEXT:  entry:
1058 // CHECK5-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
1059 // CHECK5-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
1060 // CHECK5-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
1061 // CHECK5-NEXT:    call void @_ZN1SIfED2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR4]]
1062 // CHECK5-NEXT:    ret void
1063 //
1064 //
1065 // CHECK5-LABEL: define {{[^@]+}}@main.omp_outlined.1
1066 // CHECK5-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR3]] {
1067 // CHECK5-NEXT:  entry:
1068 // CHECK5-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
1069 // CHECK5-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
1070 // CHECK5-NEXT:    [[DOTOMP_SECTIONS_LB_:%.*]] = alloca i32, align 4
1071 // CHECK5-NEXT:    [[DOTOMP_SECTIONS_UB_:%.*]] = alloca i32, align 4
1072 // CHECK5-NEXT:    [[DOTOMP_SECTIONS_ST_:%.*]] = alloca i32, align 4
1073 // CHECK5-NEXT:    [[DOTOMP_SECTIONS_IL_:%.*]] = alloca i32, align 4
1074 // CHECK5-NEXT:    [[DOTOMP_SECTIONS_IV_:%.*]] = alloca i32, align 4
1075 // CHECK5-NEXT:    [[X:%.*]] = alloca [[STRUCT_LASPRIVATE_CONDITIONAL:%.*]], align 8
1076 // CHECK5-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
1077 // CHECK5-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
1078 // CHECK5-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_LB_]], align 4
1079 // CHECK5-NEXT:    store i32 1, ptr [[DOTOMP_SECTIONS_UB_]], align 4
1080 // CHECK5-NEXT:    store i32 1, ptr [[DOTOMP_SECTIONS_ST_]], align 4
1081 // CHECK5-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_IL_]], align 4
1082 // CHECK5-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw [[STRUCT_LASPRIVATE_CONDITIONAL]], ptr [[X]], i32 0, i32 1
1083 // CHECK5-NEXT:    store i8 0, ptr [[TMP0]], align 8
1084 // CHECK5-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_LASPRIVATE_CONDITIONAL]], ptr [[X]], i32 0, i32 0
1085 // CHECK5-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1086 // CHECK5-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4
1087 // CHECK5-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_SECTIONS_IL_]], ptr [[DOTOMP_SECTIONS_LB_]], ptr [[DOTOMP_SECTIONS_UB_]], ptr [[DOTOMP_SECTIONS_ST_]], i32 1, i32 1)
1088 // CHECK5-NEXT:    [[TMP4:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_UB_]], align 4
1089 // CHECK5-NEXT:    [[TMP5:%.*]] = icmp slt i32 [[TMP4]], 1
1090 // CHECK5-NEXT:    [[TMP6:%.*]] = select i1 [[TMP5]], i32 [[TMP4]], i32 1
1091 // CHECK5-NEXT:    store i32 [[TMP6]], ptr [[DOTOMP_SECTIONS_UB_]], align 4
1092 // CHECK5-NEXT:    [[TMP7:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_LB_]], align 4
1093 // CHECK5-NEXT:    store i32 [[TMP7]], ptr [[DOTOMP_SECTIONS_IV_]], align 4
1094 // CHECK5-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
1095 // CHECK5:       omp.inner.for.cond:
1096 // CHECK5-NEXT:    [[TMP8:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
1097 // CHECK5-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_UB_]], align 4
1098 // CHECK5-NEXT:    [[CMP:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]]
1099 // CHECK5-NEXT:    br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
1100 // CHECK5:       omp.inner.for.body:
1101 // CHECK5-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
1102 // CHECK5-NEXT:    switch i32 [[TMP10]], label [[DOTOMP_SECTIONS_EXIT:%.*]] [
1103 // CHECK5-NEXT:      i32 0, label [[DOTOMP_SECTIONS_CASE:%.*]]
1104 // CHECK5-NEXT:      i32 1, label [[DOTOMP_SECTIONS_CASE1:%.*]]
1105 // CHECK5-NEXT:    ]
1106 // CHECK5:       .omp.sections.case:
1107 // CHECK5-NEXT:    [[TMP11:%.*]] = load double, ptr [[TMP1]], align 8
1108 // CHECK5-NEXT:    [[INC:%.*]] = fadd double [[TMP11]], 1.000000e+00
1109 // CHECK5-NEXT:    store double [[INC]], ptr [[TMP1]], align 8
1110 // CHECK5-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
1111 // CHECK5-NEXT:    call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP3]], ptr @.gomp_critical_user_{{pl_cond[.].+[.|,]}}var)
1112 // CHECK5-NEXT:    [[TMP13:%.*]] = load i32, ptr @.{{pl_cond[.].+[.|,]}} align 4
1113 // CHECK5-NEXT:    [[TMP14:%.*]] = icmp sle i32 [[TMP13]], [[TMP12]]
1114 // CHECK5-NEXT:    br i1 [[TMP14]], label [[LP_COND_THEN:%.*]], label [[LP_COND_EXIT:%.*]]
1115 // CHECK5:       lp_cond_then:
1116 // CHECK5-NEXT:    store i32 [[TMP12]], ptr @.{{pl_cond[.].+[.|,]}} align 4
1117 // CHECK5-NEXT:    [[TMP15:%.*]] = load double, ptr [[TMP1]], align 8
1118 // CHECK5-NEXT:    store double [[TMP15]], ptr @{{pl_cond[.].+[.|,]}} align 8
1119 // CHECK5-NEXT:    br label [[LP_COND_EXIT]]
1120 // CHECK5:       lp_cond_exit:
1121 // CHECK5-NEXT:    call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP3]], ptr @.gomp_critical_user_{{pl_cond[.].+[.|,]}}var)
1122 // CHECK5-NEXT:    br label [[DOTOMP_SECTIONS_EXIT]]
1123 // CHECK5:       .omp.sections.case1:
1124 // CHECK5-NEXT:    br label [[DOTOMP_SECTIONS_EXIT]]
1125 // CHECK5:       .omp.sections.exit:
1126 // CHECK5-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
1127 // CHECK5:       omp.inner.for.inc:
1128 // CHECK5-NEXT:    [[TMP16:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
1129 // CHECK5-NEXT:    [[INC2:%.*]] = add nsw i32 [[TMP16]], 1
1130 // CHECK5-NEXT:    store i32 [[INC2]], ptr [[DOTOMP_SECTIONS_IV_]], align 4
1131 // CHECK5-NEXT:    br label [[OMP_INNER_FOR_COND]]
1132 // CHECK5:       omp.inner.for.end:
1133 // CHECK5-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP3]])
1134 // CHECK5-NEXT:    [[TMP17:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IL_]], align 4
1135 // CHECK5-NEXT:    [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0
1136 // CHECK5-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB4:[0-9]+]], i32 [[TMP3]])
1137 // CHECK5-NEXT:    br i1 [[TMP18]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]]
1138 // CHECK5:       .omp.lastprivate.then:
1139 // CHECK5-NEXT:    [[TMP19:%.*]] = load double, ptr @{{pl_cond[.].+[.|,]}} align 8
1140 // CHECK5-NEXT:    store double [[TMP19]], ptr [[TMP1]], align 8
1141 // CHECK5-NEXT:    [[TMP20:%.*]] = load double, ptr [[TMP1]], align 8
1142 // CHECK5-NEXT:    store double [[TMP20]], ptr @_ZN1A1xE, align 8
1143 // CHECK5-NEXT:    br label [[DOTOMP_LASTPRIVATE_DONE]]
1144 // CHECK5:       .omp.lastprivate.done:
1145 // CHECK5-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP3]])
1146 // CHECK5-NEXT:    ret void
1147 //
1148 //
1149 // CHECK5-LABEL: define {{[^@]+}}@_Z5tmainIiET_v
1150 // CHECK5-SAME: () #[[ATTR1]] {
1151 // CHECK5-NEXT:  entry:
1152 // CHECK5-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
1153 // CHECK5-NEXT:    [[TEST:%.*]] = alloca [[STRUCT_S_0:%.*]], align 4
1154 // CHECK5-NEXT:    [[T_VAR:%.*]] = alloca i32, align 4
1155 // CHECK5-NEXT:    [[VEC:%.*]] = alloca [2 x i32], align 4
1156 // CHECK5-NEXT:    [[S_ARR:%.*]] = alloca [2 x %struct.S.0], align 4
1157 // CHECK5-NEXT:    [[VAR:%.*]] = alloca [[STRUCT_S_0]], align 4
1158 // CHECK5-NEXT:    call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]])
1159 // CHECK5-NEXT:    store i32 0, ptr [[T_VAR]], align 4
1160 // CHECK5-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VEC]], ptr align 4 @__const._Z5tmainIiET_v.vec, i64 8, i1 false)
1161 // CHECK5-NEXT:    call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[S_ARR]], i32 noundef 1)
1162 // CHECK5-NEXT:    [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[S_ARR]], i64 1
1163 // CHECK5-NEXT:    call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2)
1164 // CHECK5-NEXT:    call void @_ZN1SIiEC1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]], i32 noundef 3)
1165 // CHECK5-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 4, ptr @_Z5tmainIiET_v.omp_outlined, ptr [[T_VAR]], ptr [[VEC]], ptr [[S_ARR]], ptr [[VAR]])
1166 // CHECK5-NEXT:    store i32 0, ptr [[RETVAL]], align 4
1167 // CHECK5-NEXT:    call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR]]) #[[ATTR4]]
1168 // CHECK5-NEXT:    [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR]], i32 0, i32 0
1169 // CHECK5-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN]], i64 2
1170 // CHECK5-NEXT:    br label [[ARRAYDESTROY_BODY:%.*]]
1171 // CHECK5:       arraydestroy.body:
1172 // CHECK5-NEXT:    [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP0]], [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
1173 // CHECK5-NEXT:    [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
1174 // CHECK5-NEXT:    call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
1175 // CHECK5-NEXT:    [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN]]
1176 // CHECK5-NEXT:    br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]]
1177 // CHECK5:       arraydestroy.done1:
1178 // CHECK5-NEXT:    call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TEST]]) #[[ATTR4]]
1179 // CHECK5-NEXT:    [[TMP1:%.*]] = load i32, ptr [[RETVAL]], align 4
1180 // CHECK5-NEXT:    ret i32 [[TMP1]]
1181 //
1182 //
1183 // CHECK5-LABEL: define {{[^@]+}}@_ZN1SIfEC2Ev
1184 // CHECK5-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
1185 // CHECK5-NEXT:  entry:
1186 // CHECK5-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
1187 // CHECK5-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
1188 // CHECK5-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
1189 // CHECK5-NEXT:    [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0
1190 // CHECK5-NEXT:    store float 0.000000e+00, ptr [[F]], align 4
1191 // CHECK5-NEXT:    ret void
1192 //
1193 //
1194 // CHECK5-LABEL: define {{[^@]+}}@_ZN1SIfEC2Ef
1195 // CHECK5-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], float noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
1196 // CHECK5-NEXT:  entry:
1197 // CHECK5-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
1198 // CHECK5-NEXT:    [[A_ADDR:%.*]] = alloca float, align 4
1199 // CHECK5-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
1200 // CHECK5-NEXT:    store float [[A]], ptr [[A_ADDR]], align 4
1201 // CHECK5-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
1202 // CHECK5-NEXT:    [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0
1203 // CHECK5-NEXT:    [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4
1204 // CHECK5-NEXT:    store float [[TMP0]], ptr [[F]], align 4
1205 // CHECK5-NEXT:    ret void
1206 //
1207 //
1208 // CHECK5-LABEL: define {{[^@]+}}@_ZN1SIfED2Ev
1209 // CHECK5-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
1210 // CHECK5-NEXT:  entry:
1211 // CHECK5-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
1212 // CHECK5-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
1213 // CHECK5-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
1214 // CHECK5-NEXT:    ret void
1215 //
1216 //
1217 // CHECK5-LABEL: define {{[^@]+}}@_ZN1SIiEC1Ev
1218 // CHECK5-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
1219 // CHECK5-NEXT:  entry:
1220 // CHECK5-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
1221 // CHECK5-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
1222 // CHECK5-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
1223 // CHECK5-NEXT:    call void @_ZN1SIiEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]])
1224 // CHECK5-NEXT:    ret void
1225 //
1226 //
1227 // CHECK5-LABEL: define {{[^@]+}}@_ZN1SIiEC1Ei
1228 // CHECK5-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
1229 // CHECK5-NEXT:  entry:
1230 // CHECK5-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
1231 // CHECK5-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
1232 // CHECK5-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
1233 // CHECK5-NEXT:    store i32 [[A]], ptr [[A_ADDR]], align 4
1234 // CHECK5-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
1235 // CHECK5-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
1236 // CHECK5-NEXT:    call void @_ZN1SIiEC2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]])
1237 // CHECK5-NEXT:    ret void
1238 //
1239 //
1240 // CHECK5-LABEL: define {{[^@]+}}@_Z5tmainIiET_v.omp_outlined
1241 // CHECK5-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[T_VAR:%.*]], ptr noundef nonnull align 4 dereferenceable(8) [[VEC:%.*]], ptr noundef nonnull align 4 dereferenceable(8) [[S_ARR:%.*]], ptr noundef nonnull align 4 dereferenceable(4) [[VAR:%.*]]) #[[ATTR3]] {
1242 // CHECK5-NEXT:  entry:
1243 // CHECK5-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
1244 // CHECK5-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
1245 // CHECK5-NEXT:    [[T_VAR_ADDR:%.*]] = alloca ptr, align 8
1246 // CHECK5-NEXT:    [[VEC_ADDR:%.*]] = alloca ptr, align 8
1247 // CHECK5-NEXT:    [[S_ARR_ADDR:%.*]] = alloca ptr, align 8
1248 // CHECK5-NEXT:    [[VAR_ADDR:%.*]] = alloca ptr, align 8
1249 // CHECK5-NEXT:    [[DOTOMP_SECTIONS_LB_:%.*]] = alloca i32, align 4
1250 // CHECK5-NEXT:    [[DOTOMP_SECTIONS_UB_:%.*]] = alloca i32, align 4
1251 // CHECK5-NEXT:    [[DOTOMP_SECTIONS_ST_:%.*]] = alloca i32, align 4
1252 // CHECK5-NEXT:    [[DOTOMP_SECTIONS_IL_:%.*]] = alloca i32, align 4
1253 // CHECK5-NEXT:    [[DOTOMP_SECTIONS_IV_:%.*]] = alloca i32, align 4
1254 // CHECK5-NEXT:    [[T_VAR1:%.*]] = alloca i32, align 4
1255 // CHECK5-NEXT:    [[VEC2:%.*]] = alloca [2 x i32], align 4
1256 // CHECK5-NEXT:    [[S_ARR3:%.*]] = alloca [2 x %struct.S.0], align 4
1257 // CHECK5-NEXT:    [[VAR4:%.*]] = alloca [[STRUCT_S_0:%.*]], align 4
1258 // CHECK5-NEXT:    store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
1259 // CHECK5-NEXT:    store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
1260 // CHECK5-NEXT:    store ptr [[T_VAR]], ptr [[T_VAR_ADDR]], align 8
1261 // CHECK5-NEXT:    store ptr [[VEC]], ptr [[VEC_ADDR]], align 8
1262 // CHECK5-NEXT:    store ptr [[S_ARR]], ptr [[S_ARR_ADDR]], align 8
1263 // CHECK5-NEXT:    store ptr [[VAR]], ptr [[VAR_ADDR]], align 8
1264 // CHECK5-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[T_VAR_ADDR]], align 8
1265 // CHECK5-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[VEC_ADDR]], align 8
1266 // CHECK5-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[S_ARR_ADDR]], align 8
1267 // CHECK5-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[VAR_ADDR]], align 8
1268 // CHECK5-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_LB_]], align 4
1269 // CHECK5-NEXT:    store i32 1, ptr [[DOTOMP_SECTIONS_UB_]], align 4
1270 // CHECK5-NEXT:    store i32 1, ptr [[DOTOMP_SECTIONS_ST_]], align 4
1271 // CHECK5-NEXT:    store i32 0, ptr [[DOTOMP_SECTIONS_IL_]], align 4
1272 // CHECK5-NEXT:    [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR3]], i32 0, i32 0
1273 // CHECK5-NEXT:    [[ARRAYCTOR_END:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN]], i64 2
1274 // CHECK5-NEXT:    br label [[ARRAYCTOR_LOOP:%.*]]
1275 // CHECK5:       arrayctor.loop:
1276 // CHECK5-NEXT:    [[ARRAYCTOR_CUR:%.*]] = phi ptr [ [[ARRAY_BEGIN]], [[ENTRY:%.*]] ], [ [[ARRAYCTOR_NEXT:%.*]], [[ARRAYCTOR_LOOP]] ]
1277 // CHECK5-NEXT:    call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYCTOR_CUR]])
1278 // CHECK5-NEXT:    [[ARRAYCTOR_NEXT]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYCTOR_CUR]], i64 1
1279 // CHECK5-NEXT:    [[ARRAYCTOR_DONE:%.*]] = icmp eq ptr [[ARRAYCTOR_NEXT]], [[ARRAYCTOR_END]]
1280 // CHECK5-NEXT:    br i1 [[ARRAYCTOR_DONE]], label [[ARRAYCTOR_CONT:%.*]], label [[ARRAYCTOR_LOOP]]
1281 // CHECK5:       arrayctor.cont:
1282 // CHECK5-NEXT:    call void @_ZN1SIiEC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]])
1283 // CHECK5-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1284 // CHECK5-NEXT:    [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4
1285 // CHECK5-NEXT:    call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP5]], i32 34, ptr [[DOTOMP_SECTIONS_IL_]], ptr [[DOTOMP_SECTIONS_LB_]], ptr [[DOTOMP_SECTIONS_UB_]], ptr [[DOTOMP_SECTIONS_ST_]], i32 1, i32 1)
1286 // CHECK5-NEXT:    [[TMP6:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_UB_]], align 4
1287 // CHECK5-NEXT:    [[TMP7:%.*]] = icmp slt i32 [[TMP6]], 1
1288 // CHECK5-NEXT:    [[TMP8:%.*]] = select i1 [[TMP7]], i32 [[TMP6]], i32 1
1289 // CHECK5-NEXT:    store i32 [[TMP8]], ptr [[DOTOMP_SECTIONS_UB_]], align 4
1290 // CHECK5-NEXT:    [[TMP9:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_LB_]], align 4
1291 // CHECK5-NEXT:    store i32 [[TMP9]], ptr [[DOTOMP_SECTIONS_IV_]], align 4
1292 // CHECK5-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
1293 // CHECK5:       omp.inner.for.cond:
1294 // CHECK5-NEXT:    [[TMP10:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
1295 // CHECK5-NEXT:    [[TMP11:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_UB_]], align 4
1296 // CHECK5-NEXT:    [[CMP:%.*]] = icmp sle i32 [[TMP10]], [[TMP11]]
1297 // CHECK5-NEXT:    br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
1298 // CHECK5:       omp.inner.for.body:
1299 // CHECK5-NEXT:    [[TMP12:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
1300 // CHECK5-NEXT:    switch i32 [[TMP12]], label [[DOTOMP_SECTIONS_EXIT:%.*]] [
1301 // CHECK5-NEXT:      i32 0, label [[DOTOMP_SECTIONS_CASE:%.*]]
1302 // CHECK5-NEXT:      i32 1, label [[DOTOMP_SECTIONS_CASE5:%.*]]
1303 // CHECK5-NEXT:    ]
1304 // CHECK5:       .omp.sections.case:
1305 // CHECK5-NEXT:    [[TMP13:%.*]] = load i32, ptr [[T_VAR1]], align 4
1306 // CHECK5-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i32], ptr [[VEC2]], i64 0, i64 0
1307 // CHECK5-NEXT:    store i32 [[TMP13]], ptr [[ARRAYIDX]], align 4
1308 // CHECK5-NEXT:    br label [[DOTOMP_SECTIONS_EXIT]]
1309 // CHECK5:       .omp.sections.case5:
1310 // CHECK5-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR3]], i64 0, i64 0
1311 // CHECK5-NEXT:    [[CALL:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN1SIiEaSERKS0_(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYIDX6]], ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]])
1312 // CHECK5-NEXT:    br label [[DOTOMP_SECTIONS_EXIT]]
1313 // CHECK5:       .omp.sections.exit:
1314 // CHECK5-NEXT:    br label [[OMP_INNER_FOR_INC:%.*]]
1315 // CHECK5:       omp.inner.for.inc:
1316 // CHECK5-NEXT:    [[TMP14:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IV_]], align 4
1317 // CHECK5-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP14]], 1
1318 // CHECK5-NEXT:    store i32 [[INC]], ptr [[DOTOMP_SECTIONS_IV_]], align 4
1319 // CHECK5-NEXT:    br label [[OMP_INNER_FOR_COND]]
1320 // CHECK5:       omp.inner.for.end:
1321 // CHECK5-NEXT:    [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1322 // CHECK5-NEXT:    [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4
1323 // CHECK5-NEXT:    call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP16]])
1324 // CHECK5-NEXT:    [[TMP17:%.*]] = load i32, ptr [[DOTOMP_SECTIONS_IL_]], align 4
1325 // CHECK5-NEXT:    [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0
1326 // CHECK5-NEXT:    br i1 [[TMP18]], label [[DOTOMP_LASTPRIVATE_THEN:%.*]], label [[DOTOMP_LASTPRIVATE_DONE:%.*]]
1327 // CHECK5:       .omp.lastprivate.then:
1328 // CHECK5-NEXT:    [[TMP19:%.*]] = load i32, ptr [[T_VAR1]], align 4
1329 // CHECK5-NEXT:    store i32 [[TMP19]], ptr [[TMP0]], align 4
1330 // CHECK5-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[TMP1]], ptr align 4 [[VEC2]], i64 8, i1 false)
1331 // CHECK5-NEXT:    [[ARRAY_BEGIN7:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[TMP2]], i32 0, i32 0
1332 // CHECK5-NEXT:    [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN7]], i64 2
1333 // CHECK5-NEXT:    [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq ptr [[ARRAY_BEGIN7]], [[TMP20]]
1334 // CHECK5-NEXT:    br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE9:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
1335 // CHECK5:       omp.arraycpy.body:
1336 // CHECK5-NEXT:    [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi ptr [ [[S_ARR3]], [[DOTOMP_LASTPRIVATE_THEN]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
1337 // CHECK5-NEXT:    [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi ptr [ [[ARRAY_BEGIN7]], [[DOTOMP_LASTPRIVATE_THEN]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
1338 // CHECK5-NEXT:    [[CALL8:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN1SIiEaSERKS0_(ptr noundef nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr noundef nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]])
1339 // CHECK5-NEXT:    [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S_0]], ptr [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
1340 // CHECK5-NEXT:    [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[STRUCT_S_0]], ptr [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
1341 // CHECK5-NEXT:    [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq ptr [[OMP_ARRAYCPY_DEST_ELEMENT]], [[TMP20]]
1342 // CHECK5-NEXT:    br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYCPY_DONE9]], label [[OMP_ARRAYCPY_BODY]]
1343 // CHECK5:       omp.arraycpy.done9:
1344 // CHECK5-NEXT:    [[CALL10:%.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @_ZN1SIiEaSERKS0_(ptr noundef nonnull align 4 dereferenceable(4) [[TMP3]], ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]])
1345 // CHECK5-NEXT:    br label [[DOTOMP_LASTPRIVATE_DONE]]
1346 // CHECK5:       .omp.lastprivate.done:
1347 // CHECK5-NEXT:    call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[VAR4]]) #[[ATTR4]]
1348 // CHECK5-NEXT:    [[ARRAY_BEGIN11:%.*]] = getelementptr inbounds [2 x %struct.S.0], ptr [[S_ARR3]], i32 0, i32 0
1349 // CHECK5-NEXT:    [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAY_BEGIN11]], i64 2
1350 // CHECK5-NEXT:    br label [[ARRAYDESTROY_BODY:%.*]]
1351 // CHECK5:       arraydestroy.body:
1352 // CHECK5-NEXT:    [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP21]], [[DOTOMP_LASTPRIVATE_DONE]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
1353 // CHECK5-NEXT:    [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S_0]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
1354 // CHECK5-NEXT:    call void @_ZN1SIiED1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
1355 // CHECK5-NEXT:    [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN11]]
1356 // CHECK5-NEXT:    br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE12:%.*]], label [[ARRAYDESTROY_BODY]]
1357 // CHECK5:       arraydestroy.done12:
1358 // CHECK5-NEXT:    [[TMP22:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1359 // CHECK5-NEXT:    [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4
1360 // CHECK5-NEXT:    call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[TMP23]])
1361 // CHECK5-NEXT:    ret void
1362 //
1363 //
1364 // CHECK5-LABEL: define {{[^@]+}}@_ZN1SIiED1Ev
1365 // CHECK5-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
1366 // CHECK5-NEXT:  entry:
1367 // CHECK5-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
1368 // CHECK5-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
1369 // CHECK5-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
1370 // CHECK5-NEXT:    call void @_ZN1SIiED2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR4]]
1371 // CHECK5-NEXT:    ret void
1372 //
1373 //
1374 // CHECK5-LABEL: define {{[^@]+}}@_ZN1SIiEC2Ev
1375 // CHECK5-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
1376 // CHECK5-NEXT:  entry:
1377 // CHECK5-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
1378 // CHECK5-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
1379 // CHECK5-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
1380 // CHECK5-NEXT:    [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S_0:%.*]], ptr [[THIS1]], i32 0, i32 0
1381 // CHECK5-NEXT:    store i32 0, ptr [[F]], align 4
1382 // CHECK5-NEXT:    ret void
1383 //
1384 //
1385 // CHECK5-LABEL: define {{[^@]+}}@_ZN1SIiEC2Ei
1386 // CHECK5-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
1387 // CHECK5-NEXT:  entry:
1388 // CHECK5-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
1389 // CHECK5-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
1390 // CHECK5-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
1391 // CHECK5-NEXT:    store i32 [[A]], ptr [[A_ADDR]], align 4
1392 // CHECK5-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
1393 // CHECK5-NEXT:    [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S_0:%.*]], ptr [[THIS1]], i32 0, i32 0
1394 // CHECK5-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
1395 // CHECK5-NEXT:    store i32 [[TMP0]], ptr [[F]], align 4
1396 // CHECK5-NEXT:    ret void
1397 //
1398 //
1399 // CHECK5-LABEL: define {{[^@]+}}@_ZN1SIiED2Ev
1400 // CHECK5-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
1401 // CHECK5-NEXT:  entry:
1402 // CHECK5-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
1403 // CHECK5-NEXT:    store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
1404 // CHECK5-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
1405 // CHECK5-NEXT:    ret void
1406 //
1407