Files
clang-p2996/clang/test/OpenMP/for_reduction_codegen_UDR.cpp
Johannes Doerfert b52d33e6de [OpenMP][NFC] Reuse check lines for Clang/OpenMP tests
I used a script to reuse existing check lines rather than creating new
ones. There are more opportunities to reduce the line count but the
"check generated functions" logic makes that somewhat tricky.

FWIW, we really should redo the update script with all these use cases
in mind...

Differential Revision: https://reviews.llvm.org/D128686
2022-07-01 21:34:11 -05:00

4106 lines
291 KiB
C++

// 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 _
// RUN: %clang_cc1 -no-opaque-pointers -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1
// RUN: %clang_cc1 -no-opaque-pointers -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
// RUN: %clang_cc1 -no-opaque-pointers -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK1
// RUN: %clang_cc1 -no-opaque-pointers -verify -fopenmp-simd -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK3
// RUN: %clang_cc1 -no-opaque-pointers -fopenmp-simd -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
// RUN: %clang_cc1 -no-opaque-pointers -fopenmp-simd -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK3
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
enum omp_allocator_handle_t {
omp_null_allocator = 0,
omp_default_mem_alloc = 1,
omp_large_cap_mem_alloc = 2,
omp_const_mem_alloc = 3,
omp_high_bw_mem_alloc = 4,
omp_low_lat_mem_alloc = 5,
omp_cgroup_mem_alloc = 6,
omp_pteam_mem_alloc = 7,
omp_thread_mem_alloc = 8,
KMP_ALLOCATOR_MAX_HANDLE = __UINTPTR_MAX__
};
volatile double g, g_orig;
volatile double &g1 = g_orig;
struct BaseS {
int x;
};
struct BaseS1 {
float y;
};
template <class T>
struct S : public BaseS, public BaseS1 {
T f;
S(T a) : f(a + g) {}
S() : f(g) {}
S& operator=(const S&);
~S() {}
};
void red(BaseS1&, const BaseS1&);
void red_plus(BaseS1&, const BaseS1&);
void init(BaseS1&, const BaseS1&);
void init1(BaseS1&, const BaseS1&);
void init2(BaseS1&, const BaseS1&);
void init_plus(BaseS1&, const BaseS1&);
#pragma omp declare reduction(operator& : BaseS1 : red(omp_out, omp_in)) initializer(init(omp_priv, omp_orig))
#pragma omp declare reduction(+ : BaseS1 : red_plus(omp_out, omp_in)) initializer(init_plus(omp_priv, omp_orig))
#pragma omp declare reduction(&& : S<float>, S<int> : omp_out.f *= omp_in.f) initializer(init1(omp_priv, omp_orig))
#pragma omp declare reduction(operator* : S<int> : omp_out.f = 17 * omp_in.f) initializer(omp_priv = S<int>())
void bazz() {
S<int> s;
#pragma omp parallel
#pragma omp simd reduction(*: s)
for (int I = 0; I < 10; ++I)
;
}
#pragma omp declare reduction(operator&& : int : omp_out = 111 & omp_in)
template <typename T, int length>
T tmain() {
T t;
S<T> test;
T t_var = T(), t_var1;
T vec[] = {1, 2};
S<T> s_arr[] = {1, 2};
S<T> &var = test;
S<T> var1;
S<T> arr[length];
#pragma omp declare reduction(operator& : T : omp_out = 15 + omp_in)
#pragma omp declare reduction(operator+ : T : omp_out = 1513 + omp_in) initializer(omp_priv = 321)
#pragma omp declare reduction(min : T : omp_out = 47 - omp_in) initializer(omp_priv = 432 / omp_orig)
#pragma omp declare reduction(operator&& : S<T> : omp_out.f = 17 * omp_in.f) initializer(init2(omp_priv, omp_orig))
#pragma omp declare reduction(operator&& : T : omp_out = 17 * omp_in)
#pragma omp parallel
#pragma omp for reduction(+ : t_var) reduction(& : var) reduction(&& : var1) reduction(min : t_var1) nowait
for (int i = 0; i < 2; ++i) {
vec[i] = t_var;
s_arr[i] = var;
}
#pragma omp parallel
#pragma omp for reduction(&& : t_var)
for (int i = 0; i < 2; ++i) {
vec[i] = t_var;
s_arr[i] = var;
}
#pragma omp parallel
#pragma omp for reduction(+ : arr[1:length-2])
for (int i = 0; i < 2; ++i) {
vec[i] = t_var;
s_arr[i] = var;
}
return T();
}
extern S<float> **foo();
#pragma omp declare reduction(operator- : float, double : omp_out = 333 + omp_in)
#pragma omp declare reduction(min : float, double : omp_out = 555 + omp_in)
int main() {
#pragma omp declare reduction(operator+ : float, double : omp_out = 222 - omp_in) initializer(omp_priv = -1)
S<float> test;
float t_var = 0, t_var1;
int vec[] = {1, 2};
S<float> s_arr[] = {1, 2, 3, 4};
S<float> &var = test;
S<float> var1, arrs[10][4];
S<float> **var2 = foo();
S<float> vvar2[5];
S<float>(&var3)[4] = s_arr;
#pragma omp declare reduction(operator+ : int : omp_out = 555 * omp_in) initializer(omp_priv = 888)
#pragma omp parallel
#pragma omp for reduction(+ : t_var) reduction(& : var) reduction(&& : var1) reduction(min : t_var1)
for (int i = 0; i < 2; ++i) {
vec[i] = t_var;
s_arr[i] = var;
}
int arr[10][vec[1]];
#pragma omp parallel for reduction(+ : arr[1][ : vec[1]]) reduction(& : arrs[1 : vec[1]][1 : 2])
for (int i = 0; i < 10; ++i)
++arr[1][i];
#pragma omp parallel
#pragma omp for reduction(+ : arr) reduction(& : arrs)
for (int i = 0; i < 10; ++i)
++arr[1][i];
#pragma omp parallel
#pragma omp for reduction(& : var2[0 : 5][1 : 6])
for (int i = 0; i < 10; ++i)
;
#pragma omp parallel
#pragma omp for reduction(& : vvar2[0 : 5])
for (int i = 0; i < 10; ++i)
;
#pragma omp parallel
#pragma omp for reduction(& : var3[1 : 2])
for (int i = 0; i < 10; ++i)
;
#pragma omp parallel
#pragma omp for reduction(& : var3) allocate(omp_cgroup_mem_alloc: var3)
for (int i = 0; i < 10; ++i)
;
return tmain<int, 42>();
}
// Reduction list for runtime.
// For + reduction operation initial value of private variable is -1.
// For & reduction operation initial value of private variable is defined by call of 'init()' function.
// For && reduction operation initial value of private variable is 1.0.
// For min reduction operation initial value of private variable is largest repesentable value.
// Skip checks for internal operations.
// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
// res = __kmpc_reduce(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>);
// switch(res)
// case 1:
// t_var += t_var_reduction;
// var = var.operator &(var_reduction);
// var1 = var1.operator &&(var1_reduction);
// t_var1 = min(t_var1, t_var1_reduction);
// __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
// break;
// case 2:
// t_var += t_var_reduction;
// var = var.operator &(var_reduction);
// var1 = var1.operator &&(var1_reduction);
// t_var1 = min(t_var1, t_var1_reduction);
// __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
// break;
// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
// ...
// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
// *(Type<n>-1*)rhs[<n>-1]);
// }
// t_var_lhs = (float*)lhs[0];
// t_var_rhs = (float*)rhs[0];
// var_lhs = (S<float>*)lhs[1];
// var_rhs = (S<float>*)rhs[1];
// var1_lhs = (S<float>*)lhs[2];
// var1_rhs = (S<float>*)rhs[2];
// t_var1_lhs = (float*)lhs[3];
// t_var1_rhs = (float*)rhs[3];
// t_var_lhs += t_var_rhs;
// var_lhs = var_lhs.operator &(var_rhs);
// var1_lhs = var1_lhs.operator &&(var1_rhs);
// t_var1_lhs = min(t_var1_lhs, t_var1_rhs);
// Reduction list for runtime.
// Check initialization of private copy.
// Check initialization of private copy.
// Skip checks for internal operations.
// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
// res = __kmpc_reduce(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>);
// switch(res)
// case 1:
// arr[:] += arr_reduction[:];
// arrs[:] = var.operator &(arrs_reduction[:]);
// __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
// break;
// case 2:
// arr[:] += arr_reduction[:];
// arrs[:] = var.operator &(arrs_reduction[:]);
// break;
// Check destruction of private copy.
// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
// ...
// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
// *(Type<n>-1*)rhs[<n>-1]);
// }
// arr_rhs = (int*)rhs[0];
// arr_lhs = (int*)lhs[0];
// arr_size = (size_t)lhs[1];
// arrs_rhs = (S<float>*)rhs[2];
// arrs_lhs = (S<float>*)lhs[2];
// arrs_size = (size_t)lhs[3];
// arr_lhs[:] += arr_rhs[:];
// arrs_lhs = arrs_lhs.operator &(arrs_rhs);
// Reduction list for runtime.
// Check initialization of private copy.
// Check initialization of private copy.
// Skip checks for internal operations.
// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
// res = __kmpc_reduce(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>);
// switch(res)
// case 1:
// arr[:] += arr_reduction[:];
// arrs[:] = var.operator &(arrs_reduction[:]);
// __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
// break;
// case 2:
// arr[:] += arr_reduction[:];
// arrs[:] = var.operator &(arrs_reduction[:]);
// break;
// Check destruction of private copy.
// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
// ...
// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
// *(Type<n>-1*)rhs[<n>-1]);
// }
// arr_rhs = (int*)rhs[0];
// arr_lhs = (int*)lhs[0];
// arr_size = (size_t)lhs[1];
// arrs_rhs = (S<float>*)rhs[2];
// arrs_lhs = (S<float>*)lhs[2];
// arr_lhs[:] += arr_rhs[:];
// arrs_lhs = arrs_lhs.operator &(arrs_rhs);
// Reduction list for runtime.
// Reduction list for runtime.
// Reduction list for runtime.
// Reduction list for runtime.
// Not interested in this one:
// Reduction list for runtime.
// For + reduction operation initial value of private variable is 0.
// For & reduction operation initial value of private variable is ones in all bits.
// For && reduction operation initial value of private variable is 1.0.
// For min reduction operation initial value of private variable is largest repesentable value.
// Skip checks for internal operations.
// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
// res = __kmpc_reduce_nowait(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>);
// switch(res)
// case 1:
// t_var += t_var_reduction;
// var = var.operator &(var_reduction);
// var1 = var1.operator &&(var1_reduction);
// t_var1 = min(t_var1, t_var1_reduction);
// __kmpc_end_reduce_nowait(<loc>, <gtid>, &<lock>);
// break;
// case 2:
// t_var += t_var_reduction;
// var = var.operator &(var_reduction);
// var1 = var1.operator &&(var1_reduction);
// t_var1 = min(t_var1, t_var1_reduction);
// break;
// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
// ...
// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
// *(Type<n>-1*)rhs[<n>-1]);
// }
// t_var_lhs = (i{{[0-9]+}}*)lhs[0];
// t_var_rhs = (i{{[0-9]+}}*)rhs[0];
// var_lhs = (S<i{{[0-9]+}}>*)lhs[1];
// var_rhs = (S<i{{[0-9]+}}>*)rhs[1];
// var1_lhs = (S<i{{[0-9]+}}>*)lhs[2];
// var1_rhs = (S<i{{[0-9]+}}>*)rhs[2];
// t_var1_lhs = (i{{[0-9]+}}*)lhs[3];
// t_var1_rhs = (i{{[0-9]+}}*)rhs[3];
// t_var_lhs += t_var_rhs;
// var_lhs = var_lhs.operator &(var_rhs);
// var1_lhs = var1_lhs.operator &&(var1_rhs);
// t_var1_lhs = min(t_var1_lhs, t_var1_rhs);
// Reduction list for runtime.
#endif
// CHECK1-LABEL: define {{[^@]+}}@_Z4bazzv
// CHECK1-SAME: () #[[ATTR0:[0-9]+]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 4
// CHECK1-NEXT: call void @_ZN1SIiEC1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[S]])
// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.S*)* @.omp_outlined. to void (i32*, i32*, ...)*), %struct.S* [[S]])
// CHECK1-NEXT: call void @_ZN1SIiED1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[S]]) #[[ATTR4:[0-9]+]]
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiEC1Ev
// CHECK1-SAME: (%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] align 2 {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
// CHECK1-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
// CHECK1-NEXT: call void @_ZN1SIiEC2Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS1]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.
// CHECK1-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], %struct.S* noundef nonnull align 4 dereferenceable(12) [[S:%.*]]) #[[ATTR2:[0-9]+]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[S_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[S1:%.*]] = alloca [[STRUCT_S:%.*]], align 4
// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store %struct.S* [[S]], %struct.S** [[S_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = load %struct.S*, %struct.S** [[S_ADDR]], align 8
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: call void @.omp_initializer.(%struct.S* noundef [[S1]], %struct.S* noundef [[TMP0]])
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
// CHECK1: omp.inner.for.cond:
// CHECK1-NEXT: [[TMP1:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !3
// CHECK1-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], 10
// CHECK1-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]]
// CHECK1: omp.inner.for.cond.cleanup:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
// CHECK1: omp.inner.for.body:
// CHECK1-NEXT: [[TMP2:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !3
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP2]], 1
// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4, !llvm.access.group !3
// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
// CHECK1: omp.body.continue:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
// CHECK1: omp.inner.for.inc:
// CHECK1-NEXT: [[TMP3:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !3
// CHECK1-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP3]], 1
// CHECK1-NEXT: store i32 [[ADD2]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !3
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
// CHECK1: omp.inner.for.end:
// CHECK1-NEXT: store i32 10, i32* [[I]], align 4
// CHECK1-NEXT: call void @.omp_combiner.(%struct.S* noundef [[TMP0]], %struct.S* noundef [[S1]])
// CHECK1-NEXT: call void @_ZN1SIiED1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[S1]]) #[[ATTR4]]
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_combiner.
// CHECK1-SAME: (%struct.S* noalias noundef [[TMP0:%.*]], %struct.S* noalias noundef [[TMP1:%.*]]) #[[ATTR3:[0-9]+]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: store %struct.S* [[TMP0]], %struct.S** [[DOTADDR]], align 8
// CHECK1-NEXT: store %struct.S* [[TMP1]], %struct.S** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load %struct.S*, %struct.S** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load %struct.S*, %struct.S** [[DOTADDR]], align 8
// CHECK1-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[TMP2]], i32 0, i32 2
// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[F]], align 4
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 17, [[TMP4]]
// CHECK1-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP3]], i32 0, i32 2
// CHECK1-NEXT: store i32 [[MUL]], i32* [[F2]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_initializer.
// CHECK1-SAME: (%struct.S* noalias noundef [[TMP0:%.*]], %struct.S* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: store %struct.S* [[TMP0]], %struct.S** [[DOTADDR]], align 8
// CHECK1-NEXT: store %struct.S* [[TMP1]], %struct.S** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load %struct.S*, %struct.S** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load %struct.S*, %struct.S** [[DOTADDR]], align 8
// CHECK1-NEXT: call void @_ZN1SIiEC1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[TMP3]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiED1Ev
// CHECK1-SAME: (%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
// CHECK1-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
// CHECK1-NEXT: call void @_ZN1SIiED2Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS1]]) #[[ATTR4]]
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiEC2Ev
// CHECK1-SAME: (%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
// CHECK1-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = bitcast %struct.S* [[THIS1]] to %struct.BaseS*
// CHECK1-NEXT: [[TMP1:%.*]] = bitcast %struct.S* [[THIS1]] to i8*
// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 4
// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to %struct.BaseS1*
// CHECK1-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[THIS1]], i32 0, i32 2
// CHECK1-NEXT: [[TMP4:%.*]] = load volatile double, double* @g, align 8
// CHECK1-NEXT: [[CONV:%.*]] = fptosi double [[TMP4]] to i32
// CHECK1-NEXT: store i32 [[CONV]], i32* [[F]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiED2Ev
// CHECK1-SAME: (%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
// CHECK1-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@main
// CHECK1-SAME: () #[[ATTR5:[0-9]+]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[TEST:%.*]] = alloca [[STRUCT_S_0:%.*]], align 4
// CHECK1-NEXT: [[T_VAR:%.*]] = alloca float, align 4
// CHECK1-NEXT: [[T_VAR1:%.*]] = alloca float, align 4
// CHECK1-NEXT: [[VEC:%.*]] = alloca [2 x i32], align 4
// CHECK1-NEXT: [[S_ARR:%.*]] = alloca [4 x %struct.S.0], align 16
// CHECK1-NEXT: [[VAR:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: [[VAR1:%.*]] = alloca [[STRUCT_S_0]], align 4
// CHECK1-NEXT: [[ARRS:%.*]] = alloca [10 x [4 x %struct.S.0]], align 16
// CHECK1-NEXT: [[VAR2:%.*]] = alloca %struct.S.0**, align 8
// CHECK1-NEXT: [[VVAR2:%.*]] = alloca [5 x %struct.S.0], align 16
// CHECK1-NEXT: [[VAR3:%.*]] = alloca [4 x %struct.S.0]*, align 8
// CHECK1-NEXT: [[SAVED_STACK:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: [[__VLA_EXPR0:%.*]] = alloca i64, align 8
// CHECK1-NEXT: store i32 0, i32* [[RETVAL]], align 4
// CHECK1-NEXT: call void @_ZN1SIfEC1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[TEST]])
// CHECK1-NEXT: store float 0.000000e+00, float* [[T_VAR]], align 4
// CHECK1-NEXT: [[TMP0:%.*]] = bitcast [2 x i32]* [[VEC]] to i8*
// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP0]], i8* align 4 bitcast ([2 x i32]* @__const.main.vec to i8*), i64 8, i1 false)
// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [4 x %struct.S.0], [4 x %struct.S.0]* [[S_ARR]], i64 0, i64 0
// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00)
// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYINIT_BEGIN]], i64 1
// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00)
// CHECK1-NEXT: [[ARRAYINIT_ELEMENT1:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYINIT_ELEMENT]], i64 1
// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT1]], float noundef 3.000000e+00)
// CHECK1-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYINIT_ELEMENT1]], i64 1
// CHECK1-NEXT: call void @_ZN1SIfEC1Ef(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT2]], float noundef 4.000000e+00)
// CHECK1-NEXT: store %struct.S.0* [[TEST]], %struct.S.0** [[VAR]], align 8
// CHECK1-NEXT: call void @_ZN1SIfEC1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[VAR1]])
// CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [10 x [4 x %struct.S.0]], [10 x [4 x %struct.S.0]]* [[ARRS]], i32 0, i32 0, i32 0
// CHECK1-NEXT: [[ARRAYCTOR_END:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAY_BEGIN]], i64 40
// CHECK1-NEXT: br label [[ARRAYCTOR_LOOP:%.*]]
// CHECK1: arrayctor.loop:
// CHECK1-NEXT: [[ARRAYCTOR_CUR:%.*]] = phi %struct.S.0* [ [[ARRAY_BEGIN]], [[ENTRY:%.*]] ], [ [[ARRAYCTOR_NEXT:%.*]], [[ARRAYCTOR_LOOP]] ]
// CHECK1-NEXT: call void @_ZN1SIfEC1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYCTOR_CUR]])
// CHECK1-NEXT: [[ARRAYCTOR_NEXT]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYCTOR_CUR]], i64 1
// CHECK1-NEXT: [[ARRAYCTOR_DONE:%.*]] = icmp eq %struct.S.0* [[ARRAYCTOR_NEXT]], [[ARRAYCTOR_END]]
// CHECK1-NEXT: br i1 [[ARRAYCTOR_DONE]], label [[ARRAYCTOR_CONT:%.*]], label [[ARRAYCTOR_LOOP]]
// CHECK1: arrayctor.cont:
// CHECK1-NEXT: [[CALL:%.*]] = call noundef %struct.S.0** @_Z3foov()
// CHECK1-NEXT: store %struct.S.0** [[CALL]], %struct.S.0*** [[VAR2]], align 8
// CHECK1-NEXT: [[ARRAY_BEGIN3:%.*]] = getelementptr inbounds [5 x %struct.S.0], [5 x %struct.S.0]* [[VVAR2]], i32 0, i32 0
// CHECK1-NEXT: [[ARRAYCTOR_END4:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAY_BEGIN3]], i64 5
// CHECK1-NEXT: br label [[ARRAYCTOR_LOOP5:%.*]]
// CHECK1: arrayctor.loop5:
// CHECK1-NEXT: [[ARRAYCTOR_CUR6:%.*]] = phi %struct.S.0* [ [[ARRAY_BEGIN3]], [[ARRAYCTOR_CONT]] ], [ [[ARRAYCTOR_NEXT7:%.*]], [[ARRAYCTOR_LOOP5]] ]
// CHECK1-NEXT: call void @_ZN1SIfEC1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYCTOR_CUR6]])
// CHECK1-NEXT: [[ARRAYCTOR_NEXT7]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYCTOR_CUR6]], i64 1
// CHECK1-NEXT: [[ARRAYCTOR_DONE8:%.*]] = icmp eq %struct.S.0* [[ARRAYCTOR_NEXT7]], [[ARRAYCTOR_END4]]
// CHECK1-NEXT: br i1 [[ARRAYCTOR_DONE8]], label [[ARRAYCTOR_CONT9:%.*]], label [[ARRAYCTOR_LOOP5]]
// CHECK1: arrayctor.cont9:
// CHECK1-NEXT: store [4 x %struct.S.0]* [[S_ARR]], [4 x %struct.S.0]** [[VAR3]], align 8
// CHECK1-NEXT: [[TMP1:%.*]] = load %struct.S.0*, %struct.S.0** [[VAR]], align 8
// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 6, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float*, %struct.S.0*, %struct.S.0*, float*, [2 x i32]*, [4 x %struct.S.0]*)* @.omp_outlined..1 to void (i32*, i32*, ...)*), float* [[T_VAR]], %struct.S.0* [[TMP1]], %struct.S.0* [[VAR1]], float* [[T_VAR1]], [2 x i32]* [[VEC]], [4 x %struct.S.0]* [[S_ARR]])
// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[VEC]], i64 0, i64 1
// CHECK1-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
// CHECK1-NEXT: [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
// CHECK1-NEXT: [[TMP4:%.*]] = call i8* @llvm.stacksave()
// CHECK1-NEXT: store i8* [[TMP4]], i8** [[SAVED_STACK]], align 8
// CHECK1-NEXT: [[TMP5:%.*]] = mul nuw i64 10, [[TMP3]]
// CHECK1-NEXT: [[VLA:%.*]] = alloca i32, i64 [[TMP5]], align 16
// CHECK1-NEXT: store i64 [[TMP3]], i64* [[__VLA_EXPR0]], align 8
// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64, i64, i32*, [2 x i32]*, [10 x [4 x %struct.S.0]]*)* @.omp_outlined..9 to void (i32*, i32*, ...)*), i64 10, i64 [[TMP3]], i32* [[VLA]], [2 x i32]* [[VEC]], [10 x [4 x %struct.S.0]]* [[ARRS]])
// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64, i64, i32*, [10 x [4 x %struct.S.0]]*)* @.omp_outlined..13 to void (i32*, i32*, ...)*), i64 10, i64 [[TMP3]], i32* [[VLA]], [10 x [4 x %struct.S.0]]* [[ARRS]])
// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.S.0***)* @.omp_outlined..15 to void (i32*, i32*, ...)*), %struct.S.0*** [[VAR2]])
// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [5 x %struct.S.0]*)* @.omp_outlined..17 to void (i32*, i32*, ...)*), [5 x %struct.S.0]* [[VVAR2]])
// CHECK1-NEXT: [[TMP6:%.*]] = load [4 x %struct.S.0]*, [4 x %struct.S.0]** [[VAR3]], align 8
// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [4 x %struct.S.0]*)* @.omp_outlined..19 to void (i32*, i32*, ...)*), [4 x %struct.S.0]* [[TMP6]])
// CHECK1-NEXT: [[TMP7:%.*]] = load [4 x %struct.S.0]*, [4 x %struct.S.0]** [[VAR3]], align 8
// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [4 x %struct.S.0]*)* @.omp_outlined..21 to void (i32*, i32*, ...)*), [4 x %struct.S.0]* [[TMP7]])
// CHECK1-NEXT: [[CALL10:%.*]] = call noundef i32 @_Z5tmainIiLi42EET_v()
// CHECK1-NEXT: store i32 [[CALL10]], i32* [[RETVAL]], align 4
// CHECK1-NEXT: [[TMP8:%.*]] = load i8*, i8** [[SAVED_STACK]], align 8
// CHECK1-NEXT: call void @llvm.stackrestore(i8* [[TMP8]])
// CHECK1-NEXT: [[ARRAY_BEGIN11:%.*]] = getelementptr inbounds [5 x %struct.S.0], [5 x %struct.S.0]* [[VVAR2]], i32 0, i32 0
// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAY_BEGIN11]], i64 5
// CHECK1-NEXT: br label [[ARRAYDESTROY_BODY:%.*]]
// CHECK1: arraydestroy.body:
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP9]], [[ARRAYCTOR_CONT9]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
// CHECK1-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
// CHECK1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq %struct.S.0* [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN11]]
// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE12:%.*]], label [[ARRAYDESTROY_BODY]]
// CHECK1: arraydestroy.done12:
// CHECK1-NEXT: [[ARRAY_BEGIN13:%.*]] = getelementptr inbounds [10 x [4 x %struct.S.0]], [10 x [4 x %struct.S.0]]* [[ARRS]], i32 0, i32 0, i32 0
// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAY_BEGIN13]], i64 40
// CHECK1-NEXT: br label [[ARRAYDESTROY_BODY14:%.*]]
// CHECK1: arraydestroy.body14:
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST15:%.*]] = phi %struct.S.0* [ [[TMP10]], [[ARRAYDESTROY_DONE12]] ], [ [[ARRAYDESTROY_ELEMENT16:%.*]], [[ARRAYDESTROY_BODY14]] ]
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT16]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYDESTROY_ELEMENTPAST15]], i64 -1
// CHECK1-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT16]]) #[[ATTR4]]
// CHECK1-NEXT: [[ARRAYDESTROY_DONE17:%.*]] = icmp eq %struct.S.0* [[ARRAYDESTROY_ELEMENT16]], [[ARRAY_BEGIN13]]
// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE17]], label [[ARRAYDESTROY_DONE18:%.*]], label [[ARRAYDESTROY_BODY14]]
// CHECK1: arraydestroy.done18:
// CHECK1-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[VAR1]]) #[[ATTR4]]
// CHECK1-NEXT: [[ARRAY_BEGIN19:%.*]] = getelementptr inbounds [4 x %struct.S.0], [4 x %struct.S.0]* [[S_ARR]], i32 0, i32 0
// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAY_BEGIN19]], i64 4
// CHECK1-NEXT: br label [[ARRAYDESTROY_BODY20:%.*]]
// CHECK1: arraydestroy.body20:
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST21:%.*]] = phi %struct.S.0* [ [[TMP11]], [[ARRAYDESTROY_DONE18]] ], [ [[ARRAYDESTROY_ELEMENT22:%.*]], [[ARRAYDESTROY_BODY20]] ]
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT22]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYDESTROY_ELEMENTPAST21]], i64 -1
// CHECK1-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT22]]) #[[ATTR4]]
// CHECK1-NEXT: [[ARRAYDESTROY_DONE23:%.*]] = icmp eq %struct.S.0* [[ARRAYDESTROY_ELEMENT22]], [[ARRAY_BEGIN19]]
// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE23]], label [[ARRAYDESTROY_DONE24:%.*]], label [[ARRAYDESTROY_BODY20]]
// CHECK1: arraydestroy.done24:
// CHECK1-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[TEST]]) #[[ATTR4]]
// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[RETVAL]], align 4
// CHECK1-NEXT: ret i32 [[TMP12]]
//
//
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIfEC1Ev
// CHECK1-SAME: (%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
// CHECK1-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
// CHECK1-NEXT: call void @_ZN1SIfEC2Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS1]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIfEC1Ef
// CHECK1-SAME: (%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]], float noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca float, align 4
// CHECK1-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
// CHECK1-NEXT: store float [[A]], float* [[A_ADDR]], align 4
// CHECK1-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = load float, float* [[A_ADDR]], align 4
// CHECK1-NEXT: call void @_ZN1SIfEC2Ef(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS1]], float noundef [[TMP0]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..1
// CHECK1-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], float* noundef nonnull align 4 dereferenceable(4) [[T_VAR:%.*]], %struct.S.0* noundef nonnull align 4 dereferenceable(12) [[VAR:%.*]], %struct.S.0* noundef nonnull align 4 dereferenceable(12) [[VAR1:%.*]], float* noundef nonnull align 4 dereferenceable(4) [[T_VAR1:%.*]], [2 x i32]* noundef nonnull align 4 dereferenceable(8) [[VEC:%.*]], [4 x %struct.S.0]* noundef nonnull align 4 dereferenceable(48) [[S_ARR:%.*]]) #[[ATTR2]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[T_VAR_ADDR:%.*]] = alloca float*, align 8
// CHECK1-NEXT: [[VAR_ADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: [[VAR1_ADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: [[T_VAR1_ADDR:%.*]] = alloca float*, align 8
// CHECK1-NEXT: [[VEC_ADDR:%.*]] = alloca [2 x i32]*, align 8
// CHECK1-NEXT: [[S_ARR_ADDR:%.*]] = alloca [4 x %struct.S.0]*, align 8
// CHECK1-NEXT: [[TMP:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: [[_TMP1:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[_TMP2:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[T_VAR3:%.*]] = alloca float, align 4
// CHECK1-NEXT: [[VAR4:%.*]] = alloca [[STRUCT_S_0:%.*]], align 4
// CHECK1-NEXT: [[_TMP6:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: [[VAR17:%.*]] = alloca [[STRUCT_S_0]], align 4
// CHECK1-NEXT: [[T_VAR18:%.*]] = alloca float, align 4
// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [4 x i8*], align 8
// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store float* [[T_VAR]], float** [[T_VAR_ADDR]], align 8
// CHECK1-NEXT: store %struct.S.0* [[VAR]], %struct.S.0** [[VAR_ADDR]], align 8
// CHECK1-NEXT: store %struct.S.0* [[VAR1]], %struct.S.0** [[VAR1_ADDR]], align 8
// CHECK1-NEXT: store float* [[T_VAR1]], float** [[T_VAR1_ADDR]], align 8
// CHECK1-NEXT: store [2 x i32]* [[VEC]], [2 x i32]** [[VEC_ADDR]], align 8
// CHECK1-NEXT: store [4 x %struct.S.0]* [[S_ARR]], [4 x %struct.S.0]** [[S_ARR_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = load float*, float** [[T_VAR_ADDR]], align 8
// CHECK1-NEXT: [[TMP1:%.*]] = load %struct.S.0*, %struct.S.0** [[VAR_ADDR]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load %struct.S.0*, %struct.S.0** [[VAR1_ADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load float*, float** [[T_VAR1_ADDR]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = load [2 x i32]*, [2 x i32]** [[VEC_ADDR]], align 8
// CHECK1-NEXT: [[TMP5:%.*]] = load [4 x %struct.S.0]*, [4 x %struct.S.0]** [[S_ARR_ADDR]], align 8
// CHECK1-NEXT: store %struct.S.0* [[TMP1]], %struct.S.0** [[TMP]], align 8
// CHECK1-NEXT: [[TMP6:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP]], align 8
// CHECK1-NEXT: store %struct.S.0* [[TMP6]], %struct.S.0** [[_TMP1]], align 8
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
// CHECK1-NEXT: call void @.omp_initializer..3(float* noundef [[T_VAR3]], float* noundef [[TMP0]])
// CHECK1-NEXT: [[TMP7:%.*]] = load %struct.S.0*, %struct.S.0** [[_TMP1]], align 8
// CHECK1-NEXT: [[TMP8:%.*]] = bitcast %struct.S.0* [[VAR4]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP8]], i64 4
// CHECK1-NEXT: [[TMP9:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct.S.0* [[TMP7]] to i8*
// CHECK1-NEXT: [[ADD_PTR5:%.*]] = getelementptr inbounds i8, i8* [[TMP10]], i64 4
// CHECK1-NEXT: [[TMP11:%.*]] = bitcast i8* [[ADD_PTR5]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_initializer..5(%struct.BaseS1* noundef [[TMP9]], %struct.BaseS1* noundef [[TMP11]])
// CHECK1-NEXT: store %struct.S.0* [[VAR4]], %struct.S.0** [[_TMP6]], align 8
// CHECK1-NEXT: call void @.omp_initializer..7(%struct.S.0* noundef [[VAR17]], %struct.S.0* noundef [[TMP2]])
// CHECK1-NEXT: [[TMP12:%.*]] = load float, float* @.init, align 4
// CHECK1-NEXT: store float [[TMP12]], float* [[T_VAR18]], align 4
// CHECK1-NEXT: [[TMP13:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[TMP13]], align 4
// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 [[TMP14]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP15]], 1
// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
// CHECK1: cond.true:
// CHECK1-NEXT: br label [[COND_END:%.*]]
// CHECK1: cond.false:
// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: br label [[COND_END]]
// CHECK1: cond.end:
// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 1, [[COND_TRUE]] ], [ [[TMP16]], [[COND_FALSE]] ]
// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
// CHECK1: omp.inner.for.cond:
// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP9:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]]
// CHECK1-NEXT: br i1 [[CMP9]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]]
// CHECK1: omp.inner.for.cond.cleanup:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
// CHECK1: omp.inner.for.body:
// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP20]], 1
// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4
// CHECK1-NEXT: [[TMP21:%.*]] = load float, float* [[T_VAR3]], align 4
// CHECK1-NEXT: [[CONV:%.*]] = fptosi float [[TMP21]] to i32
// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[I]], align 4
// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP22]] to i64
// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP4]], i64 0, i64 [[IDXPROM]]
// CHECK1-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
// CHECK1-NEXT: [[TMP23:%.*]] = load %struct.S.0*, %struct.S.0** [[_TMP6]], align 8
// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[I]], align 4
// CHECK1-NEXT: [[IDXPROM10:%.*]] = sext i32 [[TMP24]] to i64
// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [4 x %struct.S.0], [4 x %struct.S.0]* [[TMP5]], i64 0, i64 [[IDXPROM10]]
// CHECK1-NEXT: [[CALL:%.*]] = call noundef nonnull align 4 dereferenceable(12) %struct.S.0* @_ZN1SIfEaSERKS0_(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYIDX11]], %struct.S.0* noundef nonnull align 4 dereferenceable(12) [[TMP23]])
// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
// CHECK1: omp.body.continue:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
// CHECK1: omp.inner.for.inc:
// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[ADD12:%.*]] = add nsw i32 [[TMP25]], 1
// CHECK1-NEXT: store i32 [[ADD12]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]]
// CHECK1: omp.inner.for.end:
// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
// CHECK1: omp.loop.exit:
// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP14]])
// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// CHECK1-NEXT: [[TMP27:%.*]] = bitcast float* [[T_VAR3]] to i8*
// CHECK1-NEXT: store i8* [[TMP27]], i8** [[TMP26]], align 8
// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 1
// CHECK1-NEXT: [[TMP29:%.*]] = bitcast %struct.S.0* [[VAR4]] to i8*
// CHECK1-NEXT: store i8* [[TMP29]], i8** [[TMP28]], align 8
// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 2
// CHECK1-NEXT: [[TMP31:%.*]] = bitcast %struct.S.0* [[VAR17]] to i8*
// CHECK1-NEXT: store i8* [[TMP31]], i8** [[TMP30]], align 8
// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 3
// CHECK1-NEXT: [[TMP33:%.*]] = bitcast float* [[T_VAR18]] to i8*
// CHECK1-NEXT: store i8* [[TMP33]], i8** [[TMP32]], align 8
// CHECK1-NEXT: [[TMP34:%.*]] = bitcast [4 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
// CHECK1-NEXT: [[TMP35:%.*]] = call i32 @__kmpc_reduce(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 [[TMP14]], i32 4, i64 32, i8* [[TMP34]], void (i8*, i8*)* @.omp.reduction.reduction_func, [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: switch i32 [[TMP35]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
// CHECK1-NEXT: ]
// CHECK1: .omp.reduction.case1:
// CHECK1-NEXT: call void @.omp_combiner..2(float* noundef [[TMP0]], float* noundef [[T_VAR3]])
// CHECK1-NEXT: [[TMP36:%.*]] = bitcast %struct.S.0* [[TMP7]] to i8*
// CHECK1-NEXT: [[ADD_PTR13:%.*]] = getelementptr inbounds i8, i8* [[TMP36]], i64 4
// CHECK1-NEXT: [[TMP37:%.*]] = bitcast i8* [[ADD_PTR13]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP38:%.*]] = bitcast %struct.S.0* [[VAR4]] to i8*
// CHECK1-NEXT: [[ADD_PTR14:%.*]] = getelementptr inbounds i8, i8* [[TMP38]], i64 4
// CHECK1-NEXT: [[TMP39:%.*]] = bitcast i8* [[ADD_PTR14]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP37]], %struct.BaseS1* noundef [[TMP39]])
// CHECK1-NEXT: call void @.omp_combiner..6(%struct.S.0* noundef [[TMP2]], %struct.S.0* noundef [[VAR17]])
// CHECK1-NEXT: call void @.omp_combiner..8(float* noundef [[TMP3]], float* noundef [[T_VAR18]])
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP14]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.case2:
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP14]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @.omp_combiner..2(float* noundef [[TMP0]], float* noundef [[T_VAR3]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP14]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP14]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[TMP40:%.*]] = bitcast %struct.S.0* [[TMP7]] to i8*
// CHECK1-NEXT: [[ADD_PTR15:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 4
// CHECK1-NEXT: [[TMP41:%.*]] = bitcast i8* [[ADD_PTR15]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP42:%.*]] = bitcast %struct.S.0* [[VAR4]] to i8*
// CHECK1-NEXT: [[ADD_PTR16:%.*]] = getelementptr inbounds i8, i8* [[TMP42]], i64 4
// CHECK1-NEXT: [[TMP43:%.*]] = bitcast i8* [[ADD_PTR16]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP41]], %struct.BaseS1* noundef [[TMP43]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP14]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP14]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @.omp_combiner..6(%struct.S.0* noundef [[TMP2]], %struct.S.0* noundef [[VAR17]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP14]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP14]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @.omp_combiner..8(float* noundef [[TMP3]], float* noundef [[T_VAR18]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP14]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP14]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.default:
// CHECK1-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[VAR17]]) #[[ATTR4]]
// CHECK1-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[VAR4]]) #[[ATTR4]]
// CHECK1-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB4:[0-9]+]], i32 [[TMP14]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_combiner..2
// CHECK1-SAME: (float* noalias noundef [[TMP0:%.*]], float* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca float*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca float*, align 8
// CHECK1-NEXT: store float* [[TMP0]], float** [[DOTADDR]], align 8
// CHECK1-NEXT: store float* [[TMP1]], float** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load float*, float** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load float*, float** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = load float, float* [[TMP2]], align 4
// CHECK1-NEXT: [[SUB:%.*]] = fsub float 2.220000e+02, [[TMP4]]
// CHECK1-NEXT: store float [[SUB]], float* [[TMP3]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_initializer..3
// CHECK1-SAME: (float* noalias noundef [[TMP0:%.*]], float* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca float*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca float*, align 8
// CHECK1-NEXT: store float* [[TMP0]], float** [[DOTADDR]], align 8
// CHECK1-NEXT: store float* [[TMP1]], float** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load float*, float** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load float*, float** [[DOTADDR]], align 8
// CHECK1-NEXT: store float -1.000000e+00, float* [[TMP3]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_combiner..4
// CHECK1-SAME: (%struct.BaseS1* noalias noundef [[TMP0:%.*]], %struct.BaseS1* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca %struct.BaseS1*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca %struct.BaseS1*, align 8
// CHECK1-NEXT: store %struct.BaseS1* [[TMP0]], %struct.BaseS1** [[DOTADDR]], align 8
// CHECK1-NEXT: store %struct.BaseS1* [[TMP1]], %struct.BaseS1** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load %struct.BaseS1*, %struct.BaseS1** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load %struct.BaseS1*, %struct.BaseS1** [[DOTADDR]], align 8
// CHECK1-NEXT: call void @_Z3redR6BaseS1RKS_(%struct.BaseS1* noundef nonnull align 4 dereferenceable(4) [[TMP3]], %struct.BaseS1* noundef nonnull align 4 dereferenceable(4) [[TMP2]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_initializer..5
// CHECK1-SAME: (%struct.BaseS1* noalias noundef [[TMP0:%.*]], %struct.BaseS1* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca %struct.BaseS1*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca %struct.BaseS1*, align 8
// CHECK1-NEXT: store %struct.BaseS1* [[TMP0]], %struct.BaseS1** [[DOTADDR]], align 8
// CHECK1-NEXT: store %struct.BaseS1* [[TMP1]], %struct.BaseS1** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load %struct.BaseS1*, %struct.BaseS1** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load %struct.BaseS1*, %struct.BaseS1** [[DOTADDR]], align 8
// CHECK1-NEXT: call void @_Z4initR6BaseS1RKS_(%struct.BaseS1* noundef nonnull align 4 dereferenceable(4) [[TMP3]], %struct.BaseS1* noundef nonnull align 4 dereferenceable(4) [[TMP2]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_combiner..6
// CHECK1-SAME: (%struct.S.0* noalias noundef [[TMP0:%.*]], %struct.S.0* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: store %struct.S.0* [[TMP0]], %struct.S.0** [[DOTADDR]], align 8
// CHECK1-NEXT: store %struct.S.0* [[TMP1]], %struct.S.0** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load %struct.S.0*, %struct.S.0** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load %struct.S.0*, %struct.S.0** [[DOTADDR]], align 8
// CHECK1-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S_0:%.*]], %struct.S.0* [[TMP2]], i32 0, i32 2
// CHECK1-NEXT: [[TMP4:%.*]] = load float, float* [[F]], align 4
// CHECK1-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[TMP3]], i32 0, i32 2
// CHECK1-NEXT: [[TMP5:%.*]] = load float, float* [[F2]], align 4
// CHECK1-NEXT: [[MUL:%.*]] = fmul float [[TMP5]], [[TMP4]]
// CHECK1-NEXT: store float [[MUL]], float* [[F2]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_initializer..7
// CHECK1-SAME: (%struct.S.0* noalias noundef [[TMP0:%.*]], %struct.S.0* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: store %struct.S.0* [[TMP0]], %struct.S.0** [[DOTADDR]], align 8
// CHECK1-NEXT: store %struct.S.0* [[TMP1]], %struct.S.0** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load %struct.S.0*, %struct.S.0** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load %struct.S.0*, %struct.S.0** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = bitcast %struct.S.0* [[TMP3]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP4]], i64 4
// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP6:%.*]] = bitcast %struct.S.0* [[TMP2]] to i8*
// CHECK1-NEXT: [[ADD_PTR2:%.*]] = getelementptr inbounds i8, i8* [[TMP6]], i64 4
// CHECK1-NEXT: [[TMP7:%.*]] = bitcast i8* [[ADD_PTR2]] to %struct.BaseS1*
// CHECK1-NEXT: call void @_Z5init1R6BaseS1RKS_(%struct.BaseS1* noundef nonnull align 4 dereferenceable(4) [[TMP5]], %struct.BaseS1* noundef nonnull align 4 dereferenceable(4) [[TMP7]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func
// CHECK1-SAME: (i8* noundef [[TMP0:%.*]], i8* noundef [[TMP1:%.*]]) #[[ATTR8:[0-9]+]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8
// CHECK1-NEXT: store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [4 x i8*]*
// CHECK1-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [4 x i8*]*
// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP5]], i64 0, i64 0
// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to float*
// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP3]], i64 0, i64 0
// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
// CHECK1-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to float*
// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP5]], i64 0, i64 1
// CHECK1-NEXT: [[TMP13:%.*]] = load i8*, i8** [[TMP12]], align 8
// CHECK1-NEXT: [[TMP14:%.*]] = bitcast i8* [[TMP13]] to %struct.S.0*
// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP3]], i64 0, i64 1
// CHECK1-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8
// CHECK1-NEXT: [[TMP17:%.*]] = bitcast i8* [[TMP16]] to %struct.S.0*
// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP5]], i64 0, i64 2
// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8
// CHECK1-NEXT: [[TMP20:%.*]] = bitcast i8* [[TMP19]] to %struct.S.0*
// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP3]], i64 0, i64 2
// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[TMP21]], align 8
// CHECK1-NEXT: [[TMP23:%.*]] = bitcast i8* [[TMP22]] to %struct.S.0*
// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP5]], i64 0, i64 3
// CHECK1-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8
// CHECK1-NEXT: [[TMP26:%.*]] = bitcast i8* [[TMP25]] to float*
// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP3]], i64 0, i64 3
// CHECK1-NEXT: [[TMP28:%.*]] = load i8*, i8** [[TMP27]], align 8
// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i8* [[TMP28]] to float*
// CHECK1-NEXT: call void @.omp_combiner..2(float* noundef [[TMP11]], float* noundef [[TMP8]])
// CHECK1-NEXT: [[TMP30:%.*]] = bitcast %struct.S.0* [[TMP17]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP30]], i64 4
// CHECK1-NEXT: [[TMP31:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP32:%.*]] = bitcast %struct.S.0* [[TMP14]] to i8*
// CHECK1-NEXT: [[ADD_PTR2:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 4
// CHECK1-NEXT: [[TMP33:%.*]] = bitcast i8* [[ADD_PTR2]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP31]], %struct.BaseS1* noundef [[TMP33]])
// CHECK1-NEXT: call void @.omp_combiner..6(%struct.S.0* noundef [[TMP23]], %struct.S.0* noundef [[TMP20]])
// CHECK1-NEXT: call void @.omp_combiner..8(float* noundef [[TMP29]], float* noundef [[TMP26]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_combiner..8
// CHECK1-SAME: (float* noalias noundef [[TMP0:%.*]], float* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca float*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca float*, align 8
// CHECK1-NEXT: store float* [[TMP0]], float** [[DOTADDR]], align 8
// CHECK1-NEXT: store float* [[TMP1]], float** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load float*, float** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load float*, float** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = load float, float* [[TMP2]], align 4
// CHECK1-NEXT: [[ADD:%.*]] = fadd float 5.550000e+02, [[TMP4]]
// CHECK1-NEXT: store float [[ADD]], float* [[TMP3]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIfED1Ev
// CHECK1-SAME: (%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
// CHECK1-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
// CHECK1-NEXT: call void @_ZN1SIfED2Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS1]]) #[[ATTR4]]
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..9
// CHECK1-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]], i64 noundef [[VLA1:%.*]], i32* noundef nonnull align 4 dereferenceable(4) [[ARR:%.*]], [2 x i32]* noundef nonnull align 4 dereferenceable(8) [[VEC:%.*]], [10 x [4 x %struct.S.0]]* noundef nonnull align 4 dereferenceable(480) [[ARRS:%.*]]) #[[ATTR2]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8
// CHECK1-NEXT: [[VLA_ADDR2:%.*]] = alloca i64, align 8
// CHECK1-NEXT: [[ARR_ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[VEC_ADDR:%.*]] = alloca [2 x i32]*, align 8
// CHECK1-NEXT: [[ARRS_ADDR:%.*]] = alloca [10 x [4 x %struct.S.0]]*, align 8
// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[SAVED_STACK:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: [[__VLA_EXPR0:%.*]] = alloca i64, align 8
// CHECK1-NEXT: [[__VLA_EXPR1:%.*]] = alloca i64, align 8
// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [4 x i8*], align 8
// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8
// CHECK1-NEXT: store i64 [[VLA1]], i64* [[VLA_ADDR2]], align 8
// CHECK1-NEXT: store i32* [[ARR]], i32** [[ARR_ADDR]], align 8
// CHECK1-NEXT: store [2 x i32]* [[VEC]], [2 x i32]** [[VEC_ADDR]], align 8
// CHECK1-NEXT: store [10 x [4 x %struct.S.0]]* [[ARRS]], [10 x [4 x %struct.S.0]]** [[ARRS_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8
// CHECK1-NEXT: [[TMP1:%.*]] = load i64, i64* [[VLA_ADDR2]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[ARR_ADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load [2 x i32]*, [2 x i32]** [[VEC_ADDR]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [4 x %struct.S.0]]*, [10 x [4 x %struct.S.0]]** [[ARRS_ADDR]], align 8
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 9, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
// CHECK1-NEXT: [[TMP5:%.*]] = mul nsw i64 1, [[TMP1]]
// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[TMP5]]
// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, i32* [[ARRAYIDX]], i64 0
// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP3]], i64 0, i64 1
// CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[ARRAYIDX4]], align 4
// CHECK1-NEXT: [[TMP7:%.*]] = sext i32 [[TMP6]] to i64
// CHECK1-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP7]]
// CHECK1-NEXT: [[TMP8:%.*]] = mul nsw i64 1, [[TMP1]]
// CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[TMP8]]
// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, i32* [[ARRAYIDX5]], i64 [[LB_ADD_LEN]]
// CHECK1-NEXT: [[TMP9:%.*]] = ptrtoint i32* [[ARRAYIDX6]] to i64
// CHECK1-NEXT: [[TMP10:%.*]] = ptrtoint i32* [[ARRAYIDX3]] to i64
// CHECK1-NEXT: [[TMP11:%.*]] = sub i64 [[TMP9]], [[TMP10]]
// CHECK1-NEXT: [[TMP12:%.*]] = sdiv exact i64 [[TMP11]], ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64)
// CHECK1-NEXT: [[TMP13:%.*]] = add nuw i64 [[TMP12]], 1
// CHECK1-NEXT: [[TMP14:%.*]] = mul nuw i64 [[TMP13]], ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64)
// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.stacksave()
// CHECK1-NEXT: store i8* [[TMP15]], i8** [[SAVED_STACK]], align 8
// CHECK1-NEXT: [[VLA7:%.*]] = alloca i32, i64 [[TMP13]], align 16
// CHECK1-NEXT: store i64 [[TMP13]], i64* [[__VLA_EXPR0]], align 8
// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr i32, i32* [[VLA7]], i64 [[TMP13]]
// CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq i32* [[VLA7]], [[TMP16]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYINIT_ISEMPTY]], label [[OMP_ARRAYINIT_DONE:%.*]], label [[OMP_ARRAYINIT_BODY:%.*]]
// CHECK1: omp.arrayinit.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi i32* [ [[ARRAYIDX3]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYINIT_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi i32* [ [[VLA7]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT8:%.*]], [[OMP_ARRAYINIT_BODY]] ]
// CHECK1-NEXT: call void @.omp_initializer..11(i32* noundef [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32* noundef [[OMP_ARRAYCPY_SRCELEMENTPAST]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr i32, i32* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT8]] = getelementptr i32, i32* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq i32* [[OMP_ARRAYCPY_DEST_ELEMENT8]], [[TMP16]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYINIT_DONE]], label [[OMP_ARRAYINIT_BODY]]
// CHECK1: omp.arrayinit.done:
// CHECK1-NEXT: [[TMP17:%.*]] = ptrtoint i32* [[TMP2]] to i64
// CHECK1-NEXT: [[TMP18:%.*]] = ptrtoint i32* [[ARRAYIDX3]] to i64
// CHECK1-NEXT: [[TMP19:%.*]] = sub i64 [[TMP17]], [[TMP18]]
// CHECK1-NEXT: [[TMP20:%.*]] = sdiv exact i64 [[TMP19]], ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64)
// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr i32, i32* [[VLA7]], i64 [[TMP20]]
// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [4 x %struct.S.0]], [10 x [4 x %struct.S.0]]* [[TMP4]], i64 0, i64 1
// CHECK1-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [4 x %struct.S.0], [4 x %struct.S.0]* [[ARRAYIDX9]], i64 0, i64 0
// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [[STRUCT_S_0:%.*]], %struct.S.0* [[ARRAYDECAY]], i64 1
// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP3]], i64 0, i64 1
// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[ARRAYIDX11]], align 4
// CHECK1-NEXT: [[TMP23:%.*]] = sext i32 [[TMP22]] to i64
// CHECK1-NEXT: [[LB_ADD_LEN12:%.*]] = add nsw i64 0, [[TMP23]]
// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [4 x %struct.S.0]], [10 x [4 x %struct.S.0]]* [[TMP4]], i64 0, i64 [[LB_ADD_LEN12]]
// CHECK1-NEXT: [[ARRAYDECAY14:%.*]] = getelementptr inbounds [4 x %struct.S.0], [4 x %struct.S.0]* [[ARRAYIDX13]], i64 0, i64 0
// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYDECAY14]], i64 2
// CHECK1-NEXT: [[TMP24:%.*]] = ptrtoint %struct.S.0* [[ARRAYIDX15]] to i64
// CHECK1-NEXT: [[TMP25:%.*]] = ptrtoint %struct.S.0* [[ARRAYIDX10]] to i64
// CHECK1-NEXT: [[TMP26:%.*]] = sub i64 [[TMP24]], [[TMP25]]
// CHECK1-NEXT: [[TMP27:%.*]] = sdiv exact i64 [[TMP26]], ptrtoint (%struct.S.0* getelementptr ([[STRUCT_S_0]], %struct.S.0* null, i32 1) to i64)
// CHECK1-NEXT: [[TMP28:%.*]] = add nuw i64 [[TMP27]], 1
// CHECK1-NEXT: [[TMP29:%.*]] = mul nuw i64 [[TMP28]], ptrtoint (%struct.S.0* getelementptr ([[STRUCT_S_0]], %struct.S.0* null, i32 1) to i64)
// CHECK1-NEXT: [[VLA16:%.*]] = alloca [[STRUCT_S_0]], i64 [[TMP28]], align 16
// CHECK1-NEXT: store i64 [[TMP28]], i64* [[__VLA_EXPR1]], align 8
// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[VLA16]], i64 [[TMP28]]
// CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY17:%.*]] = icmp eq %struct.S.0* [[VLA16]], [[TMP30]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYINIT_ISEMPTY17]], label [[OMP_ARRAYINIT_DONE25:%.*]], label [[OMP_ARRAYINIT_BODY18:%.*]]
// CHECK1: omp.arrayinit.body18:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST19:%.*]] = phi %struct.S.0* [ [[ARRAYIDX10]], [[OMP_ARRAYINIT_DONE]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT22:%.*]], [[OMP_ARRAYINIT_BODY18]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST20:%.*]] = phi %struct.S.0* [ [[VLA16]], [[OMP_ARRAYINIT_DONE]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT23:%.*]], [[OMP_ARRAYINIT_BODY18]] ]
// CHECK1-NEXT: [[TMP31:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST20]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP31]], i64 4
// CHECK1-NEXT: [[TMP32:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP33:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST19]] to i8*
// CHECK1-NEXT: [[ADD_PTR21:%.*]] = getelementptr inbounds i8, i8* [[TMP33]], i64 4
// CHECK1-NEXT: [[TMP34:%.*]] = bitcast i8* [[ADD_PTR21]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_initializer..5(%struct.BaseS1* noundef [[TMP32]], %struct.BaseS1* noundef [[TMP34]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT22]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST19]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT23]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST20]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE24:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT23]], [[TMP30]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE24]], label [[OMP_ARRAYINIT_DONE25]], label [[OMP_ARRAYINIT_BODY18]]
// CHECK1: omp.arrayinit.done25:
// CHECK1-NEXT: [[TMP35:%.*]] = bitcast [10 x [4 x %struct.S.0]]* [[TMP4]] to %struct.S.0*
// CHECK1-NEXT: [[TMP36:%.*]] = ptrtoint %struct.S.0* [[TMP35]] to i64
// CHECK1-NEXT: [[TMP37:%.*]] = ptrtoint %struct.S.0* [[ARRAYIDX10]] to i64
// CHECK1-NEXT: [[TMP38:%.*]] = sub i64 [[TMP36]], [[TMP37]]
// CHECK1-NEXT: [[TMP39:%.*]] = sdiv exact i64 [[TMP38]], ptrtoint (%struct.S.0* getelementptr ([[STRUCT_S_0]], %struct.S.0* null, i32 1) to i64)
// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[VLA16]], i64 [[TMP39]]
// CHECK1-NEXT: [[TMP41:%.*]] = bitcast %struct.S.0* [[TMP40]] to [10 x [4 x %struct.S.0]]*
// CHECK1-NEXT: [[TMP42:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP43:%.*]] = load i32, i32* [[TMP42]], align 4
// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP43]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
// CHECK1-NEXT: [[TMP44:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP44]], 9
// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
// CHECK1: cond.true:
// CHECK1-NEXT: br label [[COND_END:%.*]]
// CHECK1: cond.false:
// CHECK1-NEXT: [[TMP45:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: br label [[COND_END]]
// CHECK1: cond.end:
// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP45]], [[COND_FALSE]] ]
// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 [[TMP46]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
// CHECK1: omp.inner.for.cond:
// CHECK1-NEXT: [[TMP47:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP26:%.*]] = icmp sle i32 [[TMP47]], [[TMP48]]
// CHECK1-NEXT: br i1 [[CMP26]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]]
// CHECK1: omp.inner.for.cond.cleanup:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
// CHECK1: omp.inner.for.body:
// CHECK1-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP49]], 1
// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4
// CHECK1-NEXT: [[TMP50:%.*]] = mul nsw i64 1, [[TMP1]]
// CHECK1-NEXT: [[ARRAYIDX27:%.*]] = getelementptr inbounds i32, i32* [[TMP21]], i64 [[TMP50]]
// CHECK1-NEXT: [[TMP51:%.*]] = load i32, i32* [[I]], align 4
// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP51]] to i64
// CHECK1-NEXT: [[ARRAYIDX28:%.*]] = getelementptr inbounds i32, i32* [[ARRAYIDX27]], i64 [[IDXPROM]]
// CHECK1-NEXT: [[TMP52:%.*]] = load i32, i32* [[ARRAYIDX28]], align 4
// CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP52]], 1
// CHECK1-NEXT: store i32 [[INC]], i32* [[ARRAYIDX28]], align 4
// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
// CHECK1: omp.body.continue:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
// CHECK1: omp.inner.for.inc:
// CHECK1-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP53]], 1
// CHECK1-NEXT: store i32 [[ADD29]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]]
// CHECK1: omp.inner.for.end:
// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
// CHECK1: omp.loop.exit:
// CHECK1-NEXT: [[TMP54:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP55:%.*]] = load i32, i32* [[TMP54]], align 4
// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP55]])
// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// CHECK1-NEXT: [[TMP57:%.*]] = bitcast i32* [[VLA7]] to i8*
// CHECK1-NEXT: store i8* [[TMP57]], i8** [[TMP56]], align 8
// CHECK1-NEXT: [[TMP58:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 1
// CHECK1-NEXT: [[TMP59:%.*]] = inttoptr i64 [[TMP13]] to i8*
// CHECK1-NEXT: store i8* [[TMP59]], i8** [[TMP58]], align 8
// CHECK1-NEXT: [[TMP60:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 2
// CHECK1-NEXT: [[TMP61:%.*]] = bitcast %struct.S.0* [[VLA16]] to i8*
// CHECK1-NEXT: store i8* [[TMP61]], i8** [[TMP60]], align 8
// CHECK1-NEXT: [[TMP62:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 3
// CHECK1-NEXT: [[TMP63:%.*]] = inttoptr i64 [[TMP28]] to i8*
// CHECK1-NEXT: store i8* [[TMP63]], i8** [[TMP62]], align 8
// CHECK1-NEXT: [[TMP64:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP65:%.*]] = load i32, i32* [[TMP64]], align 4
// CHECK1-NEXT: [[TMP66:%.*]] = bitcast [4 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
// CHECK1-NEXT: [[TMP67:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB3]], i32 [[TMP65]], i32 2, i64 32, i8* [[TMP66]], void (i8*, i8*)* @.omp.reduction.reduction_func.12, [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: switch i32 [[TMP67]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
// CHECK1-NEXT: ]
// CHECK1: .omp.reduction.case1:
// CHECK1-NEXT: [[TMP68:%.*]] = getelementptr i32, i32* [[ARRAYIDX3]], i64 [[TMP13]]
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq i32* [[ARRAYIDX3]], [[TMP68]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE34:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
// CHECK1: omp.arraycpy.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST30:%.*]] = phi i32* [ [[VLA7]], [[DOTOMP_REDUCTION_CASE1]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST31:%.*]] = phi i32* [ [[ARRAYIDX3]], [[DOTOMP_REDUCTION_CASE1]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT32:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: call void @.omp_combiner..10(i32* noundef [[OMP_ARRAYCPY_DESTELEMENTPAST31]], i32* noundef [[OMP_ARRAYCPY_SRCELEMENTPAST30]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT32]] = getelementptr i32, i32* [[OMP_ARRAYCPY_DESTELEMENTPAST31]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr i32, i32* [[OMP_ARRAYCPY_SRCELEMENTPAST30]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE33:%.*]] = icmp eq i32* [[OMP_ARRAYCPY_DEST_ELEMENT32]], [[TMP68]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE33]], label [[OMP_ARRAYCPY_DONE34]], label [[OMP_ARRAYCPY_BODY]]
// CHECK1: omp.arraycpy.done34:
// CHECK1-NEXT: [[TMP69:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[ARRAYIDX10]], i64 [[TMP28]]
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY35:%.*]] = icmp eq %struct.S.0* [[ARRAYIDX10]], [[TMP69]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY35]], label [[OMP_ARRAYCPY_DONE44:%.*]], label [[OMP_ARRAYCPY_BODY36:%.*]]
// CHECK1: omp.arraycpy.body36:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST37:%.*]] = phi %struct.S.0* [ [[VLA16]], [[OMP_ARRAYCPY_DONE34]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT42:%.*]], [[OMP_ARRAYCPY_BODY36]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST38:%.*]] = phi %struct.S.0* [ [[ARRAYIDX10]], [[OMP_ARRAYCPY_DONE34]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT41:%.*]], [[OMP_ARRAYCPY_BODY36]] ]
// CHECK1-NEXT: [[TMP70:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST38]] to i8*
// CHECK1-NEXT: [[ADD_PTR39:%.*]] = getelementptr inbounds i8, i8* [[TMP70]], i64 4
// CHECK1-NEXT: [[TMP71:%.*]] = bitcast i8* [[ADD_PTR39]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP72:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST37]] to i8*
// CHECK1-NEXT: [[ADD_PTR40:%.*]] = getelementptr inbounds i8, i8* [[TMP72]], i64 4
// CHECK1-NEXT: [[TMP73:%.*]] = bitcast i8* [[ADD_PTR40]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP71]], %struct.BaseS1* noundef [[TMP73]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT41]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST38]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT42]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST37]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE43:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT41]], [[TMP69]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE43]], label [[OMP_ARRAYCPY_DONE44]], label [[OMP_ARRAYCPY_BODY36]]
// CHECK1: omp.arraycpy.done44:
// CHECK1-NEXT: call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB3]], i32 [[TMP65]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.case2:
// CHECK1-NEXT: [[TMP74:%.*]] = getelementptr i32, i32* [[ARRAYIDX3]], i64 [[TMP13]]
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY45:%.*]] = icmp eq i32* [[ARRAYIDX3]], [[TMP74]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY45]], label [[OMP_ARRAYCPY_DONE52:%.*]], label [[OMP_ARRAYCPY_BODY46:%.*]]
// CHECK1: omp.arraycpy.body46:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST47:%.*]] = phi i32* [ [[VLA7]], [[DOTOMP_REDUCTION_CASE2]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT50:%.*]], [[OMP_ARRAYCPY_BODY46]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST48:%.*]] = phi i32* [ [[ARRAYIDX3]], [[DOTOMP_REDUCTION_CASE2]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT49:%.*]], [[OMP_ARRAYCPY_BODY46]] ]
// CHECK1-NEXT: [[TMP75:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP76:%.*]] = load i32, i32* [[TMP75]], align 4
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP76]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @.omp_combiner..10(i32* noundef [[OMP_ARRAYCPY_DESTELEMENTPAST48]], i32* noundef [[OMP_ARRAYCPY_SRCELEMENTPAST47]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP76]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT49]] = getelementptr i32, i32* [[OMP_ARRAYCPY_DESTELEMENTPAST48]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT50]] = getelementptr i32, i32* [[OMP_ARRAYCPY_SRCELEMENTPAST47]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE51:%.*]] = icmp eq i32* [[OMP_ARRAYCPY_DEST_ELEMENT49]], [[TMP74]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE51]], label [[OMP_ARRAYCPY_DONE52]], label [[OMP_ARRAYCPY_BODY46]]
// CHECK1: omp.arraycpy.done52:
// CHECK1-NEXT: [[TMP77:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[ARRAYIDX10]], i64 [[TMP28]]
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY53:%.*]] = icmp eq %struct.S.0* [[ARRAYIDX10]], [[TMP77]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY53]], label [[OMP_ARRAYCPY_DONE62:%.*]], label [[OMP_ARRAYCPY_BODY54:%.*]]
// CHECK1: omp.arraycpy.body54:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST55:%.*]] = phi %struct.S.0* [ [[VLA16]], [[OMP_ARRAYCPY_DONE52]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT60:%.*]], [[OMP_ARRAYCPY_BODY54]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST56:%.*]] = phi %struct.S.0* [ [[ARRAYIDX10]], [[OMP_ARRAYCPY_DONE52]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT59:%.*]], [[OMP_ARRAYCPY_BODY54]] ]
// CHECK1-NEXT: [[TMP78:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP79:%.*]] = load i32, i32* [[TMP78]], align 4
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP79]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[TMP80:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST56]] to i8*
// CHECK1-NEXT: [[ADD_PTR57:%.*]] = getelementptr inbounds i8, i8* [[TMP80]], i64 4
// CHECK1-NEXT: [[TMP81:%.*]] = bitcast i8* [[ADD_PTR57]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP82:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST55]] to i8*
// CHECK1-NEXT: [[ADD_PTR58:%.*]] = getelementptr inbounds i8, i8* [[TMP82]], i64 4
// CHECK1-NEXT: [[TMP83:%.*]] = bitcast i8* [[ADD_PTR58]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP81]], %struct.BaseS1* noundef [[TMP83]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP79]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT59]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST56]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT60]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST55]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE61:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT59]], [[TMP77]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE61]], label [[OMP_ARRAYCPY_DONE62]], label [[OMP_ARRAYCPY_BODY54]]
// CHECK1: omp.arraycpy.done62:
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.default:
// CHECK1-NEXT: [[TMP84:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[VLA16]], i64 [[TMP28]]
// CHECK1-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq %struct.S.0* [[VLA16]], [[TMP84]]
// CHECK1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE63:%.*]], label [[ARRAYDESTROY_BODY:%.*]]
// CHECK1: arraydestroy.body:
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP84]], [[DOTOMP_REDUCTION_DEFAULT]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
// CHECK1-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
// CHECK1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq %struct.S.0* [[ARRAYDESTROY_ELEMENT]], [[VLA16]]
// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE63]], label [[ARRAYDESTROY_BODY]]
// CHECK1: arraydestroy.done63:
// CHECK1-NEXT: [[TMP85:%.*]] = load i8*, i8** [[SAVED_STACK]], align 8
// CHECK1-NEXT: call void @llvm.stackrestore(i8* [[TMP85]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_combiner..10
// CHECK1-SAME: (i32* noalias noundef [[TMP0:%.*]], i32* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: store i32* [[TMP0]], i32** [[DOTADDR]], align 8
// CHECK1-NEXT: store i32* [[TMP1]], i32** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[TMP2]], align 4
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 555, [[TMP4]]
// CHECK1-NEXT: store i32 [[MUL]], i32* [[TMP3]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_initializer..11
// CHECK1-SAME: (i32* noalias noundef [[TMP0:%.*]], i32* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: store i32* [[TMP0]], i32** [[DOTADDR]], align 8
// CHECK1-NEXT: store i32* [[TMP1]], i32** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTADDR]], align 8
// CHECK1-NEXT: store i32 888, i32* [[TMP3]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.12
// CHECK1-SAME: (i8* noundef [[TMP0:%.*]], i8* noundef [[TMP1:%.*]]) #[[ATTR8]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8
// CHECK1-NEXT: store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [4 x i8*]*
// CHECK1-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [4 x i8*]*
// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP5]], i64 0, i64 0
// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to i32*
// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP3]], i64 0, i64 0
// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
// CHECK1-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to i32*
// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP3]], i64 0, i64 1
// CHECK1-NEXT: [[TMP13:%.*]] = load i8*, i8** [[TMP12]], align 8
// CHECK1-NEXT: [[TMP14:%.*]] = ptrtoint i8* [[TMP13]] to i64
// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP5]], i64 0, i64 2
// CHECK1-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8
// CHECK1-NEXT: [[TMP17:%.*]] = bitcast i8* [[TMP16]] to %struct.S.0*
// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP3]], i64 0, i64 2
// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8
// CHECK1-NEXT: [[TMP20:%.*]] = bitcast i8* [[TMP19]] to %struct.S.0*
// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP3]], i64 0, i64 3
// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[TMP21]], align 8
// CHECK1-NEXT: [[TMP23:%.*]] = ptrtoint i8* [[TMP22]] to i64
// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr i32, i32* [[TMP11]], i64 [[TMP14]]
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq i32* [[TMP11]], [[TMP24]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE2:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
// CHECK1: omp.arraycpy.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi i32* [ [[TMP8]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi i32* [ [[TMP11]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: call void @.omp_combiner..10(i32* noundef [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32* noundef [[OMP_ARRAYCPY_SRCELEMENTPAST]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr i32, i32* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr i32, i32* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq i32* [[OMP_ARRAYCPY_DEST_ELEMENT]], [[TMP24]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYCPY_DONE2]], label [[OMP_ARRAYCPY_BODY]]
// CHECK1: omp.arraycpy.done2:
// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[TMP20]], i64 [[TMP23]]
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY3:%.*]] = icmp eq %struct.S.0* [[TMP20]], [[TMP25]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY3]], label [[OMP_ARRAYCPY_DONE11:%.*]], label [[OMP_ARRAYCPY_BODY4:%.*]]
// CHECK1: omp.arraycpy.body4:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST5:%.*]] = phi %struct.S.0* [ [[TMP17]], [[OMP_ARRAYCPY_DONE2]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT9:%.*]], [[OMP_ARRAYCPY_BODY4]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST6:%.*]] = phi %struct.S.0* [ [[TMP20]], [[OMP_ARRAYCPY_DONE2]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT8:%.*]], [[OMP_ARRAYCPY_BODY4]] ]
// CHECK1-NEXT: [[TMP26:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST6]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP26]], i64 4
// CHECK1-NEXT: [[TMP27:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP28:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST5]] to i8*
// CHECK1-NEXT: [[ADD_PTR7:%.*]] = getelementptr inbounds i8, i8* [[TMP28]], i64 4
// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i8* [[ADD_PTR7]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP27]], %struct.BaseS1* noundef [[TMP29]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT8]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST6]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT9]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST5]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE10:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT8]], [[TMP25]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE10]], label [[OMP_ARRAYCPY_DONE11]], label [[OMP_ARRAYCPY_BODY4]]
// CHECK1: omp.arraycpy.done11:
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..13
// CHECK1-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[VLA:%.*]], i64 noundef [[VLA1:%.*]], i32* noundef nonnull align 4 dereferenceable(4) [[ARR:%.*]], [10 x [4 x %struct.S.0]]* noundef nonnull align 4 dereferenceable(480) [[ARRS:%.*]]) #[[ATTR2]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8
// CHECK1-NEXT: [[VLA_ADDR2:%.*]] = alloca i64, align 8
// CHECK1-NEXT: [[ARR_ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[ARRS_ADDR:%.*]] = alloca [10 x [4 x %struct.S.0]]*, align 8
// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[SAVED_STACK:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: [[__VLA_EXPR0:%.*]] = alloca i64, align 8
// CHECK1-NEXT: [[ARRS5:%.*]] = alloca [10 x [4 x %struct.S.0]], align 16
// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [3 x i8*], align 8
// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8
// CHECK1-NEXT: store i64 [[VLA1]], i64* [[VLA_ADDR2]], align 8
// CHECK1-NEXT: store i32* [[ARR]], i32** [[ARR_ADDR]], align 8
// CHECK1-NEXT: store [10 x [4 x %struct.S.0]]* [[ARRS]], [10 x [4 x %struct.S.0]]** [[ARRS_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8
// CHECK1-NEXT: [[TMP1:%.*]] = load i64, i64* [[VLA_ADDR2]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[ARR_ADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [4 x %struct.S.0]]*, [10 x [4 x %struct.S.0]]** [[ARRS_ADDR]], align 8
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 9, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
// CHECK1-NEXT: [[TMP4:%.*]] = mul nuw i64 [[TMP0]], [[TMP1]]
// CHECK1-NEXT: [[TMP5:%.*]] = mul nuw i64 [[TMP4]], 4
// CHECK1-NEXT: [[TMP6:%.*]] = udiv exact i64 [[TMP5]], ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64)
// CHECK1-NEXT: [[TMP7:%.*]] = call i8* @llvm.stacksave()
// CHECK1-NEXT: store i8* [[TMP7]], i8** [[SAVED_STACK]], align 8
// CHECK1-NEXT: [[VLA3:%.*]] = alloca i32, i64 [[TMP6]], align 16
// CHECK1-NEXT: store i64 [[TMP6]], i64* [[__VLA_EXPR0]], align 8
// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr i32, i32* [[VLA3]], i64 [[TMP6]]
// CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq i32* [[VLA3]], [[TMP8]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYINIT_ISEMPTY]], label [[OMP_ARRAYINIT_DONE:%.*]], label [[OMP_ARRAYINIT_BODY:%.*]]
// CHECK1: omp.arrayinit.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi i32* [ [[TMP2]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYINIT_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi i32* [ [[VLA3]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT4:%.*]], [[OMP_ARRAYINIT_BODY]] ]
// CHECK1-NEXT: call void @.omp_initializer..11(i32* noundef [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32* noundef [[OMP_ARRAYCPY_SRCELEMENTPAST]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr i32, i32* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT4]] = getelementptr i32, i32* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq i32* [[OMP_ARRAYCPY_DEST_ELEMENT4]], [[TMP8]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYINIT_DONE]], label [[OMP_ARRAYINIT_BODY]]
// CHECK1: omp.arrayinit.done:
// CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [10 x [4 x %struct.S.0]], [10 x [4 x %struct.S.0]]* [[ARRS5]], i32 0, i32 0, i32 0
// CHECK1-NEXT: [[TMP9:%.*]] = bitcast [10 x [4 x %struct.S.0]]* [[TMP3]] to %struct.S.0*
// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[ARRAY_BEGIN]], i64 40
// CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY6:%.*]] = icmp eq %struct.S.0* [[ARRAY_BEGIN]], [[TMP10]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYINIT_ISEMPTY6]], label [[OMP_ARRAYINIT_DONE14:%.*]], label [[OMP_ARRAYINIT_BODY7:%.*]]
// CHECK1: omp.arrayinit.body7:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST8:%.*]] = phi %struct.S.0* [ [[TMP9]], [[OMP_ARRAYINIT_DONE]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT11:%.*]], [[OMP_ARRAYINIT_BODY7]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST9:%.*]] = phi %struct.S.0* [ [[ARRAY_BEGIN]], [[OMP_ARRAYINIT_DONE]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT12:%.*]], [[OMP_ARRAYINIT_BODY7]] ]
// CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST9]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP11]], i64 4
// CHECK1-NEXT: [[TMP12:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP13:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST8]] to i8*
// CHECK1-NEXT: [[ADD_PTR10:%.*]] = getelementptr inbounds i8, i8* [[TMP13]], i64 4
// CHECK1-NEXT: [[TMP14:%.*]] = bitcast i8* [[ADD_PTR10]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_initializer..5(%struct.BaseS1* noundef [[TMP12]], %struct.BaseS1* noundef [[TMP14]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT11]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST8]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT12]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST9]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE13:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT12]], [[TMP10]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE13]], label [[OMP_ARRAYINIT_DONE14]], label [[OMP_ARRAYINIT_BODY7]]
// CHECK1: omp.arrayinit.done14:
// CHECK1-NEXT: [[LHS_BEGIN:%.*]] = bitcast [10 x [4 x %struct.S.0]]* [[TMP3]] to %struct.S.0*
// CHECK1-NEXT: [[RHS_BEGIN:%.*]] = bitcast [10 x [4 x %struct.S.0]]* [[ARRS5]] to %struct.S.0*
// CHECK1-NEXT: [[TMP15:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP15]], align 4
// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP16]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP17]], 9
// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
// CHECK1: cond.true:
// CHECK1-NEXT: br label [[COND_END:%.*]]
// CHECK1: cond.false:
// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: br label [[COND_END]]
// CHECK1: cond.end:
// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP18]], [[COND_FALSE]] ]
// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
// CHECK1: omp.inner.for.cond:
// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP15:%.*]] = icmp sle i32 [[TMP20]], [[TMP21]]
// CHECK1-NEXT: br i1 [[CMP15]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]]
// CHECK1: omp.inner.for.cond.cleanup:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
// CHECK1: omp.inner.for.body:
// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP22]], 1
// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4
// CHECK1-NEXT: [[TMP23:%.*]] = mul nsw i64 1, [[TMP1]]
// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[VLA3]], i64 [[TMP23]]
// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[I]], align 4
// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP24]] to i64
// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds i32, i32* [[ARRAYIDX]], i64 [[IDXPROM]]
// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[ARRAYIDX16]], align 4
// CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP25]], 1
// CHECK1-NEXT: store i32 [[INC]], i32* [[ARRAYIDX16]], align 4
// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
// CHECK1: omp.body.continue:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
// CHECK1: omp.inner.for.inc:
// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[ADD17:%.*]] = add nsw i32 [[TMP26]], 1
// CHECK1-NEXT: store i32 [[ADD17]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]]
// CHECK1: omp.inner.for.end:
// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
// CHECK1: omp.loop.exit:
// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4
// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP28]])
// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// CHECK1-NEXT: [[TMP30:%.*]] = bitcast i32* [[VLA3]] to i8*
// CHECK1-NEXT: store i8* [[TMP30]], i8** [[TMP29]], align 8
// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 1
// CHECK1-NEXT: [[TMP32:%.*]] = inttoptr i64 [[TMP6]] to i8*
// CHECK1-NEXT: store i8* [[TMP32]], i8** [[TMP31]], align 8
// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 2
// CHECK1-NEXT: [[TMP34:%.*]] = bitcast %struct.S.0* [[RHS_BEGIN]] to i8*
// CHECK1-NEXT: store i8* [[TMP34]], i8** [[TMP33]], align 8
// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4
// CHECK1-NEXT: [[TMP37:%.*]] = bitcast [3 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
// CHECK1-NEXT: [[TMP38:%.*]] = call i32 @__kmpc_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP36]], i32 2, i64 24, i8* [[TMP37]], void (i8*, i8*)* @.omp.reduction.reduction_func.14, [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: switch i32 [[TMP38]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
// CHECK1-NEXT: ]
// CHECK1: .omp.reduction.case1:
// CHECK1-NEXT: [[TMP39:%.*]] = getelementptr i32, i32* [[TMP2]], i64 [[TMP6]]
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq i32* [[TMP2]], [[TMP39]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE22:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
// CHECK1: omp.arraycpy.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST18:%.*]] = phi i32* [ [[VLA3]], [[DOTOMP_REDUCTION_CASE1]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST19:%.*]] = phi i32* [ [[TMP2]], [[DOTOMP_REDUCTION_CASE1]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT20:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: call void @.omp_combiner..10(i32* noundef [[OMP_ARRAYCPY_DESTELEMENTPAST19]], i32* noundef [[OMP_ARRAYCPY_SRCELEMENTPAST18]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT20]] = getelementptr i32, i32* [[OMP_ARRAYCPY_DESTELEMENTPAST19]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr i32, i32* [[OMP_ARRAYCPY_SRCELEMENTPAST18]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE21:%.*]] = icmp eq i32* [[OMP_ARRAYCPY_DEST_ELEMENT20]], [[TMP39]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE21]], label [[OMP_ARRAYCPY_DONE22]], label [[OMP_ARRAYCPY_BODY]]
// CHECK1: omp.arraycpy.done22:
// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[LHS_BEGIN]], i64 40
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY23:%.*]] = icmp eq %struct.S.0* [[LHS_BEGIN]], [[TMP40]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY23]], label [[OMP_ARRAYCPY_DONE32:%.*]], label [[OMP_ARRAYCPY_BODY24:%.*]]
// CHECK1: omp.arraycpy.body24:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST25:%.*]] = phi %struct.S.0* [ [[RHS_BEGIN]], [[OMP_ARRAYCPY_DONE22]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT30:%.*]], [[OMP_ARRAYCPY_BODY24]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST26:%.*]] = phi %struct.S.0* [ [[LHS_BEGIN]], [[OMP_ARRAYCPY_DONE22]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT29:%.*]], [[OMP_ARRAYCPY_BODY24]] ]
// CHECK1-NEXT: [[TMP41:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST26]] to i8*
// CHECK1-NEXT: [[ADD_PTR27:%.*]] = getelementptr inbounds i8, i8* [[TMP41]], i64 4
// CHECK1-NEXT: [[TMP42:%.*]] = bitcast i8* [[ADD_PTR27]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP43:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST25]] to i8*
// CHECK1-NEXT: [[ADD_PTR28:%.*]] = getelementptr inbounds i8, i8* [[TMP43]], i64 4
// CHECK1-NEXT: [[TMP44:%.*]] = bitcast i8* [[ADD_PTR28]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP42]], %struct.BaseS1* noundef [[TMP44]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT29]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST26]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT30]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST25]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE31:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT29]], [[TMP40]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE31]], label [[OMP_ARRAYCPY_DONE32]], label [[OMP_ARRAYCPY_BODY24]]
// CHECK1: omp.arraycpy.done32:
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP36]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.case2:
// CHECK1-NEXT: [[TMP45:%.*]] = getelementptr i32, i32* [[TMP2]], i64 [[TMP6]]
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY33:%.*]] = icmp eq i32* [[TMP2]], [[TMP45]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY33]], label [[OMP_ARRAYCPY_DONE40:%.*]], label [[OMP_ARRAYCPY_BODY34:%.*]]
// CHECK1: omp.arraycpy.body34:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST35:%.*]] = phi i32* [ [[VLA3]], [[DOTOMP_REDUCTION_CASE2]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT38:%.*]], [[OMP_ARRAYCPY_BODY34]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST36:%.*]] = phi i32* [ [[TMP2]], [[DOTOMP_REDUCTION_CASE2]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT37:%.*]], [[OMP_ARRAYCPY_BODY34]] ]
// CHECK1-NEXT: [[TMP46:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP47:%.*]] = load i32, i32* [[TMP46]], align 4
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP47]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @.omp_combiner..10(i32* noundef [[OMP_ARRAYCPY_DESTELEMENTPAST36]], i32* noundef [[OMP_ARRAYCPY_SRCELEMENTPAST35]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP47]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT37]] = getelementptr i32, i32* [[OMP_ARRAYCPY_DESTELEMENTPAST36]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT38]] = getelementptr i32, i32* [[OMP_ARRAYCPY_SRCELEMENTPAST35]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE39:%.*]] = icmp eq i32* [[OMP_ARRAYCPY_DEST_ELEMENT37]], [[TMP45]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE39]], label [[OMP_ARRAYCPY_DONE40]], label [[OMP_ARRAYCPY_BODY34]]
// CHECK1: omp.arraycpy.done40:
// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[LHS_BEGIN]], i64 40
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY41:%.*]] = icmp eq %struct.S.0* [[LHS_BEGIN]], [[TMP48]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY41]], label [[OMP_ARRAYCPY_DONE50:%.*]], label [[OMP_ARRAYCPY_BODY42:%.*]]
// CHECK1: omp.arraycpy.body42:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST43:%.*]] = phi %struct.S.0* [ [[RHS_BEGIN]], [[OMP_ARRAYCPY_DONE40]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT48:%.*]], [[OMP_ARRAYCPY_BODY42]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST44:%.*]] = phi %struct.S.0* [ [[LHS_BEGIN]], [[OMP_ARRAYCPY_DONE40]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT47:%.*]], [[OMP_ARRAYCPY_BODY42]] ]
// CHECK1-NEXT: [[TMP49:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP50:%.*]] = load i32, i32* [[TMP49]], align 4
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP50]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[TMP51:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST44]] to i8*
// CHECK1-NEXT: [[ADD_PTR45:%.*]] = getelementptr inbounds i8, i8* [[TMP51]], i64 4
// CHECK1-NEXT: [[TMP52:%.*]] = bitcast i8* [[ADD_PTR45]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP53:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST43]] to i8*
// CHECK1-NEXT: [[ADD_PTR46:%.*]] = getelementptr inbounds i8, i8* [[TMP53]], i64 4
// CHECK1-NEXT: [[TMP54:%.*]] = bitcast i8* [[ADD_PTR46]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP52]], %struct.BaseS1* noundef [[TMP54]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP50]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT47]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST44]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT48]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST43]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE49:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT47]], [[TMP48]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE49]], label [[OMP_ARRAYCPY_DONE50]], label [[OMP_ARRAYCPY_BODY42]]
// CHECK1: omp.arraycpy.done50:
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP36]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.default:
// CHECK1-NEXT: [[ARRAY_BEGIN51:%.*]] = getelementptr inbounds [10 x [4 x %struct.S.0]], [10 x [4 x %struct.S.0]]* [[ARRS5]], i32 0, i32 0, i32 0
// CHECK1-NEXT: [[TMP55:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAY_BEGIN51]], i64 40
// CHECK1-NEXT: br label [[ARRAYDESTROY_BODY:%.*]]
// CHECK1: arraydestroy.body:
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP55]], [[DOTOMP_REDUCTION_DEFAULT]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
// CHECK1-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
// CHECK1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq %struct.S.0* [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN51]]
// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE52:%.*]], label [[ARRAYDESTROY_BODY]]
// CHECK1: arraydestroy.done52:
// CHECK1-NEXT: [[TMP56:%.*]] = load i8*, i8** [[SAVED_STACK]], align 8
// CHECK1-NEXT: call void @llvm.stackrestore(i8* [[TMP56]])
// CHECK1-NEXT: [[TMP57:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP58:%.*]] = load i32, i32* [[TMP57]], align 4
// CHECK1-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB4]], i32 [[TMP58]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.14
// CHECK1-SAME: (i8* noundef [[TMP0:%.*]], i8* noundef [[TMP1:%.*]]) #[[ATTR8]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8
// CHECK1-NEXT: store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [3 x i8*]*
// CHECK1-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [3 x i8*]*
// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP5]], i64 0, i64 0
// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to i32*
// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP3]], i64 0, i64 0
// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
// CHECK1-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to i32*
// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP3]], i64 0, i64 1
// CHECK1-NEXT: [[TMP13:%.*]] = load i8*, i8** [[TMP12]], align 8
// CHECK1-NEXT: [[TMP14:%.*]] = ptrtoint i8* [[TMP13]] to i64
// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP5]], i64 0, i64 2
// CHECK1-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8
// CHECK1-NEXT: [[TMP17:%.*]] = bitcast i8* [[TMP16]] to %struct.S.0*
// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP3]], i64 0, i64 2
// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8
// CHECK1-NEXT: [[TMP20:%.*]] = bitcast i8* [[TMP19]] to %struct.S.0*
// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr i32, i32* [[TMP11]], i64 [[TMP14]]
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq i32* [[TMP11]], [[TMP21]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE2:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
// CHECK1: omp.arraycpy.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi i32* [ [[TMP8]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi i32* [ [[TMP11]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: call void @.omp_combiner..10(i32* noundef [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32* noundef [[OMP_ARRAYCPY_SRCELEMENTPAST]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr i32, i32* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr i32, i32* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq i32* [[OMP_ARRAYCPY_DEST_ELEMENT]], [[TMP21]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYCPY_DONE2]], label [[OMP_ARRAYCPY_BODY]]
// CHECK1: omp.arraycpy.done2:
// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[TMP20]], i64 40
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY3:%.*]] = icmp eq %struct.S.0* [[TMP20]], [[TMP22]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY3]], label [[OMP_ARRAYCPY_DONE11:%.*]], label [[OMP_ARRAYCPY_BODY4:%.*]]
// CHECK1: omp.arraycpy.body4:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST5:%.*]] = phi %struct.S.0* [ [[TMP17]], [[OMP_ARRAYCPY_DONE2]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT9:%.*]], [[OMP_ARRAYCPY_BODY4]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST6:%.*]] = phi %struct.S.0* [ [[TMP20]], [[OMP_ARRAYCPY_DONE2]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT8:%.*]], [[OMP_ARRAYCPY_BODY4]] ]
// CHECK1-NEXT: [[TMP23:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST6]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP23]], i64 4
// CHECK1-NEXT: [[TMP24:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP25:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST5]] to i8*
// CHECK1-NEXT: [[ADD_PTR7:%.*]] = getelementptr inbounds i8, i8* [[TMP25]], i64 4
// CHECK1-NEXT: [[TMP26:%.*]] = bitcast i8* [[ADD_PTR7]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP24]], %struct.BaseS1* noundef [[TMP26]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT8]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST6]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT9]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST5]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE10:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT8]], [[TMP22]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE10]], label [[OMP_ARRAYCPY_DONE11]], label [[OMP_ARRAYCPY_BODY4]]
// CHECK1: omp.arraycpy.done11:
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..15
// CHECK1-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], %struct.S.0*** noundef nonnull align 8 dereferenceable(8) [[VAR2:%.*]]) #[[ATTR2]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[VAR2_ADDR:%.*]] = alloca %struct.S.0***, align 8
// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[SAVED_STACK:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: [[__VLA_EXPR0:%.*]] = alloca i64, align 8
// CHECK1-NEXT: [[_TMP6:%.*]] = alloca %struct.S.0**, align 8
// CHECK1-NEXT: [[_TMP7:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [2 x i8*], align 8
// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store %struct.S.0*** [[VAR2]], %struct.S.0**** [[VAR2_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = load %struct.S.0***, %struct.S.0**** [[VAR2_ADDR]], align 8
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 9, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
// CHECK1-NEXT: [[TMP1:%.*]] = load %struct.S.0**, %struct.S.0*** [[TMP0]], align 8
// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds %struct.S.0*, %struct.S.0** [[TMP1]], i64 0
// CHECK1-NEXT: [[TMP2:%.*]] = load %struct.S.0*, %struct.S.0** [[ARRAYIDX]], align 8
// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [[STRUCT_S_0:%.*]], %struct.S.0* [[TMP2]], i64 1
// CHECK1-NEXT: [[TMP3:%.*]] = load %struct.S.0**, %struct.S.0*** [[TMP0]], align 8
// CHECK1-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds %struct.S.0*, %struct.S.0** [[TMP3]], i64 4
// CHECK1-NEXT: [[TMP4:%.*]] = load %struct.S.0*, %struct.S.0** [[ARRAYIDX2]], align 8
// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[TMP4]], i64 6
// CHECK1-NEXT: [[TMP5:%.*]] = ptrtoint %struct.S.0* [[ARRAYIDX3]] to i64
// CHECK1-NEXT: [[TMP6:%.*]] = ptrtoint %struct.S.0* [[ARRAYIDX1]] to i64
// CHECK1-NEXT: [[TMP7:%.*]] = sub i64 [[TMP5]], [[TMP6]]
// CHECK1-NEXT: [[TMP8:%.*]] = sdiv exact i64 [[TMP7]], ptrtoint (%struct.S.0* getelementptr ([[STRUCT_S_0]], %struct.S.0* null, i32 1) to i64)
// CHECK1-NEXT: [[TMP9:%.*]] = add nuw i64 [[TMP8]], 1
// CHECK1-NEXT: [[TMP10:%.*]] = mul nuw i64 [[TMP9]], ptrtoint (%struct.S.0* getelementptr ([[STRUCT_S_0]], %struct.S.0* null, i32 1) to i64)
// CHECK1-NEXT: [[TMP11:%.*]] = call i8* @llvm.stacksave()
// CHECK1-NEXT: store i8* [[TMP11]], i8** [[SAVED_STACK]], align 8
// CHECK1-NEXT: [[VLA:%.*]] = alloca [[STRUCT_S_0]], i64 [[TMP9]], align 16
// CHECK1-NEXT: store i64 [[TMP9]], i64* [[__VLA_EXPR0]], align 8
// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[VLA]], i64 [[TMP9]]
// CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq %struct.S.0* [[VLA]], [[TMP12]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYINIT_ISEMPTY]], label [[OMP_ARRAYINIT_DONE:%.*]], label [[OMP_ARRAYINIT_BODY:%.*]]
// CHECK1: omp.arrayinit.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi %struct.S.0* [ [[ARRAYIDX1]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYINIT_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi %struct.S.0* [ [[VLA]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT5:%.*]], [[OMP_ARRAYINIT_BODY]] ]
// CHECK1-NEXT: [[TMP13:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP13]], i64 4
// CHECK1-NEXT: [[TMP14:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP15:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR4:%.*]] = getelementptr inbounds i8, i8* [[TMP15]], i64 4
// CHECK1-NEXT: [[TMP16:%.*]] = bitcast i8* [[ADD_PTR4]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_initializer..5(%struct.BaseS1* noundef [[TMP14]], %struct.BaseS1* noundef [[TMP16]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT5]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT5]], [[TMP12]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYINIT_DONE]], label [[OMP_ARRAYINIT_BODY]]
// CHECK1: omp.arrayinit.done:
// CHECK1-NEXT: [[TMP17:%.*]] = load %struct.S.0**, %struct.S.0*** [[TMP0]], align 8
// CHECK1-NEXT: [[TMP18:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP17]], align 8
// CHECK1-NEXT: [[TMP19:%.*]] = ptrtoint %struct.S.0* [[TMP18]] to i64
// CHECK1-NEXT: [[TMP20:%.*]] = ptrtoint %struct.S.0* [[ARRAYIDX1]] to i64
// CHECK1-NEXT: [[TMP21:%.*]] = sub i64 [[TMP19]], [[TMP20]]
// CHECK1-NEXT: [[TMP22:%.*]] = sdiv exact i64 [[TMP21]], ptrtoint (%struct.S.0* getelementptr ([[STRUCT_S_0]], %struct.S.0* null, i32 1) to i64)
// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[VLA]], i64 [[TMP22]]
// CHECK1-NEXT: store %struct.S.0** [[_TMP7]], %struct.S.0*** [[_TMP6]], align 8
// CHECK1-NEXT: store %struct.S.0* [[TMP23]], %struct.S.0** [[_TMP7]], align 8
// CHECK1-NEXT: [[TMP24:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4
// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP25]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP26]], 9
// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
// CHECK1: cond.true:
// CHECK1-NEXT: br label [[COND_END:%.*]]
// CHECK1: cond.false:
// CHECK1-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: br label [[COND_END]]
// CHECK1: cond.end:
// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP27]], [[COND_FALSE]] ]
// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 [[TMP28]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
// CHECK1: omp.inner.for.cond:
// CHECK1-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP29]], [[TMP30]]
// CHECK1-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]]
// CHECK1: omp.inner.for.cond.cleanup:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
// CHECK1: omp.inner.for.body:
// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP31]], 1
// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4
// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
// CHECK1: omp.body.continue:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
// CHECK1: omp.inner.for.inc:
// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[ADD9:%.*]] = add nsw i32 [[TMP32]], 1
// CHECK1-NEXT: store i32 [[ADD9]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]]
// CHECK1: omp.inner.for.end:
// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
// CHECK1: omp.loop.exit:
// CHECK1-NEXT: [[TMP33:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP33]], align 4
// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP34]])
// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// CHECK1-NEXT: [[TMP36:%.*]] = bitcast %struct.S.0* [[VLA]] to i8*
// CHECK1-NEXT: store i8* [[TMP36]], i8** [[TMP35]], align 8
// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 1
// CHECK1-NEXT: [[TMP38:%.*]] = inttoptr i64 [[TMP9]] to i8*
// CHECK1-NEXT: store i8* [[TMP38]], i8** [[TMP37]], align 8
// CHECK1-NEXT: [[TMP39:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP40:%.*]] = load i32, i32* [[TMP39]], align 4
// CHECK1-NEXT: [[TMP41:%.*]] = bitcast [2 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
// CHECK1-NEXT: [[TMP42:%.*]] = call i32 @__kmpc_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP40]], i32 1, i64 16, i8* [[TMP41]], void (i8*, i8*)* @.omp.reduction.reduction_func.16, [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: switch i32 [[TMP42]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
// CHECK1-NEXT: ]
// CHECK1: .omp.reduction.case1:
// CHECK1-NEXT: [[TMP43:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[ARRAYIDX1]], i64 [[TMP9]]
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq %struct.S.0* [[ARRAYIDX1]], [[TMP43]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE16:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
// CHECK1: omp.arraycpy.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST10:%.*]] = phi %struct.S.0* [ [[VLA]], [[DOTOMP_REDUCTION_CASE1]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST11:%.*]] = phi %struct.S.0* [ [[ARRAYIDX1]], [[DOTOMP_REDUCTION_CASE1]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT14:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[TMP44:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST11]] to i8*
// CHECK1-NEXT: [[ADD_PTR12:%.*]] = getelementptr inbounds i8, i8* [[TMP44]], i64 4
// CHECK1-NEXT: [[TMP45:%.*]] = bitcast i8* [[ADD_PTR12]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP46:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST10]] to i8*
// CHECK1-NEXT: [[ADD_PTR13:%.*]] = getelementptr inbounds i8, i8* [[TMP46]], i64 4
// CHECK1-NEXT: [[TMP47:%.*]] = bitcast i8* [[ADD_PTR13]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP45]], %struct.BaseS1* noundef [[TMP47]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT14]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST11]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST10]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE15:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT14]], [[TMP43]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE15]], label [[OMP_ARRAYCPY_DONE16]], label [[OMP_ARRAYCPY_BODY]]
// CHECK1: omp.arraycpy.done16:
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP40]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.case2:
// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[ARRAYIDX1]], i64 [[TMP9]]
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY17:%.*]] = icmp eq %struct.S.0* [[ARRAYIDX1]], [[TMP48]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY17]], label [[OMP_ARRAYCPY_DONE26:%.*]], label [[OMP_ARRAYCPY_BODY18:%.*]]
// CHECK1: omp.arraycpy.body18:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST19:%.*]] = phi %struct.S.0* [ [[VLA]], [[DOTOMP_REDUCTION_CASE2]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT24:%.*]], [[OMP_ARRAYCPY_BODY18]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST20:%.*]] = phi %struct.S.0* [ [[ARRAYIDX1]], [[DOTOMP_REDUCTION_CASE2]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT23:%.*]], [[OMP_ARRAYCPY_BODY18]] ]
// CHECK1-NEXT: [[TMP49:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP50:%.*]] = load i32, i32* [[TMP49]], align 4
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP50]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[TMP51:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST20]] to i8*
// CHECK1-NEXT: [[ADD_PTR21:%.*]] = getelementptr inbounds i8, i8* [[TMP51]], i64 4
// CHECK1-NEXT: [[TMP52:%.*]] = bitcast i8* [[ADD_PTR21]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP53:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST19]] to i8*
// CHECK1-NEXT: [[ADD_PTR22:%.*]] = getelementptr inbounds i8, i8* [[TMP53]], i64 4
// CHECK1-NEXT: [[TMP54:%.*]] = bitcast i8* [[ADD_PTR22]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP52]], %struct.BaseS1* noundef [[TMP54]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP50]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT23]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST20]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT24]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST19]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE25:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT23]], [[TMP48]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE25]], label [[OMP_ARRAYCPY_DONE26]], label [[OMP_ARRAYCPY_BODY18]]
// CHECK1: omp.arraycpy.done26:
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP40]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.default:
// CHECK1-NEXT: [[TMP55:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[VLA]], i64 [[TMP9]]
// CHECK1-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq %struct.S.0* [[VLA]], [[TMP55]]
// CHECK1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE27:%.*]], label [[ARRAYDESTROY_BODY:%.*]]
// CHECK1: arraydestroy.body:
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP55]], [[DOTOMP_REDUCTION_DEFAULT]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
// CHECK1-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
// CHECK1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq %struct.S.0* [[ARRAYDESTROY_ELEMENT]], [[VLA]]
// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE27]], label [[ARRAYDESTROY_BODY]]
// CHECK1: arraydestroy.done27:
// CHECK1-NEXT: [[TMP56:%.*]] = load i8*, i8** [[SAVED_STACK]], align 8
// CHECK1-NEXT: call void @llvm.stackrestore(i8* [[TMP56]])
// CHECK1-NEXT: [[TMP57:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP58:%.*]] = load i32, i32* [[TMP57]], align 4
// CHECK1-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB4]], i32 [[TMP58]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.16
// CHECK1-SAME: (i8* noundef [[TMP0:%.*]], i8* noundef [[TMP1:%.*]]) #[[ATTR8]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8
// CHECK1-NEXT: store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [2 x i8*]*
// CHECK1-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [2 x i8*]*
// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[TMP5]], i64 0, i64 0
// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.S.0*
// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[TMP3]], i64 0, i64 0
// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
// CHECK1-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.S.0*
// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[TMP3]], i64 0, i64 1
// CHECK1-NEXT: [[TMP13:%.*]] = load i8*, i8** [[TMP12]], align 8
// CHECK1-NEXT: [[TMP14:%.*]] = ptrtoint i8* [[TMP13]] to i64
// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[TMP11]], i64 [[TMP14]]
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq %struct.S.0* [[TMP11]], [[TMP15]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE3:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
// CHECK1: omp.arraycpy.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP8]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP11]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[TMP16:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP16]], i64 4
// CHECK1-NEXT: [[TMP17:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP18:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR2:%.*]] = getelementptr inbounds i8, i8* [[TMP18]], i64 4
// CHECK1-NEXT: [[TMP19:%.*]] = bitcast i8* [[ADD_PTR2]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP17]], %struct.BaseS1* noundef [[TMP19]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT]], [[TMP15]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYCPY_DONE3]], label [[OMP_ARRAYCPY_BODY]]
// CHECK1: omp.arraycpy.done3:
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..17
// CHECK1-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], [5 x %struct.S.0]* noundef nonnull align 4 dereferenceable(60) [[VVAR2:%.*]]) #[[ATTR2]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[VVAR2_ADDR:%.*]] = alloca [5 x %struct.S.0]*, align 8
// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[VVAR22:%.*]] = alloca [5 x %struct.S.0], align 16
// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store [5 x %struct.S.0]* [[VVAR2]], [5 x %struct.S.0]** [[VVAR2_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = load [5 x %struct.S.0]*, [5 x %struct.S.0]** [[VVAR2_ADDR]], align 8
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 9, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [5 x %struct.S.0], [5 x %struct.S.0]* [[TMP0]], i64 0, i64 0
// CHECK1-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [5 x %struct.S.0], [5 x %struct.S.0]* [[TMP0]], i64 0, i64 4
// CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [5 x %struct.S.0], [5 x %struct.S.0]* [[VVAR22]], i32 0, i32 0
// CHECK1-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[ARRAY_BEGIN]], i64 5
// CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq %struct.S.0* [[ARRAY_BEGIN]], [[TMP1]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYINIT_ISEMPTY]], label [[OMP_ARRAYINIT_DONE:%.*]], label [[OMP_ARRAYINIT_BODY:%.*]]
// CHECK1: omp.arrayinit.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi %struct.S.0* [ [[ARRAYIDX]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYINIT_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi %struct.S.0* [ [[ARRAY_BEGIN]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT4:%.*]], [[OMP_ARRAYINIT_BODY]] ]
// CHECK1-NEXT: [[TMP2:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP2]], i64 4
// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP4:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR3:%.*]] = getelementptr inbounds i8, i8* [[TMP4]], i64 4
// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i8* [[ADD_PTR3]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_initializer..5(%struct.BaseS1* noundef [[TMP3]], %struct.BaseS1* noundef [[TMP5]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT4]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT4]], [[TMP1]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYINIT_DONE]], label [[OMP_ARRAYINIT_BODY]]
// CHECK1: omp.arrayinit.done:
// CHECK1-NEXT: [[TMP6:%.*]] = bitcast [5 x %struct.S.0]* [[TMP0]] to %struct.S.0*
// CHECK1-NEXT: [[TMP7:%.*]] = ptrtoint %struct.S.0* [[TMP6]] to i64
// CHECK1-NEXT: [[TMP8:%.*]] = ptrtoint %struct.S.0* [[ARRAYIDX]] to i64
// CHECK1-NEXT: [[TMP9:%.*]] = sub i64 [[TMP7]], [[TMP8]]
// CHECK1-NEXT: [[TMP10:%.*]] = sdiv exact i64 [[TMP9]], ptrtoint (%struct.S.0* getelementptr ([[STRUCT_S_0]], %struct.S.0* null, i32 1) to i64)
// CHECK1-NEXT: [[TMP11:%.*]] = bitcast [5 x %struct.S.0]* [[VVAR22]] to %struct.S.0*
// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[TMP11]], i64 [[TMP10]]
// CHECK1-NEXT: [[TMP13:%.*]] = bitcast %struct.S.0* [[TMP12]] to [5 x %struct.S.0]*
// CHECK1-NEXT: [[RHS_BEGIN:%.*]] = bitcast [5 x %struct.S.0]* [[VVAR22]] to %struct.S.0*
// CHECK1-NEXT: [[TMP14:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[TMP14]], align 4
// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP15]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP16]], 9
// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
// CHECK1: cond.true:
// CHECK1-NEXT: br label [[COND_END:%.*]]
// CHECK1: cond.false:
// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: br label [[COND_END]]
// CHECK1: cond.end:
// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP17]], [[COND_FALSE]] ]
// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 [[TMP18]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
// CHECK1: omp.inner.for.cond:
// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP19]], [[TMP20]]
// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]]
// CHECK1: omp.inner.for.cond.cleanup:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
// CHECK1: omp.inner.for.body:
// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP21]], 1
// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4
// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
// CHECK1: omp.body.continue:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
// CHECK1: omp.inner.for.inc:
// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP22]], 1
// CHECK1-NEXT: store i32 [[ADD6]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]]
// CHECK1: omp.inner.for.end:
// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
// CHECK1: omp.loop.exit:
// CHECK1-NEXT: [[TMP23:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[TMP23]], align 4
// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP24]])
// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// CHECK1-NEXT: [[TMP26:%.*]] = bitcast %struct.S.0* [[RHS_BEGIN]] to i8*
// CHECK1-NEXT: store i8* [[TMP26]], i8** [[TMP25]], align 8
// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4
// CHECK1-NEXT: [[TMP29:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
// CHECK1-NEXT: [[TMP30:%.*]] = call i32 @__kmpc_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP28]], i32 1, i64 8, i8* [[TMP29]], void (i8*, i8*)* @.omp.reduction.reduction_func.18, [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: switch i32 [[TMP30]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
// CHECK1-NEXT: ]
// CHECK1: .omp.reduction.case1:
// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[ARRAYIDX]], i64 5
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq %struct.S.0* [[ARRAYIDX]], [[TMP31]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE13:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
// CHECK1: omp.arraycpy.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST7:%.*]] = phi %struct.S.0* [ [[RHS_BEGIN]], [[DOTOMP_REDUCTION_CASE1]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST8:%.*]] = phi %struct.S.0* [ [[ARRAYIDX]], [[DOTOMP_REDUCTION_CASE1]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT11:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[TMP32:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST8]] to i8*
// CHECK1-NEXT: [[ADD_PTR9:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 4
// CHECK1-NEXT: [[TMP33:%.*]] = bitcast i8* [[ADD_PTR9]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP34:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST7]] to i8*
// CHECK1-NEXT: [[ADD_PTR10:%.*]] = getelementptr inbounds i8, i8* [[TMP34]], i64 4
// CHECK1-NEXT: [[TMP35:%.*]] = bitcast i8* [[ADD_PTR10]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP33]], %struct.BaseS1* noundef [[TMP35]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT11]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST8]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST7]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE12:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT11]], [[TMP31]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE12]], label [[OMP_ARRAYCPY_DONE13]], label [[OMP_ARRAYCPY_BODY]]
// CHECK1: omp.arraycpy.done13:
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP28]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.case2:
// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[ARRAYIDX]], i64 5
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY14:%.*]] = icmp eq %struct.S.0* [[ARRAYIDX]], [[TMP36]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY14]], label [[OMP_ARRAYCPY_DONE23:%.*]], label [[OMP_ARRAYCPY_BODY15:%.*]]
// CHECK1: omp.arraycpy.body15:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST16:%.*]] = phi %struct.S.0* [ [[RHS_BEGIN]], [[DOTOMP_REDUCTION_CASE2]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT21:%.*]], [[OMP_ARRAYCPY_BODY15]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST17:%.*]] = phi %struct.S.0* [ [[ARRAYIDX]], [[DOTOMP_REDUCTION_CASE2]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT20:%.*]], [[OMP_ARRAYCPY_BODY15]] ]
// CHECK1-NEXT: [[TMP37:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP38:%.*]] = load i32, i32* [[TMP37]], align 4
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP38]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[TMP39:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST17]] to i8*
// CHECK1-NEXT: [[ADD_PTR18:%.*]] = getelementptr inbounds i8, i8* [[TMP39]], i64 4
// CHECK1-NEXT: [[TMP40:%.*]] = bitcast i8* [[ADD_PTR18]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP41:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST16]] to i8*
// CHECK1-NEXT: [[ADD_PTR19:%.*]] = getelementptr inbounds i8, i8* [[TMP41]], i64 4
// CHECK1-NEXT: [[TMP42:%.*]] = bitcast i8* [[ADD_PTR19]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP40]], %struct.BaseS1* noundef [[TMP42]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP38]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT20]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST17]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT21]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST16]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE22:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT20]], [[TMP36]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE22]], label [[OMP_ARRAYCPY_DONE23]], label [[OMP_ARRAYCPY_BODY15]]
// CHECK1: omp.arraycpy.done23:
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP28]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.default:
// CHECK1-NEXT: [[ARRAY_BEGIN24:%.*]] = getelementptr inbounds [5 x %struct.S.0], [5 x %struct.S.0]* [[VVAR22]], i32 0, i32 0
// CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAY_BEGIN24]], i64 5
// CHECK1-NEXT: br label [[ARRAYDESTROY_BODY:%.*]]
// CHECK1: arraydestroy.body:
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP43]], [[DOTOMP_REDUCTION_DEFAULT]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
// CHECK1-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
// CHECK1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq %struct.S.0* [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN24]]
// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE25:%.*]], label [[ARRAYDESTROY_BODY]]
// CHECK1: arraydestroy.done25:
// CHECK1-NEXT: [[TMP44:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP45:%.*]] = load i32, i32* [[TMP44]], align 4
// CHECK1-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB4]], i32 [[TMP45]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.18
// CHECK1-SAME: (i8* noundef [[TMP0:%.*]], i8* noundef [[TMP1:%.*]]) #[[ATTR8]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8
// CHECK1-NEXT: store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
// CHECK1-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.S.0*
// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
// CHECK1-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.S.0*
// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[TMP11]], i64 5
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq %struct.S.0* [[TMP11]], [[TMP12]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE3:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
// CHECK1: omp.arraycpy.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP8]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP11]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[TMP13:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP13]], i64 4
// CHECK1-NEXT: [[TMP14:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP15:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR2:%.*]] = getelementptr inbounds i8, i8* [[TMP15]], i64 4
// CHECK1-NEXT: [[TMP16:%.*]] = bitcast i8* [[ADD_PTR2]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP14]], %struct.BaseS1* noundef [[TMP16]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT]], [[TMP12]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYCPY_DONE3]], label [[OMP_ARRAYCPY_BODY]]
// CHECK1: omp.arraycpy.done3:
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..19
// CHECK1-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], [4 x %struct.S.0]* noundef nonnull align 4 dereferenceable(48) [[VAR3:%.*]]) #[[ATTR2]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[VAR3_ADDR:%.*]] = alloca [4 x %struct.S.0]*, align 8
// CHECK1-NEXT: [[TMP:%.*]] = alloca [4 x %struct.S.0]*, align 8
// CHECK1-NEXT: [[_TMP1:%.*]] = alloca [4 x %struct.S.0]*, align 8
// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[_TMP2:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[VAR34:%.*]] = alloca [2 x %struct.S.0], align 16
// CHECK1-NEXT: [[_TMP7:%.*]] = alloca [4 x %struct.S.0]*, align 8
// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store [4 x %struct.S.0]* [[VAR3]], [4 x %struct.S.0]** [[VAR3_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = load [4 x %struct.S.0]*, [4 x %struct.S.0]** [[VAR3_ADDR]], align 8
// CHECK1-NEXT: store [4 x %struct.S.0]* [[TMP0]], [4 x %struct.S.0]** [[TMP]], align 8
// CHECK1-NEXT: [[TMP1:%.*]] = load [4 x %struct.S.0]*, [4 x %struct.S.0]** [[TMP]], align 8
// CHECK1-NEXT: store [4 x %struct.S.0]* [[TMP1]], [4 x %struct.S.0]** [[_TMP1]], align 8
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 9, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
// CHECK1-NEXT: [[TMP2:%.*]] = load [4 x %struct.S.0]*, [4 x %struct.S.0]** [[_TMP1]], align 8
// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x %struct.S.0], [4 x %struct.S.0]* [[TMP2]], i64 0, i64 1
// CHECK1-NEXT: [[TMP3:%.*]] = load [4 x %struct.S.0]*, [4 x %struct.S.0]** [[_TMP1]], align 8
// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [4 x %struct.S.0], [4 x %struct.S.0]* [[TMP3]], i64 0, i64 2
// CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[VAR34]], i32 0, i32 0
// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[ARRAY_BEGIN]], i64 2
// CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq %struct.S.0* [[ARRAY_BEGIN]], [[TMP4]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYINIT_ISEMPTY]], label [[OMP_ARRAYINIT_DONE:%.*]], label [[OMP_ARRAYINIT_BODY:%.*]]
// CHECK1: omp.arrayinit.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi %struct.S.0* [ [[ARRAYIDX]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYINIT_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi %struct.S.0* [ [[ARRAY_BEGIN]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT6:%.*]], [[OMP_ARRAYINIT_BODY]] ]
// CHECK1-NEXT: [[TMP5:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP5]], i64 4
// CHECK1-NEXT: [[TMP6:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP7:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR5:%.*]] = getelementptr inbounds i8, i8* [[TMP7]], i64 4
// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[ADD_PTR5]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_initializer..5(%struct.BaseS1* noundef [[TMP6]], %struct.BaseS1* noundef [[TMP8]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT6]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT6]], [[TMP4]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYINIT_DONE]], label [[OMP_ARRAYINIT_BODY]]
// CHECK1: omp.arrayinit.done:
// CHECK1-NEXT: [[TMP9:%.*]] = load [4 x %struct.S.0]*, [4 x %struct.S.0]** [[_TMP1]], align 8
// CHECK1-NEXT: [[TMP10:%.*]] = bitcast [4 x %struct.S.0]* [[TMP9]] to %struct.S.0*
// CHECK1-NEXT: [[TMP11:%.*]] = ptrtoint %struct.S.0* [[TMP10]] to i64
// CHECK1-NEXT: [[TMP12:%.*]] = ptrtoint %struct.S.0* [[ARRAYIDX]] to i64
// CHECK1-NEXT: [[TMP13:%.*]] = sub i64 [[TMP11]], [[TMP12]]
// CHECK1-NEXT: [[TMP14:%.*]] = sdiv exact i64 [[TMP13]], ptrtoint (%struct.S.0* getelementptr ([[STRUCT_S_0]], %struct.S.0* null, i32 1) to i64)
// CHECK1-NEXT: [[TMP15:%.*]] = bitcast [2 x %struct.S.0]* [[VAR34]] to %struct.S.0*
// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[TMP15]], i64 [[TMP14]]
// CHECK1-NEXT: [[TMP17:%.*]] = bitcast %struct.S.0* [[TMP16]] to [4 x %struct.S.0]*
// CHECK1-NEXT: store [4 x %struct.S.0]* [[TMP17]], [4 x %struct.S.0]** [[_TMP7]], align 8
// CHECK1-NEXT: [[RHS_BEGIN:%.*]] = bitcast [2 x %struct.S.0]* [[VAR34]] to %struct.S.0*
// CHECK1-NEXT: [[TMP18:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 4
// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP19]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP20]], 9
// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
// CHECK1: cond.true:
// CHECK1-NEXT: br label [[COND_END:%.*]]
// CHECK1: cond.false:
// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: br label [[COND_END]]
// CHECK1: cond.end:
// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP21]], [[COND_FALSE]] ]
// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 [[TMP22]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
// CHECK1: omp.inner.for.cond:
// CHECK1-NEXT: [[TMP23:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP23]], [[TMP24]]
// CHECK1-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]]
// CHECK1: omp.inner.for.cond.cleanup:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
// CHECK1: omp.inner.for.body:
// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP25]], 1
// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4
// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
// CHECK1: omp.body.continue:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
// CHECK1: omp.inner.for.inc:
// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[ADD9:%.*]] = add nsw i32 [[TMP26]], 1
// CHECK1-NEXT: store i32 [[ADD9]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]]
// CHECK1: omp.inner.for.end:
// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
// CHECK1: omp.loop.exit:
// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4
// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP28]])
// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// CHECK1-NEXT: [[TMP30:%.*]] = bitcast %struct.S.0* [[RHS_BEGIN]] to i8*
// CHECK1-NEXT: store i8* [[TMP30]], i8** [[TMP29]], align 8
// CHECK1-NEXT: [[TMP31:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[TMP31]], align 4
// CHECK1-NEXT: [[TMP33:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
// CHECK1-NEXT: [[TMP34:%.*]] = call i32 @__kmpc_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP32]], i32 1, i64 8, i8* [[TMP33]], void (i8*, i8*)* @.omp.reduction.reduction_func.20, [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: switch i32 [[TMP34]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
// CHECK1-NEXT: ]
// CHECK1: .omp.reduction.case1:
// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[ARRAYIDX]], i64 2
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq %struct.S.0* [[ARRAYIDX]], [[TMP35]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE16:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
// CHECK1: omp.arraycpy.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST10:%.*]] = phi %struct.S.0* [ [[RHS_BEGIN]], [[DOTOMP_REDUCTION_CASE1]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST11:%.*]] = phi %struct.S.0* [ [[ARRAYIDX]], [[DOTOMP_REDUCTION_CASE1]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT14:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[TMP36:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST11]] to i8*
// CHECK1-NEXT: [[ADD_PTR12:%.*]] = getelementptr inbounds i8, i8* [[TMP36]], i64 4
// CHECK1-NEXT: [[TMP37:%.*]] = bitcast i8* [[ADD_PTR12]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP38:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST10]] to i8*
// CHECK1-NEXT: [[ADD_PTR13:%.*]] = getelementptr inbounds i8, i8* [[TMP38]], i64 4
// CHECK1-NEXT: [[TMP39:%.*]] = bitcast i8* [[ADD_PTR13]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP37]], %struct.BaseS1* noundef [[TMP39]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT14]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST11]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST10]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE15:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT14]], [[TMP35]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE15]], label [[OMP_ARRAYCPY_DONE16]], label [[OMP_ARRAYCPY_BODY]]
// CHECK1: omp.arraycpy.done16:
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP32]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.case2:
// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[ARRAYIDX]], i64 2
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY17:%.*]] = icmp eq %struct.S.0* [[ARRAYIDX]], [[TMP40]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY17]], label [[OMP_ARRAYCPY_DONE26:%.*]], label [[OMP_ARRAYCPY_BODY18:%.*]]
// CHECK1: omp.arraycpy.body18:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST19:%.*]] = phi %struct.S.0* [ [[RHS_BEGIN]], [[DOTOMP_REDUCTION_CASE2]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT24:%.*]], [[OMP_ARRAYCPY_BODY18]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST20:%.*]] = phi %struct.S.0* [ [[ARRAYIDX]], [[DOTOMP_REDUCTION_CASE2]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT23:%.*]], [[OMP_ARRAYCPY_BODY18]] ]
// CHECK1-NEXT: [[TMP41:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP42:%.*]] = load i32, i32* [[TMP41]], align 4
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP42]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[TMP43:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST20]] to i8*
// CHECK1-NEXT: [[ADD_PTR21:%.*]] = getelementptr inbounds i8, i8* [[TMP43]], i64 4
// CHECK1-NEXT: [[TMP44:%.*]] = bitcast i8* [[ADD_PTR21]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP45:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST19]] to i8*
// CHECK1-NEXT: [[ADD_PTR22:%.*]] = getelementptr inbounds i8, i8* [[TMP45]], i64 4
// CHECK1-NEXT: [[TMP46:%.*]] = bitcast i8* [[ADD_PTR22]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP44]], %struct.BaseS1* noundef [[TMP46]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP42]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT23]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST20]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT24]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST19]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE25:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT23]], [[TMP40]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE25]], label [[OMP_ARRAYCPY_DONE26]], label [[OMP_ARRAYCPY_BODY18]]
// CHECK1: omp.arraycpy.done26:
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP32]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.default:
// CHECK1-NEXT: [[ARRAY_BEGIN27:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[VAR34]], i32 0, i32 0
// CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAY_BEGIN27]], i64 2
// CHECK1-NEXT: br label [[ARRAYDESTROY_BODY:%.*]]
// CHECK1: arraydestroy.body:
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP47]], [[DOTOMP_REDUCTION_DEFAULT]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
// CHECK1-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
// CHECK1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq %struct.S.0* [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN27]]
// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE28:%.*]], label [[ARRAYDESTROY_BODY]]
// CHECK1: arraydestroy.done28:
// CHECK1-NEXT: [[TMP48:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP49:%.*]] = load i32, i32* [[TMP48]], align 4
// CHECK1-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB4]], i32 [[TMP49]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.20
// CHECK1-SAME: (i8* noundef [[TMP0:%.*]], i8* noundef [[TMP1:%.*]]) #[[ATTR8]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8
// CHECK1-NEXT: store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
// CHECK1-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.S.0*
// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
// CHECK1-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.S.0*
// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[TMP11]], i64 2
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq %struct.S.0* [[TMP11]], [[TMP12]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE3:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
// CHECK1: omp.arraycpy.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP8]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP11]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[TMP13:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP13]], i64 4
// CHECK1-NEXT: [[TMP14:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP15:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR2:%.*]] = getelementptr inbounds i8, i8* [[TMP15]], i64 4
// CHECK1-NEXT: [[TMP16:%.*]] = bitcast i8* [[ADD_PTR2]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP14]], %struct.BaseS1* noundef [[TMP16]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT]], [[TMP12]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYCPY_DONE3]], label [[OMP_ARRAYCPY_BODY]]
// CHECK1: omp.arraycpy.done3:
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..21
// CHECK1-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], [4 x %struct.S.0]* noundef nonnull align 4 dereferenceable(48) [[VAR3:%.*]]) #[[ATTR2]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[VAR3_ADDR:%.*]] = alloca [4 x %struct.S.0]*, align 8
// CHECK1-NEXT: [[TMP:%.*]] = alloca [4 x %struct.S.0]*, align 8
// CHECK1-NEXT: [[_TMP1:%.*]] = alloca [4 x %struct.S.0]*, align 8
// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[_TMP2:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[_TMP5:%.*]] = alloca [4 x %struct.S.0]*, align 8
// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store [4 x %struct.S.0]* [[VAR3]], [4 x %struct.S.0]** [[VAR3_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = load [4 x %struct.S.0]*, [4 x %struct.S.0]** [[VAR3_ADDR]], align 8
// CHECK1-NEXT: store [4 x %struct.S.0]* [[TMP0]], [4 x %struct.S.0]** [[TMP]], align 8
// CHECK1-NEXT: [[TMP1:%.*]] = load [4 x %struct.S.0]*, [4 x %struct.S.0]** [[TMP]], align 8
// CHECK1-NEXT: store [4 x %struct.S.0]* [[TMP1]], [4 x %struct.S.0]** [[_TMP1]], align 8
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 9, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
// CHECK1-NEXT: [[TMP2:%.*]] = load [4 x %struct.S.0]*, [4 x %struct.S.0]** [[_TMP1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[TMP3]], align 4
// CHECK1-NEXT: [[DOTVAR3__VOID_ADDR:%.*]] = call i8* @__kmpc_alloc(i32 [[TMP4]], i64 48, i8* inttoptr (i64 6 to i8*))
// CHECK1-NEXT: [[DOTVAR3__ADDR:%.*]] = bitcast i8* [[DOTVAR3__VOID_ADDR]] to [4 x %struct.S.0]*
// CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [4 x %struct.S.0], [4 x %struct.S.0]* [[DOTVAR3__ADDR]], i32 0, i32 0
// CHECK1-NEXT: [[TMP5:%.*]] = bitcast [4 x %struct.S.0]* [[TMP2]] to %struct.S.0*
// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[ARRAY_BEGIN]], i64 4
// CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq %struct.S.0* [[ARRAY_BEGIN]], [[TMP6]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYINIT_ISEMPTY]], label [[OMP_ARRAYINIT_DONE:%.*]], label [[OMP_ARRAYINIT_BODY:%.*]]
// CHECK1: omp.arrayinit.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP5]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYINIT_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi %struct.S.0* [ [[ARRAY_BEGIN]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT4:%.*]], [[OMP_ARRAYINIT_BODY]] ]
// CHECK1-NEXT: [[TMP7:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP7]], i64 4
// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR3:%.*]] = getelementptr inbounds i8, i8* [[TMP9]], i64 4
// CHECK1-NEXT: [[TMP10:%.*]] = bitcast i8* [[ADD_PTR3]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_initializer..5(%struct.BaseS1* noundef [[TMP8]], %struct.BaseS1* noundef [[TMP10]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT4]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT4]], [[TMP6]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYINIT_DONE]], label [[OMP_ARRAYINIT_BODY]]
// CHECK1: omp.arrayinit.done:
// CHECK1-NEXT: store [4 x %struct.S.0]* [[DOTVAR3__ADDR]], [4 x %struct.S.0]** [[_TMP5]], align 8
// CHECK1-NEXT: [[LHS_BEGIN:%.*]] = bitcast [4 x %struct.S.0]* [[TMP2]] to %struct.S.0*
// CHECK1-NEXT: [[RHS_BEGIN:%.*]] = bitcast [4 x %struct.S.0]* [[DOTVAR3__ADDR]] to %struct.S.0*
// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP4]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP11]], 9
// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
// CHECK1: cond.true:
// CHECK1-NEXT: br label [[COND_END:%.*]]
// CHECK1: cond.false:
// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: br label [[COND_END]]
// CHECK1: cond.end:
// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
// CHECK1: omp.inner.for.cond:
// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP14]], [[TMP15]]
// CHECK1-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]]
// CHECK1: omp.inner.for.cond.cleanup:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
// CHECK1: omp.inner.for.body:
// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP16]], 1
// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4
// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
// CHECK1: omp.body.continue:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
// CHECK1: omp.inner.for.inc:
// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP17]], 1
// CHECK1-NEXT: store i32 [[ADD7]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]]
// CHECK1: omp.inner.for.end:
// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
// CHECK1: omp.loop.exit:
// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP4]])
// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// CHECK1-NEXT: [[TMP19:%.*]] = bitcast %struct.S.0* [[RHS_BEGIN]] to i8*
// CHECK1-NEXT: store i8* [[TMP19]], i8** [[TMP18]], align 8
// CHECK1-NEXT: [[TMP20:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
// CHECK1-NEXT: [[TMP21:%.*]] = call i32 @__kmpc_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP4]], i32 1, i64 8, i8* [[TMP20]], void (i8*, i8*)* @.omp.reduction.reduction_func.22, [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: switch i32 [[TMP21]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
// CHECK1-NEXT: ]
// CHECK1: .omp.reduction.case1:
// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[LHS_BEGIN]], i64 4
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq %struct.S.0* [[LHS_BEGIN]], [[TMP22]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE14:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
// CHECK1: omp.arraycpy.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST8:%.*]] = phi %struct.S.0* [ [[RHS_BEGIN]], [[DOTOMP_REDUCTION_CASE1]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST9:%.*]] = phi %struct.S.0* [ [[LHS_BEGIN]], [[DOTOMP_REDUCTION_CASE1]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT12:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[TMP23:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST9]] to i8*
// CHECK1-NEXT: [[ADD_PTR10:%.*]] = getelementptr inbounds i8, i8* [[TMP23]], i64 4
// CHECK1-NEXT: [[TMP24:%.*]] = bitcast i8* [[ADD_PTR10]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP25:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST8]] to i8*
// CHECK1-NEXT: [[ADD_PTR11:%.*]] = getelementptr inbounds i8, i8* [[TMP25]], i64 4
// CHECK1-NEXT: [[TMP26:%.*]] = bitcast i8* [[ADD_PTR11]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP24]], %struct.BaseS1* noundef [[TMP26]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT12]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST9]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST8]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE13:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT12]], [[TMP22]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE13]], label [[OMP_ARRAYCPY_DONE14]], label [[OMP_ARRAYCPY_BODY]]
// CHECK1: omp.arraycpy.done14:
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP4]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.case2:
// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[LHS_BEGIN]], i64 4
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY15:%.*]] = icmp eq %struct.S.0* [[LHS_BEGIN]], [[TMP27]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY15]], label [[OMP_ARRAYCPY_DONE24:%.*]], label [[OMP_ARRAYCPY_BODY16:%.*]]
// CHECK1: omp.arraycpy.body16:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST17:%.*]] = phi %struct.S.0* [ [[RHS_BEGIN]], [[DOTOMP_REDUCTION_CASE2]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT22:%.*]], [[OMP_ARRAYCPY_BODY16]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST18:%.*]] = phi %struct.S.0* [ [[LHS_BEGIN]], [[DOTOMP_REDUCTION_CASE2]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT21:%.*]], [[OMP_ARRAYCPY_BODY16]] ]
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[TMP28:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST18]] to i8*
// CHECK1-NEXT: [[ADD_PTR19:%.*]] = getelementptr inbounds i8, i8* [[TMP28]], i64 4
// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i8* [[ADD_PTR19]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP30:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST17]] to i8*
// CHECK1-NEXT: [[ADD_PTR20:%.*]] = getelementptr inbounds i8, i8* [[TMP30]], i64 4
// CHECK1-NEXT: [[TMP31:%.*]] = bitcast i8* [[ADD_PTR20]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP29]], %struct.BaseS1* noundef [[TMP31]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT21]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST18]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT22]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST17]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE23:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT21]], [[TMP27]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE23]], label [[OMP_ARRAYCPY_DONE24]], label [[OMP_ARRAYCPY_BODY16]]
// CHECK1: omp.arraycpy.done24:
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP4]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.default:
// CHECK1-NEXT: [[ARRAY_BEGIN25:%.*]] = getelementptr inbounds [4 x %struct.S.0], [4 x %struct.S.0]* [[DOTVAR3__ADDR]], i32 0, i32 0
// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAY_BEGIN25]], i64 4
// CHECK1-NEXT: br label [[ARRAYDESTROY_BODY:%.*]]
// CHECK1: arraydestroy.body:
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP32]], [[DOTOMP_REDUCTION_DEFAULT]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
// CHECK1-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
// CHECK1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq %struct.S.0* [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN25]]
// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE26:%.*]], label [[ARRAYDESTROY_BODY]]
// CHECK1: arraydestroy.done26:
// CHECK1-NEXT: [[TMP33:%.*]] = bitcast [4 x %struct.S.0]* [[DOTVAR3__ADDR]] to i8*
// CHECK1-NEXT: call void @__kmpc_free(i32 [[TMP4]], i8* [[TMP33]], i8* inttoptr (i64 6 to i8*))
// CHECK1-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB4]], i32 [[TMP4]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.22
// CHECK1-SAME: (i8* noundef [[TMP0:%.*]], i8* noundef [[TMP1:%.*]]) #[[ATTR8]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8
// CHECK1-NEXT: store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
// CHECK1-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.S.0*
// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
// CHECK1-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.S.0*
// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[TMP11]], i64 4
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq %struct.S.0* [[TMP11]], [[TMP12]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE3:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
// CHECK1: omp.arraycpy.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP8]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP11]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[TMP13:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP13]], i64 4
// CHECK1-NEXT: [[TMP14:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP15:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR2:%.*]] = getelementptr inbounds i8, i8* [[TMP15]], i64 4
// CHECK1-NEXT: [[TMP16:%.*]] = bitcast i8* [[ADD_PTR2]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP14]], %struct.BaseS1* noundef [[TMP16]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT]], [[TMP12]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYCPY_DONE3]], label [[OMP_ARRAYCPY_BODY]]
// CHECK1: omp.arraycpy.done3:
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@_Z5tmainIiLi42EET_v
// CHECK1-SAME: () #[[ATTR0]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[T:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[TEST:%.*]] = alloca [[STRUCT_S:%.*]], align 4
// CHECK1-NEXT: [[T_VAR:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[T_VAR1:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[VEC:%.*]] = alloca [2 x i32], align 4
// CHECK1-NEXT: [[S_ARR:%.*]] = alloca [2 x %struct.S], align 16
// CHECK1-NEXT: [[VAR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[VAR1:%.*]] = alloca [[STRUCT_S]], align 4
// CHECK1-NEXT: [[ARR:%.*]] = alloca [42 x %struct.S], align 16
// CHECK1-NEXT: call void @_ZN1SIiEC1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[TEST]])
// CHECK1-NEXT: store i32 0, i32* [[T_VAR]], align 4
// CHECK1-NEXT: [[TMP0:%.*]] = bitcast [2 x i32]* [[VEC]] to i8*
// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP0]], i8* align 4 bitcast ([2 x i32]* @__const._Z5tmainIiLi42EET_v.vec to i8*), i64 8, i1 false)
// CHECK1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[S_ARR]], i64 0, i64 0
// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_BEGIN]], i32 noundef 1)
// CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAYINIT_BEGIN]], i64 1
// CHECK1-NEXT: call void @_ZN1SIiEC1Ei(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT]], i32 noundef 2)
// CHECK1-NEXT: store %struct.S* [[TEST]], %struct.S** [[VAR]], align 8
// CHECK1-NEXT: call void @_ZN1SIiEC1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[VAR1]])
// CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [42 x %struct.S], [42 x %struct.S]* [[ARR]], i32 0, i32 0
// CHECK1-NEXT: [[ARRAYCTOR_END:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAY_BEGIN]], i64 42
// CHECK1-NEXT: br label [[ARRAYCTOR_LOOP:%.*]]
// CHECK1: arrayctor.loop:
// CHECK1-NEXT: [[ARRAYCTOR_CUR:%.*]] = phi %struct.S* [ [[ARRAY_BEGIN]], [[ENTRY:%.*]] ], [ [[ARRAYCTOR_NEXT:%.*]], [[ARRAYCTOR_LOOP]] ]
// CHECK1-NEXT: call void @_ZN1SIiEC1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYCTOR_CUR]])
// CHECK1-NEXT: [[ARRAYCTOR_NEXT]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAYCTOR_CUR]], i64 1
// CHECK1-NEXT: [[ARRAYCTOR_DONE:%.*]] = icmp eq %struct.S* [[ARRAYCTOR_NEXT]], [[ARRAYCTOR_END]]
// CHECK1-NEXT: br i1 [[ARRAYCTOR_DONE]], label [[ARRAYCTOR_CONT:%.*]], label [[ARRAYCTOR_LOOP]]
// CHECK1: arrayctor.cont:
// CHECK1-NEXT: [[TMP1:%.*]] = load %struct.S*, %struct.S** [[VAR]], align 8
// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 6, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, %struct.S*, %struct.S*, i32*, [2 x i32]*, [2 x %struct.S]*)* @.omp_outlined..23 to void (i32*, i32*, ...)*), i32* [[T_VAR]], %struct.S* [[TMP1]], %struct.S* [[VAR1]], i32* [[T_VAR1]], [2 x i32]* [[VEC]], [2 x %struct.S]* [[S_ARR]])
// CHECK1-NEXT: [[TMP2:%.*]] = load %struct.S*, %struct.S** [[VAR]], align 8
// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, [2 x i32]*, [2 x %struct.S]*, %struct.S*)* @.omp_outlined..31 to void (i32*, i32*, ...)*), i32* [[T_VAR]], [2 x i32]* [[VEC]], [2 x %struct.S]* [[S_ARR]], %struct.S* [[TMP2]])
// CHECK1-NEXT: [[TMP3:%.*]] = load %struct.S*, %struct.S** [[VAR]], align 8
// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [42 x %struct.S]*, [2 x i32]*, i32*, [2 x %struct.S]*, %struct.S*)* @.omp_outlined..35 to void (i32*, i32*, ...)*), [42 x %struct.S]* [[ARR]], [2 x i32]* [[VEC]], i32* [[T_VAR]], [2 x %struct.S]* [[S_ARR]], %struct.S* [[TMP3]])
// CHECK1-NEXT: store i32 0, i32* [[RETVAL]], align 4
// CHECK1-NEXT: [[ARRAY_BEGIN1:%.*]] = getelementptr inbounds [42 x %struct.S], [42 x %struct.S]* [[ARR]], i32 0, i32 0
// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAY_BEGIN1]], i64 42
// CHECK1-NEXT: br label [[ARRAYDESTROY_BODY:%.*]]
// CHECK1: arraydestroy.body:
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi %struct.S* [ [[TMP4]], [[ARRAYCTOR_CONT]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
// CHECK1-NEXT: call void @_ZN1SIiED1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
// CHECK1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq %struct.S* [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN1]]
// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE2:%.*]], label [[ARRAYDESTROY_BODY]]
// CHECK1: arraydestroy.done2:
// CHECK1-NEXT: call void @_ZN1SIiED1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[VAR1]]) #[[ATTR4]]
// CHECK1-NEXT: [[ARRAY_BEGIN3:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[S_ARR]], i32 0, i32 0
// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAY_BEGIN3]], i64 2
// CHECK1-NEXT: br label [[ARRAYDESTROY_BODY4:%.*]]
// CHECK1: arraydestroy.body4:
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST5:%.*]] = phi %struct.S* [ [[TMP5]], [[ARRAYDESTROY_DONE2]] ], [ [[ARRAYDESTROY_ELEMENT6:%.*]], [[ARRAYDESTROY_BODY4]] ]
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT6]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAYDESTROY_ELEMENTPAST5]], i64 -1
// CHECK1-NEXT: call void @_ZN1SIiED1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT6]]) #[[ATTR4]]
// CHECK1-NEXT: [[ARRAYDESTROY_DONE7:%.*]] = icmp eq %struct.S* [[ARRAYDESTROY_ELEMENT6]], [[ARRAY_BEGIN3]]
// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE7]], label [[ARRAYDESTROY_DONE8:%.*]], label [[ARRAYDESTROY_BODY4]]
// CHECK1: arraydestroy.done8:
// CHECK1-NEXT: call void @_ZN1SIiED1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[TEST]]) #[[ATTR4]]
// CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[RETVAL]], align 4
// CHECK1-NEXT: ret i32 [[TMP6]]
//
//
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIfEC2Ev
// CHECK1-SAME: (%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
// CHECK1-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = bitcast %struct.S.0* [[THIS1]] to %struct.BaseS*
// CHECK1-NEXT: [[TMP1:%.*]] = bitcast %struct.S.0* [[THIS1]] to i8*
// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 4
// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to %struct.BaseS1*
// CHECK1-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S_0:%.*]], %struct.S.0* [[THIS1]], i32 0, i32 2
// CHECK1-NEXT: [[TMP4:%.*]] = load volatile double, double* @g, align 8
// CHECK1-NEXT: [[CONV:%.*]] = fptrunc double [[TMP4]] to float
// CHECK1-NEXT: store float [[CONV]], float* [[F]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIfEC2Ef
// CHECK1-SAME: (%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]], float noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca float, align 4
// CHECK1-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
// CHECK1-NEXT: store float [[A]], float* [[A_ADDR]], align 4
// CHECK1-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = bitcast %struct.S.0* [[THIS1]] to %struct.BaseS*
// CHECK1-NEXT: [[TMP1:%.*]] = bitcast %struct.S.0* [[THIS1]] to i8*
// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 4
// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to %struct.BaseS1*
// CHECK1-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S_0:%.*]], %struct.S.0* [[THIS1]], i32 0, i32 2
// CHECK1-NEXT: [[TMP4:%.*]] = load float, float* [[A_ADDR]], align 4
// CHECK1-NEXT: [[CONV:%.*]] = fpext float [[TMP4]] to double
// CHECK1-NEXT: [[TMP5:%.*]] = load volatile double, double* @g, align 8
// CHECK1-NEXT: [[ADD:%.*]] = fadd double [[CONV]], [[TMP5]]
// CHECK1-NEXT: [[CONV2:%.*]] = fptrunc double [[ADD]] to float
// CHECK1-NEXT: store float [[CONV2]], float* [[F]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIfED2Ev
// CHECK1-SAME: (%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK1-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
// CHECK1-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiEC1Ei
// CHECK1-SAME: (%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
// CHECK1-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
// CHECK1-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4
// CHECK1-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4
// CHECK1-NEXT: call void @_ZN1SIiEC2Ei(%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS1]], i32 noundef [[TMP0]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..23
// CHECK1-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], i32* noundef nonnull align 4 dereferenceable(4) [[T_VAR:%.*]], %struct.S* noundef nonnull align 4 dereferenceable(12) [[VAR:%.*]], %struct.S* noundef nonnull align 4 dereferenceable(12) [[VAR1:%.*]], i32* noundef nonnull align 4 dereferenceable(4) [[T_VAR1:%.*]], [2 x i32]* noundef nonnull align 4 dereferenceable(8) [[VEC:%.*]], [2 x %struct.S]* noundef nonnull align 4 dereferenceable(24) [[S_ARR:%.*]]) #[[ATTR2]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[T_VAR_ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[VAR_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[VAR1_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[T_VAR1_ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[VEC_ADDR:%.*]] = alloca [2 x i32]*, align 8
// CHECK1-NEXT: [[S_ARR_ADDR:%.*]] = alloca [2 x %struct.S]*, align 8
// CHECK1-NEXT: [[TMP:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[_TMP1:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[_TMP2:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[T_VAR3:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[VAR4:%.*]] = alloca [[STRUCT_S:%.*]], align 4
// CHECK1-NEXT: [[_TMP6:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[VAR17:%.*]] = alloca [[STRUCT_S]], align 4
// CHECK1-NEXT: [[T_VAR18:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [4 x i8*], align 8
// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store i32* [[T_VAR]], i32** [[T_VAR_ADDR]], align 8
// CHECK1-NEXT: store %struct.S* [[VAR]], %struct.S** [[VAR_ADDR]], align 8
// CHECK1-NEXT: store %struct.S* [[VAR1]], %struct.S** [[VAR1_ADDR]], align 8
// CHECK1-NEXT: store i32* [[T_VAR1]], i32** [[T_VAR1_ADDR]], align 8
// CHECK1-NEXT: store [2 x i32]* [[VEC]], [2 x i32]** [[VEC_ADDR]], align 8
// CHECK1-NEXT: store [2 x %struct.S]* [[S_ARR]], [2 x %struct.S]** [[S_ARR_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = load i32*, i32** [[T_VAR_ADDR]], align 8
// CHECK1-NEXT: [[TMP1:%.*]] = load %struct.S*, %struct.S** [[VAR_ADDR]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load %struct.S*, %struct.S** [[VAR1_ADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[T_VAR1_ADDR]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = load [2 x i32]*, [2 x i32]** [[VEC_ADDR]], align 8
// CHECK1-NEXT: [[TMP5:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[S_ARR_ADDR]], align 8
// CHECK1-NEXT: store %struct.S* [[TMP1]], %struct.S** [[TMP]], align 8
// CHECK1-NEXT: [[TMP6:%.*]] = load %struct.S*, %struct.S** [[TMP]], align 8
// CHECK1-NEXT: store %struct.S* [[TMP6]], %struct.S** [[_TMP1]], align 8
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
// CHECK1-NEXT: call void @.omp_initializer..25(i32* noundef [[T_VAR3]], i32* noundef [[TMP0]])
// CHECK1-NEXT: [[TMP7:%.*]] = load %struct.S*, %struct.S** [[_TMP1]], align 8
// CHECK1-NEXT: [[TMP8:%.*]] = bitcast %struct.S* [[VAR4]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP8]], i64 4
// CHECK1-NEXT: [[TMP9:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
// CHECK1-NEXT: [[ADD_PTR5:%.*]] = getelementptr inbounds i8, i8* [[TMP10]], i64 4
// CHECK1-NEXT: [[TMP11:%.*]] = bitcast i8* [[ADD_PTR5]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_initializer..5(%struct.BaseS1* noundef [[TMP9]], %struct.BaseS1* noundef [[TMP11]])
// CHECK1-NEXT: store %struct.S* [[VAR4]], %struct.S** [[_TMP6]], align 8
// CHECK1-NEXT: call void @.omp_initializer..27(%struct.S* noundef [[VAR17]], %struct.S* noundef [[TMP2]])
// CHECK1-NEXT: call void @.omp_initializer..29(i32* noundef [[T_VAR18]], i32* noundef [[TMP3]])
// CHECK1-NEXT: [[TMP12:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4
// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP13]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP14]], 1
// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
// CHECK1: cond.true:
// CHECK1-NEXT: br label [[COND_END:%.*]]
// CHECK1: cond.false:
// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: br label [[COND_END]]
// CHECK1: cond.end:
// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 1, [[COND_TRUE]] ], [ [[TMP15]], [[COND_FALSE]] ]
// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 [[TMP16]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
// CHECK1: omp.inner.for.cond:
// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP9:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]]
// CHECK1-NEXT: br i1 [[CMP9]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]]
// CHECK1: omp.inner.for.cond.cleanup:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
// CHECK1: omp.inner.for.body:
// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP19]], 1
// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4
// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[T_VAR3]], align 4
// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[I]], align 4
// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP21]] to i64
// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP4]], i64 0, i64 [[IDXPROM]]
// CHECK1-NEXT: store i32 [[TMP20]], i32* [[ARRAYIDX]], align 4
// CHECK1-NEXT: [[TMP22:%.*]] = load %struct.S*, %struct.S** [[_TMP6]], align 8
// CHECK1-NEXT: [[TMP23:%.*]] = load i32, i32* [[I]], align 4
// CHECK1-NEXT: [[IDXPROM10:%.*]] = sext i32 [[TMP23]] to i64
// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP5]], i64 0, i64 [[IDXPROM10]]
// CHECK1-NEXT: [[CALL:%.*]] = call noundef nonnull align 4 dereferenceable(12) %struct.S* @_ZN1SIiEaSERKS0_(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYIDX11]], %struct.S* noundef nonnull align 4 dereferenceable(12) [[TMP22]])
// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
// CHECK1: omp.body.continue:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
// CHECK1: omp.inner.for.inc:
// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[ADD12:%.*]] = add nsw i32 [[TMP24]], 1
// CHECK1-NEXT: store i32 [[ADD12]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]]
// CHECK1: omp.inner.for.end:
// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
// CHECK1: omp.loop.exit:
// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP13]])
// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// CHECK1-NEXT: [[TMP26:%.*]] = bitcast i32* [[T_VAR3]] to i8*
// CHECK1-NEXT: store i8* [[TMP26]], i8** [[TMP25]], align 8
// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 1
// CHECK1-NEXT: [[TMP28:%.*]] = bitcast %struct.S* [[VAR4]] to i8*
// CHECK1-NEXT: store i8* [[TMP28]], i8** [[TMP27]], align 8
// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 2
// CHECK1-NEXT: [[TMP30:%.*]] = bitcast %struct.S* [[VAR17]] to i8*
// CHECK1-NEXT: store i8* [[TMP30]], i8** [[TMP29]], align 8
// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 3
// CHECK1-NEXT: [[TMP32:%.*]] = bitcast i32* [[T_VAR18]] to i8*
// CHECK1-NEXT: store i8* [[TMP32]], i8** [[TMP31]], align 8
// CHECK1-NEXT: [[TMP33:%.*]] = bitcast [4 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
// CHECK1-NEXT: [[TMP34:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* @[[GLOB3]], i32 [[TMP13]], i32 4, i64 32, i8* [[TMP33]], void (i8*, i8*)* @.omp.reduction.reduction_func.30, [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: switch i32 [[TMP34]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
// CHECK1-NEXT: ]
// CHECK1: .omp.reduction.case1:
// CHECK1-NEXT: call void @.omp_combiner..24(i32* noundef [[TMP0]], i32* noundef [[T_VAR3]])
// CHECK1-NEXT: [[TMP35:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
// CHECK1-NEXT: [[ADD_PTR13:%.*]] = getelementptr inbounds i8, i8* [[TMP35]], i64 4
// CHECK1-NEXT: [[TMP36:%.*]] = bitcast i8* [[ADD_PTR13]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP37:%.*]] = bitcast %struct.S* [[VAR4]] to i8*
// CHECK1-NEXT: [[ADD_PTR14:%.*]] = getelementptr inbounds i8, i8* [[TMP37]], i64 4
// CHECK1-NEXT: [[TMP38:%.*]] = bitcast i8* [[ADD_PTR14]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP36]], %struct.BaseS1* noundef [[TMP38]])
// CHECK1-NEXT: call void @.omp_combiner..26(%struct.S* noundef [[TMP2]], %struct.S* noundef [[VAR17]])
// CHECK1-NEXT: call void @.omp_combiner..28(i32* noundef [[TMP3]], i32* noundef [[T_VAR18]])
// CHECK1-NEXT: call void @__kmpc_end_reduce_nowait(%struct.ident_t* @[[GLOB3]], i32 [[TMP13]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.case2:
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP13]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @.omp_combiner..24(i32* noundef [[TMP0]], i32* noundef [[T_VAR3]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP13]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP13]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[TMP39:%.*]] = bitcast %struct.S* [[TMP7]] to i8*
// CHECK1-NEXT: [[ADD_PTR15:%.*]] = getelementptr inbounds i8, i8* [[TMP39]], i64 4
// CHECK1-NEXT: [[TMP40:%.*]] = bitcast i8* [[ADD_PTR15]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP41:%.*]] = bitcast %struct.S* [[VAR4]] to i8*
// CHECK1-NEXT: [[ADD_PTR16:%.*]] = getelementptr inbounds i8, i8* [[TMP41]], i64 4
// CHECK1-NEXT: [[TMP42:%.*]] = bitcast i8* [[ADD_PTR16]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP40]], %struct.BaseS1* noundef [[TMP42]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP13]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP13]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @.omp_combiner..26(%struct.S* noundef [[TMP2]], %struct.S* noundef [[VAR17]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP13]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP13]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @.omp_combiner..28(i32* noundef [[TMP3]], i32* noundef [[T_VAR18]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP13]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.default:
// CHECK1-NEXT: call void @_ZN1SIiED1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[VAR17]]) #[[ATTR4]]
// CHECK1-NEXT: call void @_ZN1SIiED1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[VAR4]]) #[[ATTR4]]
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_combiner..24
// CHECK1-SAME: (i32* noalias noundef [[TMP0:%.*]], i32* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: store i32* [[TMP0]], i32** [[DOTADDR]], align 8
// CHECK1-NEXT: store i32* [[TMP1]], i32** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[TMP2]], align 4
// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 1513, [[TMP4]]
// CHECK1-NEXT: store i32 [[ADD]], i32* [[TMP3]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_initializer..25
// CHECK1-SAME: (i32* noalias noundef [[TMP0:%.*]], i32* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: store i32* [[TMP0]], i32** [[DOTADDR]], align 8
// CHECK1-NEXT: store i32* [[TMP1]], i32** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTADDR]], align 8
// CHECK1-NEXT: store i32 321, i32* [[TMP3]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_combiner..26
// CHECK1-SAME: (%struct.S* noalias noundef [[TMP0:%.*]], %struct.S* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: store %struct.S* [[TMP0]], %struct.S** [[DOTADDR]], align 8
// CHECK1-NEXT: store %struct.S* [[TMP1]], %struct.S** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load %struct.S*, %struct.S** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load %struct.S*, %struct.S** [[DOTADDR]], align 8
// CHECK1-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[TMP2]], i32 0, i32 2
// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[F]], align 4
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 17, [[TMP4]]
// CHECK1-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP3]], i32 0, i32 2
// CHECK1-NEXT: store i32 [[MUL]], i32* [[F2]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_initializer..27
// CHECK1-SAME: (%struct.S* noalias noundef [[TMP0:%.*]], %struct.S* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: store %struct.S* [[TMP0]], %struct.S** [[DOTADDR]], align 8
// CHECK1-NEXT: store %struct.S* [[TMP1]], %struct.S** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load %struct.S*, %struct.S** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load %struct.S*, %struct.S** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = bitcast %struct.S* [[TMP3]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP4]], i64 4
// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP6:%.*]] = bitcast %struct.S* [[TMP2]] to i8*
// CHECK1-NEXT: [[ADD_PTR2:%.*]] = getelementptr inbounds i8, i8* [[TMP6]], i64 4
// CHECK1-NEXT: [[TMP7:%.*]] = bitcast i8* [[ADD_PTR2]] to %struct.BaseS1*
// CHECK1-NEXT: call void @_Z5init2R6BaseS1RKS_(%struct.BaseS1* noundef nonnull align 4 dereferenceable(4) [[TMP5]], %struct.BaseS1* noundef nonnull align 4 dereferenceable(4) [[TMP7]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_combiner..28
// CHECK1-SAME: (i32* noalias noundef [[TMP0:%.*]], i32* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: store i32* [[TMP0]], i32** [[DOTADDR]], align 8
// CHECK1-NEXT: store i32* [[TMP1]], i32** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[TMP2]], align 4
// CHECK1-NEXT: [[SUB:%.*]] = sub nsw i32 47, [[TMP4]]
// CHECK1-NEXT: store i32 [[SUB]], i32* [[TMP3]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_initializer..29
// CHECK1-SAME: (i32* noalias noundef [[TMP0:%.*]], i32* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: store i32* [[TMP0]], i32** [[DOTADDR]], align 8
// CHECK1-NEXT: store i32* [[TMP1]], i32** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[TMP2]], align 4
// CHECK1-NEXT: [[DIV:%.*]] = sdiv i32 432, [[TMP4]]
// CHECK1-NEXT: store i32 [[DIV]], i32* [[TMP3]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.30
// CHECK1-SAME: (i8* noundef [[TMP0:%.*]], i8* noundef [[TMP1:%.*]]) #[[ATTR8]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8
// CHECK1-NEXT: store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [4 x i8*]*
// CHECK1-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [4 x i8*]*
// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP5]], i64 0, i64 0
// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to i32*
// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP3]], i64 0, i64 0
// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
// CHECK1-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to i32*
// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP5]], i64 0, i64 1
// CHECK1-NEXT: [[TMP13:%.*]] = load i8*, i8** [[TMP12]], align 8
// CHECK1-NEXT: [[TMP14:%.*]] = bitcast i8* [[TMP13]] to %struct.S*
// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP3]], i64 0, i64 1
// CHECK1-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8
// CHECK1-NEXT: [[TMP17:%.*]] = bitcast i8* [[TMP16]] to %struct.S*
// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP5]], i64 0, i64 2
// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8
// CHECK1-NEXT: [[TMP20:%.*]] = bitcast i8* [[TMP19]] to %struct.S*
// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP3]], i64 0, i64 2
// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[TMP21]], align 8
// CHECK1-NEXT: [[TMP23:%.*]] = bitcast i8* [[TMP22]] to %struct.S*
// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP5]], i64 0, i64 3
// CHECK1-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8
// CHECK1-NEXT: [[TMP26:%.*]] = bitcast i8* [[TMP25]] to i32*
// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[TMP3]], i64 0, i64 3
// CHECK1-NEXT: [[TMP28:%.*]] = load i8*, i8** [[TMP27]], align 8
// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i8* [[TMP28]] to i32*
// CHECK1-NEXT: call void @.omp_combiner..24(i32* noundef [[TMP11]], i32* noundef [[TMP8]])
// CHECK1-NEXT: [[TMP30:%.*]] = bitcast %struct.S* [[TMP17]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP30]], i64 4
// CHECK1-NEXT: [[TMP31:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP32:%.*]] = bitcast %struct.S* [[TMP14]] to i8*
// CHECK1-NEXT: [[ADD_PTR2:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 4
// CHECK1-NEXT: [[TMP33:%.*]] = bitcast i8* [[ADD_PTR2]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..4(%struct.BaseS1* noundef [[TMP31]], %struct.BaseS1* noundef [[TMP33]])
// CHECK1-NEXT: call void @.omp_combiner..26(%struct.S* noundef [[TMP23]], %struct.S* noundef [[TMP20]])
// CHECK1-NEXT: call void @.omp_combiner..28(i32* noundef [[TMP29]], i32* noundef [[TMP26]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..31
// CHECK1-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], i32* noundef nonnull align 4 dereferenceable(4) [[T_VAR:%.*]], [2 x i32]* noundef nonnull align 4 dereferenceable(8) [[VEC:%.*]], [2 x %struct.S]* noundef nonnull align 4 dereferenceable(24) [[S_ARR:%.*]], %struct.S* noundef nonnull align 4 dereferenceable(12) [[VAR:%.*]]) #[[ATTR2]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[T_VAR_ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[VEC_ADDR:%.*]] = alloca [2 x i32]*, align 8
// CHECK1-NEXT: [[S_ARR_ADDR:%.*]] = alloca [2 x %struct.S]*, align 8
// CHECK1-NEXT: [[VAR_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[TMP:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[_TMP1:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[_TMP2:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[T_VAR3:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store i32* [[T_VAR]], i32** [[T_VAR_ADDR]], align 8
// CHECK1-NEXT: store [2 x i32]* [[VEC]], [2 x i32]** [[VEC_ADDR]], align 8
// CHECK1-NEXT: store [2 x %struct.S]* [[S_ARR]], [2 x %struct.S]** [[S_ARR_ADDR]], align 8
// CHECK1-NEXT: store %struct.S* [[VAR]], %struct.S** [[VAR_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = load i32*, i32** [[T_VAR_ADDR]], align 8
// CHECK1-NEXT: [[TMP1:%.*]] = load [2 x i32]*, [2 x i32]** [[VEC_ADDR]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[S_ARR_ADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load %struct.S*, %struct.S** [[VAR_ADDR]], align 8
// CHECK1-NEXT: store %struct.S* [[TMP3]], %struct.S** [[TMP]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = load %struct.S*, %struct.S** [[TMP]], align 8
// CHECK1-NEXT: store %struct.S* [[TMP4]], %struct.S** [[_TMP1]], align 8
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
// CHECK1-NEXT: [[TMP5:%.*]] = load i32, i32* @.init.32, align 4
// CHECK1-NEXT: store i32 [[TMP5]], i32* [[T_VAR3]], align 4
// CHECK1-NEXT: [[TMP6:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4
// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP7]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
// CHECK1-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP8]], 1
// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
// CHECK1: cond.true:
// CHECK1-NEXT: br label [[COND_END:%.*]]
// CHECK1: cond.false:
// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: br label [[COND_END]]
// CHECK1: cond.end:
// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 1, [[COND_TRUE]] ], [ [[TMP9]], [[COND_FALSE]] ]
// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 [[TMP10]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
// CHECK1: omp.inner.for.cond:
// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP4:%.*]] = icmp sle i32 [[TMP11]], [[TMP12]]
// CHECK1-NEXT: br i1 [[CMP4]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
// CHECK1: omp.inner.for.body:
// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP13]], 1
// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4
// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[T_VAR3]], align 4
// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[I]], align 4
// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP15]] to i64
// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP1]], i64 0, i64 [[IDXPROM]]
// CHECK1-NEXT: store i32 [[TMP14]], i32* [[ARRAYIDX]], align 4
// CHECK1-NEXT: [[TMP16:%.*]] = load %struct.S*, %struct.S** [[_TMP1]], align 8
// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[I]], align 4
// CHECK1-NEXT: [[IDXPROM5:%.*]] = sext i32 [[TMP17]] to i64
// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP2]], i64 0, i64 [[IDXPROM5]]
// CHECK1-NEXT: [[CALL:%.*]] = call noundef nonnull align 4 dereferenceable(12) %struct.S* @_ZN1SIiEaSERKS0_(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYIDX6]], %struct.S* noundef nonnull align 4 dereferenceable(12) [[TMP16]])
// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
// CHECK1: omp.body.continue:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
// CHECK1: omp.inner.for.inc:
// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP18]], 1
// CHECK1-NEXT: store i32 [[ADD7]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]]
// CHECK1: omp.inner.for.end:
// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
// CHECK1: omp.loop.exit:
// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP7]])
// CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// CHECK1-NEXT: [[TMP20:%.*]] = bitcast i32* [[T_VAR3]] to i8*
// CHECK1-NEXT: store i8* [[TMP20]], i8** [[TMP19]], align 8
// CHECK1-NEXT: [[TMP21:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
// CHECK1-NEXT: [[TMP22:%.*]] = call i32 @__kmpc_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP7]], i32 1, i64 8, i8* [[TMP21]], void (i8*, i8*)* @.omp.reduction.reduction_func.33, [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: switch i32 [[TMP22]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
// CHECK1-NEXT: ]
// CHECK1: .omp.reduction.case1:
// CHECK1-NEXT: call void @.omp_combiner..34(i32* noundef [[TMP0]], i32* noundef [[T_VAR3]])
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP7]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.case2:
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP7]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @.omp_combiner..34(i32* noundef [[TMP0]], i32* noundef [[T_VAR3]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP7]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP7]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.default:
// CHECK1-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB4]], i32 [[TMP7]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.33
// CHECK1-SAME: (i8* noundef [[TMP0:%.*]], i8* noundef [[TMP1:%.*]]) #[[ATTR8]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8
// CHECK1-NEXT: store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
// CHECK1-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to i32*
// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
// CHECK1-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to i32*
// CHECK1-NEXT: call void @.omp_combiner..34(i32* noundef [[TMP11]], i32* noundef [[TMP8]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_combiner..34
// CHECK1-SAME: (i32* noalias noundef [[TMP0:%.*]], i32* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: store i32* [[TMP0]], i32** [[DOTADDR]], align 8
// CHECK1-NEXT: store i32* [[TMP1]], i32** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[TMP2]], align 4
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 17, [[TMP4]]
// CHECK1-NEXT: store i32 [[MUL]], i32* [[TMP3]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..35
// CHECK1-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]], [42 x %struct.S]* noundef nonnull align 4 dereferenceable(504) [[ARR:%.*]], [2 x i32]* noundef nonnull align 4 dereferenceable(8) [[VEC:%.*]], i32* noundef nonnull align 4 dereferenceable(4) [[T_VAR:%.*]], [2 x %struct.S]* noundef nonnull align 4 dereferenceable(24) [[S_ARR:%.*]], %struct.S* noundef nonnull align 4 dereferenceable(12) [[VAR:%.*]]) #[[ATTR2]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[ARR_ADDR:%.*]] = alloca [42 x %struct.S]*, align 8
// CHECK1-NEXT: [[VEC_ADDR:%.*]] = alloca [2 x i32]*, align 8
// CHECK1-NEXT: [[T_VAR_ADDR:%.*]] = alloca i32*, align 8
// CHECK1-NEXT: [[S_ARR_ADDR:%.*]] = alloca [2 x %struct.S]*, align 8
// CHECK1-NEXT: [[VAR_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[TMP:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[_TMP1:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[_TMP2:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[ARR4:%.*]] = alloca [40 x %struct.S], align 16
// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4
// CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
// CHECK1-NEXT: store [42 x %struct.S]* [[ARR]], [42 x %struct.S]** [[ARR_ADDR]], align 8
// CHECK1-NEXT: store [2 x i32]* [[VEC]], [2 x i32]** [[VEC_ADDR]], align 8
// CHECK1-NEXT: store i32* [[T_VAR]], i32** [[T_VAR_ADDR]], align 8
// CHECK1-NEXT: store [2 x %struct.S]* [[S_ARR]], [2 x %struct.S]** [[S_ARR_ADDR]], align 8
// CHECK1-NEXT: store %struct.S* [[VAR]], %struct.S** [[VAR_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = load [42 x %struct.S]*, [42 x %struct.S]** [[ARR_ADDR]], align 8
// CHECK1-NEXT: [[TMP1:%.*]] = load [2 x i32]*, [2 x i32]** [[VEC_ADDR]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[T_VAR_ADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[S_ARR_ADDR]], align 8
// CHECK1-NEXT: [[TMP4:%.*]] = load %struct.S*, %struct.S** [[VAR_ADDR]], align 8
// CHECK1-NEXT: store %struct.S* [[TMP4]], %struct.S** [[TMP]], align 8
// CHECK1-NEXT: [[TMP5:%.*]] = load %struct.S*, %struct.S** [[TMP]], align 8
// CHECK1-NEXT: store %struct.S* [[TMP5]], %struct.S** [[_TMP1]], align 8
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [42 x %struct.S], [42 x %struct.S]* [[TMP0]], i64 0, i64 1
// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [42 x %struct.S], [42 x %struct.S]* [[TMP0]], i64 0, i64 40
// CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [40 x %struct.S], [40 x %struct.S]* [[ARR4]], i32 0, i32 0
// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr [[STRUCT_S:%.*]], %struct.S* [[ARRAY_BEGIN]], i64 40
// CHECK1-NEXT: [[OMP_ARRAYINIT_ISEMPTY:%.*]] = icmp eq %struct.S* [[ARRAY_BEGIN]], [[TMP6]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYINIT_ISEMPTY]], label [[OMP_ARRAYINIT_DONE:%.*]], label [[OMP_ARRAYINIT_BODY:%.*]]
// CHECK1: omp.arrayinit.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi %struct.S* [ [[ARRAYIDX]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYINIT_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi %struct.S* [ [[ARRAY_BEGIN]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT6:%.*]], [[OMP_ARRAYINIT_BODY]] ]
// CHECK1-NEXT: [[TMP7:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP7]], i64 4
// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR5:%.*]] = getelementptr inbounds i8, i8* [[TMP9]], i64 4
// CHECK1-NEXT: [[TMP10:%.*]] = bitcast i8* [[ADD_PTR5]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_initializer..37(%struct.BaseS1* noundef [[TMP8]], %struct.BaseS1* noundef [[TMP10]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT6]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq %struct.S* [[OMP_ARRAYCPY_DEST_ELEMENT6]], [[TMP6]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYINIT_DONE]], label [[OMP_ARRAYINIT_BODY]]
// CHECK1: omp.arrayinit.done:
// CHECK1-NEXT: [[TMP11:%.*]] = bitcast [42 x %struct.S]* [[TMP0]] to %struct.S*
// CHECK1-NEXT: [[TMP12:%.*]] = ptrtoint %struct.S* [[TMP11]] to i64
// CHECK1-NEXT: [[TMP13:%.*]] = ptrtoint %struct.S* [[ARRAYIDX]] to i64
// CHECK1-NEXT: [[TMP14:%.*]] = sub i64 [[TMP12]], [[TMP13]]
// CHECK1-NEXT: [[TMP15:%.*]] = sdiv exact i64 [[TMP14]], ptrtoint (%struct.S* getelementptr ([[STRUCT_S]], %struct.S* null, i32 1) to i64)
// CHECK1-NEXT: [[TMP16:%.*]] = bitcast [40 x %struct.S]* [[ARR4]] to %struct.S*
// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr [[STRUCT_S]], %struct.S* [[TMP16]], i64 [[TMP15]]
// CHECK1-NEXT: [[TMP18:%.*]] = bitcast %struct.S* [[TMP17]] to [42 x %struct.S]*
// CHECK1-NEXT: [[RHS_BEGIN:%.*]] = bitcast [40 x %struct.S]* [[ARR4]] to %struct.S*
// CHECK1-NEXT: [[TMP19:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[TMP19]], align 4
// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP20]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP21]], 1
// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
// CHECK1: cond.true:
// CHECK1-NEXT: br label [[COND_END:%.*]]
// CHECK1: cond.false:
// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: br label [[COND_END]]
// CHECK1: cond.end:
// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 1, [[COND_TRUE]] ], [ [[TMP22]], [[COND_FALSE]] ]
// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[TMP23:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
// CHECK1-NEXT: store i32 [[TMP23]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
// CHECK1: omp.inner.for.cond:
// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
// CHECK1-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP24]], [[TMP25]]
// CHECK1-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]]
// CHECK1: omp.inner.for.cond.cleanup:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
// CHECK1: omp.inner.for.body:
// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP26]], 1
// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4
// CHECK1-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP2]], align 4
// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[I]], align 4
// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP28]] to i64
// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP1]], i64 0, i64 [[IDXPROM]]
// CHECK1-NEXT: store i32 [[TMP27]], i32* [[ARRAYIDX8]], align 4
// CHECK1-NEXT: [[TMP29:%.*]] = load %struct.S*, %struct.S** [[_TMP1]], align 8
// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[I]], align 4
// CHECK1-NEXT: [[IDXPROM9:%.*]] = sext i32 [[TMP30]] to i64
// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP3]], i64 0, i64 [[IDXPROM9]]
// CHECK1-NEXT: [[CALL:%.*]] = call noundef nonnull align 4 dereferenceable(12) %struct.S* @_ZN1SIiEaSERKS0_(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYIDX10]], %struct.S* noundef nonnull align 4 dereferenceable(12) [[TMP29]])
// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
// CHECK1: omp.body.continue:
// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
// CHECK1: omp.inner.for.inc:
// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP31]], 1
// CHECK1-NEXT: store i32 [[ADD11]], i32* [[DOTOMP_IV]], align 4
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]]
// CHECK1: omp.inner.for.end:
// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
// CHECK1: omp.loop.exit:
// CHECK1-NEXT: [[TMP32:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP32]], align 4
// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP33]])
// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
// CHECK1-NEXT: [[TMP35:%.*]] = bitcast %struct.S* [[RHS_BEGIN]] to i8*
// CHECK1-NEXT: store i8* [[TMP35]], i8** [[TMP34]], align 8
// CHECK1-NEXT: [[TMP36:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP37:%.*]] = load i32, i32* [[TMP36]], align 4
// CHECK1-NEXT: [[TMP38:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
// CHECK1-NEXT: [[TMP39:%.*]] = call i32 @__kmpc_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP37]], i32 1, i64 8, i8* [[TMP38]], void (i8*, i8*)* @.omp.reduction.reduction_func.38, [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: switch i32 [[TMP39]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
// CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
// CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
// CHECK1-NEXT: ]
// CHECK1: .omp.reduction.case1:
// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr [[STRUCT_S]], %struct.S* [[ARRAYIDX]], i64 40
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq %struct.S* [[ARRAYIDX]], [[TMP40]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE18:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
// CHECK1: omp.arraycpy.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST12:%.*]] = phi %struct.S* [ [[RHS_BEGIN]], [[DOTOMP_REDUCTION_CASE1]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST13:%.*]] = phi %struct.S* [ [[ARRAYIDX]], [[DOTOMP_REDUCTION_CASE1]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT16:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[TMP41:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST13]] to i8*
// CHECK1-NEXT: [[ADD_PTR14:%.*]] = getelementptr inbounds i8, i8* [[TMP41]], i64 4
// CHECK1-NEXT: [[TMP42:%.*]] = bitcast i8* [[ADD_PTR14]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP43:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST12]] to i8*
// CHECK1-NEXT: [[ADD_PTR15:%.*]] = getelementptr inbounds i8, i8* [[TMP43]], i64 4
// CHECK1-NEXT: [[TMP44:%.*]] = bitcast i8* [[ADD_PTR15]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..36(%struct.BaseS1* noundef [[TMP42]], %struct.BaseS1* noundef [[TMP44]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT16]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST13]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST12]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE17:%.*]] = icmp eq %struct.S* [[OMP_ARRAYCPY_DEST_ELEMENT16]], [[TMP40]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE17]], label [[OMP_ARRAYCPY_DONE18]], label [[OMP_ARRAYCPY_BODY]]
// CHECK1: omp.arraycpy.done18:
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP37]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.case2:
// CHECK1-NEXT: [[TMP45:%.*]] = getelementptr [[STRUCT_S]], %struct.S* [[ARRAYIDX]], i64 40
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY19:%.*]] = icmp eq %struct.S* [[ARRAYIDX]], [[TMP45]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY19]], label [[OMP_ARRAYCPY_DONE28:%.*]], label [[OMP_ARRAYCPY_BODY20:%.*]]
// CHECK1: omp.arraycpy.body20:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST21:%.*]] = phi %struct.S* [ [[RHS_BEGIN]], [[DOTOMP_REDUCTION_CASE2]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT26:%.*]], [[OMP_ARRAYCPY_BODY20]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST22:%.*]] = phi %struct.S* [ [[ARRAYIDX]], [[DOTOMP_REDUCTION_CASE2]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT25:%.*]], [[OMP_ARRAYCPY_BODY20]] ]
// CHECK1-NEXT: [[TMP46:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP47:%.*]] = load i32, i32* [[TMP46]], align 4
// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP47]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[TMP48:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST22]] to i8*
// CHECK1-NEXT: [[ADD_PTR23:%.*]] = getelementptr inbounds i8, i8* [[TMP48]], i64 4
// CHECK1-NEXT: [[TMP49:%.*]] = bitcast i8* [[ADD_PTR23]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP50:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST21]] to i8*
// CHECK1-NEXT: [[ADD_PTR24:%.*]] = getelementptr inbounds i8, i8* [[TMP50]], i64 4
// CHECK1-NEXT: [[TMP51:%.*]] = bitcast i8* [[ADD_PTR24]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..36(%struct.BaseS1* noundef [[TMP49]], %struct.BaseS1* noundef [[TMP51]])
// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP47]], [8 x i32]* @.gomp_critical_user_.atomic_reduction.var)
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT25]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST22]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT26]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST21]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE27:%.*]] = icmp eq %struct.S* [[OMP_ARRAYCPY_DEST_ELEMENT25]], [[TMP45]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE27]], label [[OMP_ARRAYCPY_DONE28]], label [[OMP_ARRAYCPY_BODY20]]
// CHECK1: omp.arraycpy.done28:
// CHECK1-NEXT: call void @__kmpc_end_reduce(%struct.ident_t* @[[GLOB3]], i32 [[TMP37]], [8 x i32]* @.gomp_critical_user_.reduction.var)
// CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
// CHECK1: .omp.reduction.default:
// CHECK1-NEXT: [[ARRAY_BEGIN29:%.*]] = getelementptr inbounds [40 x %struct.S], [40 x %struct.S]* [[ARR4]], i32 0, i32 0
// CHECK1-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAY_BEGIN29]], i64 40
// CHECK1-NEXT: br label [[ARRAYDESTROY_BODY:%.*]]
// CHECK1: arraydestroy.body:
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi %struct.S* [ [[TMP52]], [[DOTOMP_REDUCTION_DEFAULT]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
// CHECK1-NEXT: call void @_ZN1SIiED1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]]
// CHECK1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq %struct.S* [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN29]]
// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE30:%.*]], label [[ARRAYDESTROY_BODY]]
// CHECK1: arraydestroy.done30:
// CHECK1-NEXT: [[TMP53:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
// CHECK1-NEXT: [[TMP54:%.*]] = load i32, i32* [[TMP53]], align 4
// CHECK1-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB4]], i32 [[TMP54]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_combiner..36
// CHECK1-SAME: (%struct.BaseS1* noalias noundef [[TMP0:%.*]], %struct.BaseS1* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca %struct.BaseS1*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca %struct.BaseS1*, align 8
// CHECK1-NEXT: store %struct.BaseS1* [[TMP0]], %struct.BaseS1** [[DOTADDR]], align 8
// CHECK1-NEXT: store %struct.BaseS1* [[TMP1]], %struct.BaseS1** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load %struct.BaseS1*, %struct.BaseS1** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load %struct.BaseS1*, %struct.BaseS1** [[DOTADDR]], align 8
// CHECK1-NEXT: call void @_Z8red_plusR6BaseS1RKS_(%struct.BaseS1* noundef nonnull align 4 dereferenceable(4) [[TMP3]], %struct.BaseS1* noundef nonnull align 4 dereferenceable(4) [[TMP2]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp_initializer..37
// CHECK1-SAME: (%struct.BaseS1* noalias noundef [[TMP0:%.*]], %struct.BaseS1* noalias noundef [[TMP1:%.*]]) #[[ATTR3]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca %struct.BaseS1*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca %struct.BaseS1*, align 8
// CHECK1-NEXT: store %struct.BaseS1* [[TMP0]], %struct.BaseS1** [[DOTADDR]], align 8
// CHECK1-NEXT: store %struct.BaseS1* [[TMP1]], %struct.BaseS1** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load %struct.BaseS1*, %struct.BaseS1** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = load %struct.BaseS1*, %struct.BaseS1** [[DOTADDR]], align 8
// CHECK1-NEXT: call void @_Z9init_plusR6BaseS1RKS_(%struct.BaseS1* noundef nonnull align 4 dereferenceable(4) [[TMP3]], %struct.BaseS1* noundef nonnull align 4 dereferenceable(4) [[TMP2]])
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func.38
// CHECK1-SAME: (i8* noundef [[TMP0:%.*]], i8* noundef [[TMP1:%.*]]) #[[ATTR8]] {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i8*, align 8
// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8
// CHECK1-NEXT: store i8* [[TMP1]], i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8
// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*
// CHECK1-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8
// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*
// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0
// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8
// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.S*
// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0
// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8
// CHECK1-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %struct.S*
// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr [[STRUCT_S:%.*]], %struct.S* [[TMP11]], i64 40
// CHECK1-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq %struct.S* [[TMP11]], [[TMP12]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE3:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]]
// CHECK1: omp.arraycpy.body:
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi %struct.S* [ [[TMP8]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi %struct.S* [ [[TMP11]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ]
// CHECK1-NEXT: [[TMP13:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[TMP13]], i64 4
// CHECK1-NEXT: [[TMP14:%.*]] = bitcast i8* [[ADD_PTR]] to %struct.BaseS1*
// CHECK1-NEXT: [[TMP15:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST]] to i8*
// CHECK1-NEXT: [[ADD_PTR2:%.*]] = getelementptr inbounds i8, i8* [[TMP15]], i64 4
// CHECK1-NEXT: [[TMP16:%.*]] = bitcast i8* [[ADD_PTR2]] to %struct.BaseS1*
// CHECK1-NEXT: call void @.omp_combiner..36(%struct.BaseS1* noundef [[TMP14]], %struct.BaseS1* noundef [[TMP16]])
// CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1
// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq %struct.S* [[OMP_ARRAYCPY_DEST_ELEMENT]], [[TMP12]]
// CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYCPY_DONE3]], label [[OMP_ARRAYCPY_BODY]]
// CHECK1: omp.arraycpy.done3:
// CHECK1-NEXT: ret void
//
//
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiEC2Ei
// CHECK1-SAME: (%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK1-NEXT: entry:
// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
// CHECK1-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
// CHECK1-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4
// CHECK1-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
// CHECK1-NEXT: [[TMP0:%.*]] = bitcast %struct.S* [[THIS1]] to %struct.BaseS*
// CHECK1-NEXT: [[TMP1:%.*]] = bitcast %struct.S* [[THIS1]] to i8*
// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 4
// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to %struct.BaseS1*
// CHECK1-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[THIS1]], i32 0, i32 2
// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[A_ADDR]], align 4
// CHECK1-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP4]] to double
// CHECK1-NEXT: [[TMP5:%.*]] = load volatile double, double* @g, align 8
// CHECK1-NEXT: [[ADD:%.*]] = fadd double [[CONV]], [[TMP5]]
// CHECK1-NEXT: [[CONV2:%.*]] = fptosi double [[ADD]] to i32
// CHECK1-NEXT: store i32 [[CONV2]], i32* [[F]], align 4
// CHECK1-NEXT: ret void
//
//
// CHECK3-LABEL: define {{[^@]+}}@_Z4bazzv
// CHECK3-SAME: () #[[ATTR0:[0-9]+]] {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 4
// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[S1:%.*]] = alloca [[STRUCT_S]], align 4
// CHECK3-NEXT: call void @_ZN1SIiEC1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[S]])
// CHECK3-NEXT: store i32 0, i32* [[DOTOMP_IV]], align 4
// CHECK3-NEXT: call void @.omp_initializer.(%struct.S* noundef [[S1]], %struct.S* noundef [[S]])
// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
// CHECK3: omp.inner.for.cond:
// CHECK3-NEXT: [[TMP0:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !2
// CHECK3-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10
// CHECK3-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]]
// CHECK3: omp.inner.for.cond.cleanup:
// CHECK3-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
// CHECK3: omp.inner.for.body:
// CHECK3-NEXT: [[TMP1:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !2
// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP1]], 1
// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
// CHECK3-NEXT: store i32 [[ADD]], i32* [[I]], align 4, !llvm.access.group !2
// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
// CHECK3: omp.body.continue:
// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
// CHECK3: omp.inner.for.inc:
// CHECK3-NEXT: [[TMP2:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !2
// CHECK3-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP2]], 1
// CHECK3-NEXT: store i32 [[ADD2]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !2
// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP3:![0-9]+]]
// CHECK3: omp.inner.for.end:
// CHECK3-NEXT: store i32 10, i32* [[I]], align 4
// CHECK3-NEXT: call void @.omp_combiner.(%struct.S* noundef [[S]], %struct.S* noundef [[S1]])
// CHECK3-NEXT: call void @_ZN1SIiED1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[S1]]) #[[ATTR7:[0-9]+]]
// CHECK3-NEXT: call void @_ZN1SIiED1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[S]]) #[[ATTR7]]
// CHECK3-NEXT: ret void
//
//
// CHECK3-LABEL: define {{[^@]+}}@_ZN1SIiEC1Ev
// CHECK3-SAME: (%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] align 2 {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
// CHECK3-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
// CHECK3-NEXT: call void @_ZN1SIiEC2Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS1]])
// CHECK3-NEXT: ret void
//
//
// CHECK3-LABEL: define {{[^@]+}}@.omp_combiner.
// CHECK3-SAME: (%struct.S* noalias noundef [[TMP0:%.*]], %struct.S* noalias noundef [[TMP1:%.*]]) #[[ATTR2:[0-9]+]] {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[DOTADDR:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: [[DOTADDR1:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: store %struct.S* [[TMP0]], %struct.S** [[DOTADDR]], align 8
// CHECK3-NEXT: store %struct.S* [[TMP1]], %struct.S** [[DOTADDR1]], align 8
// CHECK3-NEXT: [[TMP2:%.*]] = load %struct.S*, %struct.S** [[DOTADDR1]], align 8
// CHECK3-NEXT: [[TMP3:%.*]] = load %struct.S*, %struct.S** [[DOTADDR]], align 8
// CHECK3-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[TMP2]], i32 0, i32 2
// CHECK3-NEXT: [[TMP4:%.*]] = load i32, i32* [[F]], align 4
// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 17, [[TMP4]]
// CHECK3-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP3]], i32 0, i32 2
// CHECK3-NEXT: store i32 [[MUL]], i32* [[F2]], align 4
// CHECK3-NEXT: ret void
//
//
// CHECK3-LABEL: define {{[^@]+}}@.omp_initializer.
// CHECK3-SAME: (%struct.S* noalias noundef [[TMP0:%.*]], %struct.S* noalias noundef [[TMP1:%.*]]) #[[ATTR2]] {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[DOTADDR:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: [[DOTADDR1:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: store %struct.S* [[TMP0]], %struct.S** [[DOTADDR]], align 8
// CHECK3-NEXT: store %struct.S* [[TMP1]], %struct.S** [[DOTADDR1]], align 8
// CHECK3-NEXT: [[TMP2:%.*]] = load %struct.S*, %struct.S** [[DOTADDR1]], align 8
// CHECK3-NEXT: [[TMP3:%.*]] = load %struct.S*, %struct.S** [[DOTADDR]], align 8
// CHECK3-NEXT: call void @_ZN1SIiEC1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[TMP3]])
// CHECK3-NEXT: ret void
//
//
// CHECK3-LABEL: define {{[^@]+}}@_ZN1SIiED1Ev
// CHECK3-SAME: (%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
// CHECK3-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
// CHECK3-NEXT: call void @_ZN1SIiED2Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS1]]) #[[ATTR7]]
// CHECK3-NEXT: ret void
//
//
// CHECK3-LABEL: define {{[^@]+}}@main
// CHECK3-SAME: () #[[ATTR3:[0-9]+]] {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[TEST:%.*]] = alloca [[STRUCT_S_0:%.*]], align 4
// CHECK3-NEXT: [[T_VAR:%.*]] = alloca float, align 4
// CHECK3-NEXT: [[T_VAR1:%.*]] = alloca float, align 4
// CHECK3-NEXT: [[VEC:%.*]] = alloca [2 x i32], align 4
// CHECK3-NEXT: [[S_ARR:%.*]] = alloca [4 x %struct.S.0], align 16
// CHECK3-NEXT: [[VAR:%.*]] = alloca %struct.S.0*, align 8
// CHECK3-NEXT: [[VAR1:%.*]] = alloca [[STRUCT_S_0]], align 4
// CHECK3-NEXT: [[ARRS:%.*]] = alloca [10 x [4 x %struct.S.0]], align 16
// CHECK3-NEXT: [[VAR2:%.*]] = alloca %struct.S.0**, align 8
// CHECK3-NEXT: [[VVAR2:%.*]] = alloca [5 x %struct.S.0], align 16
// CHECK3-NEXT: [[VAR3:%.*]] = alloca [4 x %struct.S.0]*, align 8
// CHECK3-NEXT: [[TMP:%.*]] = alloca %struct.S.0*, align 8
// CHECK3-NEXT: [[_TMP10:%.*]] = alloca %struct.S.0*, align 8
// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[SAVED_STACK:%.*]] = alloca i8*, align 8
// CHECK3-NEXT: [[__VLA_EXPR0:%.*]] = alloca i64, align 8
// CHECK3-NEXT: [[I15:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[I26:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[I37:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[I44:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[_TMP51:%.*]] = alloca [4 x %struct.S.0]*, align 8
// CHECK3-NEXT: [[_TMP52:%.*]] = alloca [4 x %struct.S.0]*, align 8
// CHECK3-NEXT: [[I53:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[_TMP60:%.*]] = alloca [4 x %struct.S.0]*, align 8
// CHECK3-NEXT: [[_TMP61:%.*]] = alloca [4 x %struct.S.0]*, align 8
// CHECK3-NEXT: [[I62:%.*]] = alloca i32, align 4
// CHECK3-NEXT: store i32 0, i32* [[RETVAL]], align 4
// CHECK3-NEXT: call void @_ZN1SIfEC1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[TEST]])
// CHECK3-NEXT: store float 0.000000e+00, float* [[T_VAR]], align 4
// CHECK3-NEXT: [[TMP0:%.*]] = bitcast [2 x i32]* [[VEC]] to i8*
// CHECK3-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP0]], i8* align 4 bitcast ([2 x i32]* @__const.main.vec to i8*), i64 8, i1 false)
// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [4 x %struct.S.0], [4 x %struct.S.0]* [[S_ARR]], i64 0, i64 0
// CHECK3-NEXT: call void @_ZN1SIfEC1Ef(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_BEGIN]], float noundef 1.000000e+00)
// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYINIT_BEGIN]], i64 1
// CHECK3-NEXT: call void @_ZN1SIfEC1Ef(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT]], float noundef 2.000000e+00)
// CHECK3-NEXT: [[ARRAYINIT_ELEMENT1:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYINIT_ELEMENT]], i64 1
// CHECK3-NEXT: call void @_ZN1SIfEC1Ef(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT1]], float noundef 3.000000e+00)
// CHECK3-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYINIT_ELEMENT1]], i64 1
// CHECK3-NEXT: call void @_ZN1SIfEC1Ef(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT2]], float noundef 4.000000e+00)
// CHECK3-NEXT: store %struct.S.0* [[TEST]], %struct.S.0** [[VAR]], align 8
// CHECK3-NEXT: call void @_ZN1SIfEC1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[VAR1]])
// CHECK3-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [10 x [4 x %struct.S.0]], [10 x [4 x %struct.S.0]]* [[ARRS]], i32 0, i32 0, i32 0
// CHECK3-NEXT: [[ARRAYCTOR_END:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAY_BEGIN]], i64 40
// CHECK3-NEXT: br label [[ARRAYCTOR_LOOP:%.*]]
// CHECK3: arrayctor.loop:
// CHECK3-NEXT: [[ARRAYCTOR_CUR:%.*]] = phi %struct.S.0* [ [[ARRAY_BEGIN]], [[ENTRY:%.*]] ], [ [[ARRAYCTOR_NEXT:%.*]], [[ARRAYCTOR_LOOP]] ]
// CHECK3-NEXT: call void @_ZN1SIfEC1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYCTOR_CUR]])
// CHECK3-NEXT: [[ARRAYCTOR_NEXT]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYCTOR_CUR]], i64 1
// CHECK3-NEXT: [[ARRAYCTOR_DONE:%.*]] = icmp eq %struct.S.0* [[ARRAYCTOR_NEXT]], [[ARRAYCTOR_END]]
// CHECK3-NEXT: br i1 [[ARRAYCTOR_DONE]], label [[ARRAYCTOR_CONT:%.*]], label [[ARRAYCTOR_LOOP]]
// CHECK3: arrayctor.cont:
// CHECK3-NEXT: [[CALL:%.*]] = call noundef %struct.S.0** @_Z3foov()
// CHECK3-NEXT: store %struct.S.0** [[CALL]], %struct.S.0*** [[VAR2]], align 8
// CHECK3-NEXT: [[ARRAY_BEGIN3:%.*]] = getelementptr inbounds [5 x %struct.S.0], [5 x %struct.S.0]* [[VVAR2]], i32 0, i32 0
// CHECK3-NEXT: [[ARRAYCTOR_END4:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAY_BEGIN3]], i64 5
// CHECK3-NEXT: br label [[ARRAYCTOR_LOOP5:%.*]]
// CHECK3: arrayctor.loop5:
// CHECK3-NEXT: [[ARRAYCTOR_CUR6:%.*]] = phi %struct.S.0* [ [[ARRAY_BEGIN3]], [[ARRAYCTOR_CONT]] ], [ [[ARRAYCTOR_NEXT7:%.*]], [[ARRAYCTOR_LOOP5]] ]
// CHECK3-NEXT: call void @_ZN1SIfEC1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYCTOR_CUR6]])
// CHECK3-NEXT: [[ARRAYCTOR_NEXT7]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYCTOR_CUR6]], i64 1
// CHECK3-NEXT: [[ARRAYCTOR_DONE8:%.*]] = icmp eq %struct.S.0* [[ARRAYCTOR_NEXT7]], [[ARRAYCTOR_END4]]
// CHECK3-NEXT: br i1 [[ARRAYCTOR_DONE8]], label [[ARRAYCTOR_CONT9:%.*]], label [[ARRAYCTOR_LOOP5]]
// CHECK3: arrayctor.cont9:
// CHECK3-NEXT: store [4 x %struct.S.0]* [[S_ARR]], [4 x %struct.S.0]** [[VAR3]], align 8
// CHECK3-NEXT: [[TMP1:%.*]] = load %struct.S.0*, %struct.S.0** [[VAR]], align 8
// CHECK3-NEXT: store %struct.S.0* [[TMP1]], %struct.S.0** [[TMP]], align 8
// CHECK3-NEXT: [[TMP2:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP]], align 8
// CHECK3-NEXT: store %struct.S.0* [[TMP2]], %struct.S.0** [[_TMP10]], align 8
// CHECK3-NEXT: store i32 0, i32* [[I]], align 4
// CHECK3-NEXT: br label [[FOR_COND:%.*]]
// CHECK3: for.cond:
// CHECK3-NEXT: [[TMP3:%.*]] = load i32, i32* [[I]], align 4
// CHECK3-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP3]], 2
// CHECK3-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
// CHECK3: for.body:
// CHECK3-NEXT: [[TMP4:%.*]] = load float, float* [[T_VAR]], align 4
// CHECK3-NEXT: [[CONV:%.*]] = fptosi float [[TMP4]] to i32
// CHECK3-NEXT: [[TMP5:%.*]] = load i32, i32* [[I]], align 4
// CHECK3-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP5]] to i64
// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[VEC]], i64 0, i64 [[IDXPROM]]
// CHECK3-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
// CHECK3-NEXT: [[TMP6:%.*]] = load %struct.S.0*, %struct.S.0** [[_TMP10]], align 8
// CHECK3-NEXT: [[TMP7:%.*]] = load i32, i32* [[I]], align 4
// CHECK3-NEXT: [[IDXPROM11:%.*]] = sext i32 [[TMP7]] to i64
// CHECK3-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [4 x %struct.S.0], [4 x %struct.S.0]* [[S_ARR]], i64 0, i64 [[IDXPROM11]]
// CHECK3-NEXT: [[CALL13:%.*]] = call noundef nonnull align 4 dereferenceable(12) %struct.S.0* @_ZN1SIfEaSERKS0_(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYIDX12]], %struct.S.0* noundef nonnull align 4 dereferenceable(12) [[TMP6]])
// CHECK3-NEXT: br label [[FOR_INC:%.*]]
// CHECK3: for.inc:
// CHECK3-NEXT: [[TMP8:%.*]] = load i32, i32* [[I]], align 4
// CHECK3-NEXT: [[INC:%.*]] = add nsw i32 [[TMP8]], 1
// CHECK3-NEXT: store i32 [[INC]], i32* [[I]], align 4
// CHECK3-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP6:![0-9]+]]
// CHECK3: for.end:
// CHECK3-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[VEC]], i64 0, i64 1
// CHECK3-NEXT: [[TMP9:%.*]] = load i32, i32* [[ARRAYIDX14]], align 4
// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64
// CHECK3-NEXT: [[TMP11:%.*]] = call i8* @llvm.stacksave()
// CHECK3-NEXT: store i8* [[TMP11]], i8** [[SAVED_STACK]], align 8
// CHECK3-NEXT: [[TMP12:%.*]] = mul nuw i64 10, [[TMP10]]
// CHECK3-NEXT: [[VLA:%.*]] = alloca i32, i64 [[TMP12]], align 16
// CHECK3-NEXT: store i64 [[TMP10]], i64* [[__VLA_EXPR0]], align 8
// CHECK3-NEXT: store i32 0, i32* [[I15]], align 4
// CHECK3-NEXT: br label [[FOR_COND16:%.*]]
// CHECK3: for.cond16:
// CHECK3-NEXT: [[TMP13:%.*]] = load i32, i32* [[I15]], align 4
// CHECK3-NEXT: [[CMP17:%.*]] = icmp slt i32 [[TMP13]], 10
// CHECK3-NEXT: br i1 [[CMP17]], label [[FOR_BODY18:%.*]], label [[FOR_END25:%.*]]
// CHECK3: for.body18:
// CHECK3-NEXT: [[TMP14:%.*]] = mul nsw i64 1, [[TMP10]]
// CHECK3-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds i32, i32* [[VLA]], i64 [[TMP14]]
// CHECK3-NEXT: [[TMP15:%.*]] = load i32, i32* [[I15]], align 4
// CHECK3-NEXT: [[IDXPROM20:%.*]] = sext i32 [[TMP15]] to i64
// CHECK3-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds i32, i32* [[ARRAYIDX19]], i64 [[IDXPROM20]]
// CHECK3-NEXT: [[TMP16:%.*]] = load i32, i32* [[ARRAYIDX21]], align 4
// CHECK3-NEXT: [[INC22:%.*]] = add nsw i32 [[TMP16]], 1
// CHECK3-NEXT: store i32 [[INC22]], i32* [[ARRAYIDX21]], align 4
// CHECK3-NEXT: br label [[FOR_INC23:%.*]]
// CHECK3: for.inc23:
// CHECK3-NEXT: [[TMP17:%.*]] = load i32, i32* [[I15]], align 4
// CHECK3-NEXT: [[INC24:%.*]] = add nsw i32 [[TMP17]], 1
// CHECK3-NEXT: store i32 [[INC24]], i32* [[I15]], align 4
// CHECK3-NEXT: br label [[FOR_COND16]], !llvm.loop [[LOOP8:![0-9]+]]
// CHECK3: for.end25:
// CHECK3-NEXT: store i32 0, i32* [[I26]], align 4
// CHECK3-NEXT: br label [[FOR_COND27:%.*]]
// CHECK3: for.cond27:
// CHECK3-NEXT: [[TMP18:%.*]] = load i32, i32* [[I26]], align 4
// CHECK3-NEXT: [[CMP28:%.*]] = icmp slt i32 [[TMP18]], 10
// CHECK3-NEXT: br i1 [[CMP28]], label [[FOR_BODY29:%.*]], label [[FOR_END36:%.*]]
// CHECK3: for.body29:
// CHECK3-NEXT: [[TMP19:%.*]] = mul nsw i64 1, [[TMP10]]
// CHECK3-NEXT: [[ARRAYIDX30:%.*]] = getelementptr inbounds i32, i32* [[VLA]], i64 [[TMP19]]
// CHECK3-NEXT: [[TMP20:%.*]] = load i32, i32* [[I26]], align 4
// CHECK3-NEXT: [[IDXPROM31:%.*]] = sext i32 [[TMP20]] to i64
// CHECK3-NEXT: [[ARRAYIDX32:%.*]] = getelementptr inbounds i32, i32* [[ARRAYIDX30]], i64 [[IDXPROM31]]
// CHECK3-NEXT: [[TMP21:%.*]] = load i32, i32* [[ARRAYIDX32]], align 4
// CHECK3-NEXT: [[INC33:%.*]] = add nsw i32 [[TMP21]], 1
// CHECK3-NEXT: store i32 [[INC33]], i32* [[ARRAYIDX32]], align 4
// CHECK3-NEXT: br label [[FOR_INC34:%.*]]
// CHECK3: for.inc34:
// CHECK3-NEXT: [[TMP22:%.*]] = load i32, i32* [[I26]], align 4
// CHECK3-NEXT: [[INC35:%.*]] = add nsw i32 [[TMP22]], 1
// CHECK3-NEXT: store i32 [[INC35]], i32* [[I26]], align 4
// CHECK3-NEXT: br label [[FOR_COND27]], !llvm.loop [[LOOP9:![0-9]+]]
// CHECK3: for.end36:
// CHECK3-NEXT: store i32 0, i32* [[I37]], align 4
// CHECK3-NEXT: br label [[FOR_COND38:%.*]]
// CHECK3: for.cond38:
// CHECK3-NEXT: [[TMP23:%.*]] = load i32, i32* [[I37]], align 4
// CHECK3-NEXT: [[CMP39:%.*]] = icmp slt i32 [[TMP23]], 10
// CHECK3-NEXT: br i1 [[CMP39]], label [[FOR_BODY40:%.*]], label [[FOR_END43:%.*]]
// CHECK3: for.body40:
// CHECK3-NEXT: br label [[FOR_INC41:%.*]]
// CHECK3: for.inc41:
// CHECK3-NEXT: [[TMP24:%.*]] = load i32, i32* [[I37]], align 4
// CHECK3-NEXT: [[INC42:%.*]] = add nsw i32 [[TMP24]], 1
// CHECK3-NEXT: store i32 [[INC42]], i32* [[I37]], align 4
// CHECK3-NEXT: br label [[FOR_COND38]], !llvm.loop [[LOOP10:![0-9]+]]
// CHECK3: for.end43:
// CHECK3-NEXT: store i32 0, i32* [[I44]], align 4
// CHECK3-NEXT: br label [[FOR_COND45:%.*]]
// CHECK3: for.cond45:
// CHECK3-NEXT: [[TMP25:%.*]] = load i32, i32* [[I44]], align 4
// CHECK3-NEXT: [[CMP46:%.*]] = icmp slt i32 [[TMP25]], 10
// CHECK3-NEXT: br i1 [[CMP46]], label [[FOR_BODY47:%.*]], label [[FOR_END50:%.*]]
// CHECK3: for.body47:
// CHECK3-NEXT: br label [[FOR_INC48:%.*]]
// CHECK3: for.inc48:
// CHECK3-NEXT: [[TMP26:%.*]] = load i32, i32* [[I44]], align 4
// CHECK3-NEXT: [[INC49:%.*]] = add nsw i32 [[TMP26]], 1
// CHECK3-NEXT: store i32 [[INC49]], i32* [[I44]], align 4
// CHECK3-NEXT: br label [[FOR_COND45]], !llvm.loop [[LOOP11:![0-9]+]]
// CHECK3: for.end50:
// CHECK3-NEXT: [[TMP27:%.*]] = load [4 x %struct.S.0]*, [4 x %struct.S.0]** [[VAR3]], align 8
// CHECK3-NEXT: store [4 x %struct.S.0]* [[TMP27]], [4 x %struct.S.0]** [[_TMP51]], align 8
// CHECK3-NEXT: [[TMP28:%.*]] = load [4 x %struct.S.0]*, [4 x %struct.S.0]** [[_TMP51]], align 8
// CHECK3-NEXT: store [4 x %struct.S.0]* [[TMP28]], [4 x %struct.S.0]** [[_TMP52]], align 8
// CHECK3-NEXT: store i32 0, i32* [[I53]], align 4
// CHECK3-NEXT: br label [[FOR_COND54:%.*]]
// CHECK3: for.cond54:
// CHECK3-NEXT: [[TMP29:%.*]] = load i32, i32* [[I53]], align 4
// CHECK3-NEXT: [[CMP55:%.*]] = icmp slt i32 [[TMP29]], 10
// CHECK3-NEXT: br i1 [[CMP55]], label [[FOR_BODY56:%.*]], label [[FOR_END59:%.*]]
// CHECK3: for.body56:
// CHECK3-NEXT: br label [[FOR_INC57:%.*]]
// CHECK3: for.inc57:
// CHECK3-NEXT: [[TMP30:%.*]] = load i32, i32* [[I53]], align 4
// CHECK3-NEXT: [[INC58:%.*]] = add nsw i32 [[TMP30]], 1
// CHECK3-NEXT: store i32 [[INC58]], i32* [[I53]], align 4
// CHECK3-NEXT: br label [[FOR_COND54]], !llvm.loop [[LOOP12:![0-9]+]]
// CHECK3: for.end59:
// CHECK3-NEXT: [[TMP31:%.*]] = load [4 x %struct.S.0]*, [4 x %struct.S.0]** [[VAR3]], align 8
// CHECK3-NEXT: store [4 x %struct.S.0]* [[TMP31]], [4 x %struct.S.0]** [[_TMP60]], align 8
// CHECK3-NEXT: [[TMP32:%.*]] = load [4 x %struct.S.0]*, [4 x %struct.S.0]** [[_TMP60]], align 8
// CHECK3-NEXT: store [4 x %struct.S.0]* [[TMP32]], [4 x %struct.S.0]** [[_TMP61]], align 8
// CHECK3-NEXT: store i32 0, i32* [[I62]], align 4
// CHECK3-NEXT: br label [[FOR_COND63:%.*]]
// CHECK3: for.cond63:
// CHECK3-NEXT: [[TMP33:%.*]] = load i32, i32* [[I62]], align 4
// CHECK3-NEXT: [[CMP64:%.*]] = icmp slt i32 [[TMP33]], 10
// CHECK3-NEXT: br i1 [[CMP64]], label [[FOR_BODY65:%.*]], label [[FOR_END68:%.*]]
// CHECK3: for.body65:
// CHECK3-NEXT: br label [[FOR_INC66:%.*]]
// CHECK3: for.inc66:
// CHECK3-NEXT: [[TMP34:%.*]] = load i32, i32* [[I62]], align 4
// CHECK3-NEXT: [[INC67:%.*]] = add nsw i32 [[TMP34]], 1
// CHECK3-NEXT: store i32 [[INC67]], i32* [[I62]], align 4
// CHECK3-NEXT: br label [[FOR_COND63]], !llvm.loop [[LOOP13:![0-9]+]]
// CHECK3: for.end68:
// CHECK3-NEXT: [[CALL69:%.*]] = call noundef i32 @_Z5tmainIiLi42EET_v()
// CHECK3-NEXT: store i32 [[CALL69]], i32* [[RETVAL]], align 4
// CHECK3-NEXT: [[TMP35:%.*]] = load i8*, i8** [[SAVED_STACK]], align 8
// CHECK3-NEXT: call void @llvm.stackrestore(i8* [[TMP35]])
// CHECK3-NEXT: [[ARRAY_BEGIN70:%.*]] = getelementptr inbounds [5 x %struct.S.0], [5 x %struct.S.0]* [[VVAR2]], i32 0, i32 0
// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAY_BEGIN70]], i64 5
// CHECK3-NEXT: br label [[ARRAYDESTROY_BODY:%.*]]
// CHECK3: arraydestroy.body:
// CHECK3-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi %struct.S.0* [ [[TMP36]], [[FOR_END68]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
// CHECK3-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
// CHECK3-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR7]]
// CHECK3-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq %struct.S.0* [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN70]]
// CHECK3-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE71:%.*]], label [[ARRAYDESTROY_BODY]]
// CHECK3: arraydestroy.done71:
// CHECK3-NEXT: [[ARRAY_BEGIN72:%.*]] = getelementptr inbounds [10 x [4 x %struct.S.0]], [10 x [4 x %struct.S.0]]* [[ARRS]], i32 0, i32 0, i32 0
// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAY_BEGIN72]], i64 40
// CHECK3-NEXT: br label [[ARRAYDESTROY_BODY73:%.*]]
// CHECK3: arraydestroy.body73:
// CHECK3-NEXT: [[ARRAYDESTROY_ELEMENTPAST74:%.*]] = phi %struct.S.0* [ [[TMP37]], [[ARRAYDESTROY_DONE71]] ], [ [[ARRAYDESTROY_ELEMENT75:%.*]], [[ARRAYDESTROY_BODY73]] ]
// CHECK3-NEXT: [[ARRAYDESTROY_ELEMENT75]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYDESTROY_ELEMENTPAST74]], i64 -1
// CHECK3-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT75]]) #[[ATTR7]]
// CHECK3-NEXT: [[ARRAYDESTROY_DONE76:%.*]] = icmp eq %struct.S.0* [[ARRAYDESTROY_ELEMENT75]], [[ARRAY_BEGIN72]]
// CHECK3-NEXT: br i1 [[ARRAYDESTROY_DONE76]], label [[ARRAYDESTROY_DONE77:%.*]], label [[ARRAYDESTROY_BODY73]]
// CHECK3: arraydestroy.done77:
// CHECK3-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[VAR1]]) #[[ATTR7]]
// CHECK3-NEXT: [[ARRAY_BEGIN78:%.*]] = getelementptr inbounds [4 x %struct.S.0], [4 x %struct.S.0]* [[S_ARR]], i32 0, i32 0
// CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAY_BEGIN78]], i64 4
// CHECK3-NEXT: br label [[ARRAYDESTROY_BODY79:%.*]]
// CHECK3: arraydestroy.body79:
// CHECK3-NEXT: [[ARRAYDESTROY_ELEMENTPAST80:%.*]] = phi %struct.S.0* [ [[TMP38]], [[ARRAYDESTROY_DONE77]] ], [ [[ARRAYDESTROY_ELEMENT81:%.*]], [[ARRAYDESTROY_BODY79]] ]
// CHECK3-NEXT: [[ARRAYDESTROY_ELEMENT81]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[ARRAYDESTROY_ELEMENTPAST80]], i64 -1
// CHECK3-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT81]]) #[[ATTR7]]
// CHECK3-NEXT: [[ARRAYDESTROY_DONE82:%.*]] = icmp eq %struct.S.0* [[ARRAYDESTROY_ELEMENT81]], [[ARRAY_BEGIN78]]
// CHECK3-NEXT: br i1 [[ARRAYDESTROY_DONE82]], label [[ARRAYDESTROY_DONE83:%.*]], label [[ARRAYDESTROY_BODY79]]
// CHECK3: arraydestroy.done83:
// CHECK3-NEXT: call void @_ZN1SIfED1Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[TEST]]) #[[ATTR7]]
// CHECK3-NEXT: [[TMP39:%.*]] = load i32, i32* [[RETVAL]], align 4
// CHECK3-NEXT: ret i32 [[TMP39]]
//
//
// CHECK3-LABEL: define {{[^@]+}}@_ZN1SIfEC1Ev
// CHECK3-SAME: (%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK3-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
// CHECK3-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
// CHECK3-NEXT: call void @_ZN1SIfEC2Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS1]])
// CHECK3-NEXT: ret void
//
//
// CHECK3-LABEL: define {{[^@]+}}@_ZN1SIfEC1Ef
// CHECK3-SAME: (%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]], float noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK3-NEXT: [[A_ADDR:%.*]] = alloca float, align 4
// CHECK3-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
// CHECK3-NEXT: store float [[A]], float* [[A_ADDR]], align 4
// CHECK3-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
// CHECK3-NEXT: [[TMP0:%.*]] = load float, float* [[A_ADDR]], align 4
// CHECK3-NEXT: call void @_ZN1SIfEC2Ef(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS1]], float noundef [[TMP0]])
// CHECK3-NEXT: ret void
//
//
// CHECK3-LABEL: define {{[^@]+}}@_Z5tmainIiLi42EET_v
// CHECK3-SAME: () #[[ATTR0]] {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[T:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[TEST:%.*]] = alloca [[STRUCT_S:%.*]], align 4
// CHECK3-NEXT: [[T_VAR:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[T_VAR1:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[VEC:%.*]] = alloca [2 x i32], align 4
// CHECK3-NEXT: [[S_ARR:%.*]] = alloca [2 x %struct.S], align 16
// CHECK3-NEXT: [[VAR:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: [[VAR1:%.*]] = alloca [[STRUCT_S]], align 4
// CHECK3-NEXT: [[ARR:%.*]] = alloca [42 x %struct.S], align 16
// CHECK3-NEXT: [[TMP:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: [[_TMP1:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[_TMP4:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: [[_TMP5:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: [[I6:%.*]] = alloca i32, align 4
// CHECK3-NEXT: [[_TMP18:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: [[_TMP19:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: [[I20:%.*]] = alloca i32, align 4
// CHECK3-NEXT: call void @_ZN1SIiEC1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[TEST]])
// CHECK3-NEXT: store i32 0, i32* [[T_VAR]], align 4
// CHECK3-NEXT: [[TMP0:%.*]] = bitcast [2 x i32]* [[VEC]] to i8*
// CHECK3-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP0]], i8* align 4 bitcast ([2 x i32]* @__const._Z5tmainIiLi42EET_v.vec to i8*), i64 8, i1 false)
// CHECK3-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[S_ARR]], i64 0, i64 0
// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_BEGIN]], i32 noundef 1)
// CHECK3-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAYINIT_BEGIN]], i64 1
// CHECK3-NEXT: call void @_ZN1SIiEC1Ei(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYINIT_ELEMENT]], i32 noundef 2)
// CHECK3-NEXT: store %struct.S* [[TEST]], %struct.S** [[VAR]], align 8
// CHECK3-NEXT: call void @_ZN1SIiEC1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[VAR1]])
// CHECK3-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [42 x %struct.S], [42 x %struct.S]* [[ARR]], i32 0, i32 0
// CHECK3-NEXT: [[ARRAYCTOR_END:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAY_BEGIN]], i64 42
// CHECK3-NEXT: br label [[ARRAYCTOR_LOOP:%.*]]
// CHECK3: arrayctor.loop:
// CHECK3-NEXT: [[ARRAYCTOR_CUR:%.*]] = phi %struct.S* [ [[ARRAY_BEGIN]], [[ENTRY:%.*]] ], [ [[ARRAYCTOR_NEXT:%.*]], [[ARRAYCTOR_LOOP]] ]
// CHECK3-NEXT: call void @_ZN1SIiEC1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYCTOR_CUR]])
// CHECK3-NEXT: [[ARRAYCTOR_NEXT]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAYCTOR_CUR]], i64 1
// CHECK3-NEXT: [[ARRAYCTOR_DONE:%.*]] = icmp eq %struct.S* [[ARRAYCTOR_NEXT]], [[ARRAYCTOR_END]]
// CHECK3-NEXT: br i1 [[ARRAYCTOR_DONE]], label [[ARRAYCTOR_CONT:%.*]], label [[ARRAYCTOR_LOOP]]
// CHECK3: arrayctor.cont:
// CHECK3-NEXT: [[TMP1:%.*]] = load %struct.S*, %struct.S** [[VAR]], align 8
// CHECK3-NEXT: store %struct.S* [[TMP1]], %struct.S** [[TMP]], align 8
// CHECK3-NEXT: [[TMP2:%.*]] = load %struct.S*, %struct.S** [[TMP]], align 8
// CHECK3-NEXT: store %struct.S* [[TMP2]], %struct.S** [[_TMP1]], align 8
// CHECK3-NEXT: store i32 0, i32* [[I]], align 4
// CHECK3-NEXT: br label [[FOR_COND:%.*]]
// CHECK3: for.cond:
// CHECK3-NEXT: [[TMP3:%.*]] = load i32, i32* [[I]], align 4
// CHECK3-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP3]], 2
// CHECK3-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
// CHECK3: for.body:
// CHECK3-NEXT: [[TMP4:%.*]] = load i32, i32* [[T_VAR]], align 4
// CHECK3-NEXT: [[TMP5:%.*]] = load i32, i32* [[I]], align 4
// CHECK3-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP5]] to i64
// CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[VEC]], i64 0, i64 [[IDXPROM]]
// CHECK3-NEXT: store i32 [[TMP4]], i32* [[ARRAYIDX]], align 4
// CHECK3-NEXT: [[TMP6:%.*]] = load %struct.S*, %struct.S** [[_TMP1]], align 8
// CHECK3-NEXT: [[TMP7:%.*]] = load i32, i32* [[I]], align 4
// CHECK3-NEXT: [[IDXPROM2:%.*]] = sext i32 [[TMP7]] to i64
// CHECK3-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[S_ARR]], i64 0, i64 [[IDXPROM2]]
// CHECK3-NEXT: [[CALL:%.*]] = call noundef nonnull align 4 dereferenceable(12) %struct.S* @_ZN1SIiEaSERKS0_(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYIDX3]], %struct.S* noundef nonnull align 4 dereferenceable(12) [[TMP6]])
// CHECK3-NEXT: br label [[FOR_INC:%.*]]
// CHECK3: for.inc:
// CHECK3-NEXT: [[TMP8:%.*]] = load i32, i32* [[I]], align 4
// CHECK3-NEXT: [[INC:%.*]] = add nsw i32 [[TMP8]], 1
// CHECK3-NEXT: store i32 [[INC]], i32* [[I]], align 4
// CHECK3-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP14:![0-9]+]]
// CHECK3: for.end:
// CHECK3-NEXT: [[TMP9:%.*]] = load %struct.S*, %struct.S** [[VAR]], align 8
// CHECK3-NEXT: store %struct.S* [[TMP9]], %struct.S** [[_TMP4]], align 8
// CHECK3-NEXT: [[TMP10:%.*]] = load %struct.S*, %struct.S** [[_TMP4]], align 8
// CHECK3-NEXT: store %struct.S* [[TMP10]], %struct.S** [[_TMP5]], align 8
// CHECK3-NEXT: store i32 0, i32* [[I6]], align 4
// CHECK3-NEXT: br label [[FOR_COND7:%.*]]
// CHECK3: for.cond7:
// CHECK3-NEXT: [[TMP11:%.*]] = load i32, i32* [[I6]], align 4
// CHECK3-NEXT: [[CMP8:%.*]] = icmp slt i32 [[TMP11]], 2
// CHECK3-NEXT: br i1 [[CMP8]], label [[FOR_BODY9:%.*]], label [[FOR_END17:%.*]]
// CHECK3: for.body9:
// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[T_VAR]], align 4
// CHECK3-NEXT: [[TMP13:%.*]] = load i32, i32* [[I6]], align 4
// CHECK3-NEXT: [[IDXPROM10:%.*]] = sext i32 [[TMP13]] to i64
// CHECK3-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[VEC]], i64 0, i64 [[IDXPROM10]]
// CHECK3-NEXT: store i32 [[TMP12]], i32* [[ARRAYIDX11]], align 4
// CHECK3-NEXT: [[TMP14:%.*]] = load %struct.S*, %struct.S** [[_TMP5]], align 8
// CHECK3-NEXT: [[TMP15:%.*]] = load i32, i32* [[I6]], align 4
// CHECK3-NEXT: [[IDXPROM12:%.*]] = sext i32 [[TMP15]] to i64
// CHECK3-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[S_ARR]], i64 0, i64 [[IDXPROM12]]
// CHECK3-NEXT: [[CALL14:%.*]] = call noundef nonnull align 4 dereferenceable(12) %struct.S* @_ZN1SIiEaSERKS0_(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYIDX13]], %struct.S* noundef nonnull align 4 dereferenceable(12) [[TMP14]])
// CHECK3-NEXT: br label [[FOR_INC15:%.*]]
// CHECK3: for.inc15:
// CHECK3-NEXT: [[TMP16:%.*]] = load i32, i32* [[I6]], align 4
// CHECK3-NEXT: [[INC16:%.*]] = add nsw i32 [[TMP16]], 1
// CHECK3-NEXT: store i32 [[INC16]], i32* [[I6]], align 4
// CHECK3-NEXT: br label [[FOR_COND7]], !llvm.loop [[LOOP15:![0-9]+]]
// CHECK3: for.end17:
// CHECK3-NEXT: [[TMP17:%.*]] = load %struct.S*, %struct.S** [[VAR]], align 8
// CHECK3-NEXT: store %struct.S* [[TMP17]], %struct.S** [[_TMP18]], align 8
// CHECK3-NEXT: [[TMP18:%.*]] = load %struct.S*, %struct.S** [[_TMP18]], align 8
// CHECK3-NEXT: store %struct.S* [[TMP18]], %struct.S** [[_TMP19]], align 8
// CHECK3-NEXT: store i32 0, i32* [[I20]], align 4
// CHECK3-NEXT: br label [[FOR_COND21:%.*]]
// CHECK3: for.cond21:
// CHECK3-NEXT: [[TMP19:%.*]] = load i32, i32* [[I20]], align 4
// CHECK3-NEXT: [[CMP22:%.*]] = icmp slt i32 [[TMP19]], 2
// CHECK3-NEXT: br i1 [[CMP22]], label [[FOR_BODY23:%.*]], label [[FOR_END31:%.*]]
// CHECK3: for.body23:
// CHECK3-NEXT: [[TMP20:%.*]] = load i32, i32* [[T_VAR]], align 4
// CHECK3-NEXT: [[TMP21:%.*]] = load i32, i32* [[I20]], align 4
// CHECK3-NEXT: [[IDXPROM24:%.*]] = sext i32 [[TMP21]] to i64
// CHECK3-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[VEC]], i64 0, i64 [[IDXPROM24]]
// CHECK3-NEXT: store i32 [[TMP20]], i32* [[ARRAYIDX25]], align 4
// CHECK3-NEXT: [[TMP22:%.*]] = load %struct.S*, %struct.S** [[_TMP19]], align 8
// CHECK3-NEXT: [[TMP23:%.*]] = load i32, i32* [[I20]], align 4
// CHECK3-NEXT: [[IDXPROM26:%.*]] = sext i32 [[TMP23]] to i64
// CHECK3-NEXT: [[ARRAYIDX27:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[S_ARR]], i64 0, i64 [[IDXPROM26]]
// CHECK3-NEXT: [[CALL28:%.*]] = call noundef nonnull align 4 dereferenceable(12) %struct.S* @_ZN1SIiEaSERKS0_(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYIDX27]], %struct.S* noundef nonnull align 4 dereferenceable(12) [[TMP22]])
// CHECK3-NEXT: br label [[FOR_INC29:%.*]]
// CHECK3: for.inc29:
// CHECK3-NEXT: [[TMP24:%.*]] = load i32, i32* [[I20]], align 4
// CHECK3-NEXT: [[INC30:%.*]] = add nsw i32 [[TMP24]], 1
// CHECK3-NEXT: store i32 [[INC30]], i32* [[I20]], align 4
// CHECK3-NEXT: br label [[FOR_COND21]], !llvm.loop [[LOOP16:![0-9]+]]
// CHECK3: for.end31:
// CHECK3-NEXT: store i32 0, i32* [[RETVAL]], align 4
// CHECK3-NEXT: [[ARRAY_BEGIN32:%.*]] = getelementptr inbounds [42 x %struct.S], [42 x %struct.S]* [[ARR]], i32 0, i32 0
// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAY_BEGIN32]], i64 42
// CHECK3-NEXT: br label [[ARRAYDESTROY_BODY:%.*]]
// CHECK3: arraydestroy.body:
// CHECK3-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi %struct.S* [ [[TMP25]], [[FOR_END31]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ]
// CHECK3-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAYDESTROY_ELEMENTPAST]], i64 -1
// CHECK3-NEXT: call void @_ZN1SIiED1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR7]]
// CHECK3-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq %struct.S* [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN32]]
// CHECK3-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE33:%.*]], label [[ARRAYDESTROY_BODY]]
// CHECK3: arraydestroy.done33:
// CHECK3-NEXT: call void @_ZN1SIiED1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[VAR1]]) #[[ATTR7]]
// CHECK3-NEXT: [[ARRAY_BEGIN34:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[S_ARR]], i32 0, i32 0
// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAY_BEGIN34]], i64 2
// CHECK3-NEXT: br label [[ARRAYDESTROY_BODY35:%.*]]
// CHECK3: arraydestroy.body35:
// CHECK3-NEXT: [[ARRAYDESTROY_ELEMENTPAST36:%.*]] = phi %struct.S* [ [[TMP26]], [[ARRAYDESTROY_DONE33]] ], [ [[ARRAYDESTROY_ELEMENT37:%.*]], [[ARRAYDESTROY_BODY35]] ]
// CHECK3-NEXT: [[ARRAYDESTROY_ELEMENT37]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[ARRAYDESTROY_ELEMENTPAST36]], i64 -1
// CHECK3-NEXT: call void @_ZN1SIiED1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[ARRAYDESTROY_ELEMENT37]]) #[[ATTR7]]
// CHECK3-NEXT: [[ARRAYDESTROY_DONE38:%.*]] = icmp eq %struct.S* [[ARRAYDESTROY_ELEMENT37]], [[ARRAY_BEGIN34]]
// CHECK3-NEXT: br i1 [[ARRAYDESTROY_DONE38]], label [[ARRAYDESTROY_DONE39:%.*]], label [[ARRAYDESTROY_BODY35]]
// CHECK3: arraydestroy.done39:
// CHECK3-NEXT: call void @_ZN1SIiED1Ev(%struct.S* noundef nonnull align 4 dereferenceable(12) [[TEST]]) #[[ATTR7]]
// CHECK3-NEXT: [[TMP27:%.*]] = load i32, i32* [[RETVAL]], align 4
// CHECK3-NEXT: ret i32 [[TMP27]]
//
//
// CHECK3-LABEL: define {{[^@]+}}@_ZN1SIfED1Ev
// CHECK3-SAME: (%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK3-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
// CHECK3-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
// CHECK3-NEXT: call void @_ZN1SIfED2Ev(%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS1]]) #[[ATTR7]]
// CHECK3-NEXT: ret void
//
//
// CHECK3-LABEL: define {{[^@]+}}@_ZN1SIiEC2Ev
// CHECK3-SAME: (%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
// CHECK3-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
// CHECK3-NEXT: [[TMP0:%.*]] = bitcast %struct.S* [[THIS1]] to %struct.BaseS*
// CHECK3-NEXT: [[TMP1:%.*]] = bitcast %struct.S* [[THIS1]] to i8*
// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 4
// CHECK3-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to %struct.BaseS1*
// CHECK3-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[THIS1]], i32 0, i32 2
// CHECK3-NEXT: [[TMP4:%.*]] = load volatile double, double* @g, align 8
// CHECK3-NEXT: [[CONV:%.*]] = fptosi double [[TMP4]] to i32
// CHECK3-NEXT: store i32 [[CONV]], i32* [[F]], align 4
// CHECK3-NEXT: ret void
//
//
// CHECK3-LABEL: define {{[^@]+}}@_ZN1SIiED2Ev
// CHECK3-SAME: (%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
// CHECK3-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
// CHECK3-NEXT: ret void
//
//
// CHECK3-LABEL: define {{[^@]+}}@_ZN1SIfEC2Ev
// CHECK3-SAME: (%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK3-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
// CHECK3-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
// CHECK3-NEXT: [[TMP0:%.*]] = bitcast %struct.S.0* [[THIS1]] to %struct.BaseS*
// CHECK3-NEXT: [[TMP1:%.*]] = bitcast %struct.S.0* [[THIS1]] to i8*
// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 4
// CHECK3-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to %struct.BaseS1*
// CHECK3-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S_0:%.*]], %struct.S.0* [[THIS1]], i32 0, i32 2
// CHECK3-NEXT: [[TMP4:%.*]] = load volatile double, double* @g, align 8
// CHECK3-NEXT: [[CONV:%.*]] = fptrunc double [[TMP4]] to float
// CHECK3-NEXT: store float [[CONV]], float* [[F]], align 4
// CHECK3-NEXT: ret void
//
//
// CHECK3-LABEL: define {{[^@]+}}@_ZN1SIfED2Ev
// CHECK3-SAME: (%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK3-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
// CHECK3-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
// CHECK3-NEXT: ret void
//
//
// CHECK3-LABEL: define {{[^@]+}}@_ZN1SIfEC2Ef
// CHECK3-SAME: (%struct.S.0* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]], float noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
// CHECK3-NEXT: [[A_ADDR:%.*]] = alloca float, align 4
// CHECK3-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
// CHECK3-NEXT: store float [[A]], float* [[A_ADDR]], align 4
// CHECK3-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
// CHECK3-NEXT: [[TMP0:%.*]] = bitcast %struct.S.0* [[THIS1]] to %struct.BaseS*
// CHECK3-NEXT: [[TMP1:%.*]] = bitcast %struct.S.0* [[THIS1]] to i8*
// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 4
// CHECK3-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to %struct.BaseS1*
// CHECK3-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S_0:%.*]], %struct.S.0* [[THIS1]], i32 0, i32 2
// CHECK3-NEXT: [[TMP4:%.*]] = load float, float* [[A_ADDR]], align 4
// CHECK3-NEXT: [[CONV:%.*]] = fpext float [[TMP4]] to double
// CHECK3-NEXT: [[TMP5:%.*]] = load volatile double, double* @g, align 8
// CHECK3-NEXT: [[ADD:%.*]] = fadd double [[CONV]], [[TMP5]]
// CHECK3-NEXT: [[CONV2:%.*]] = fptrunc double [[ADD]] to float
// CHECK3-NEXT: store float [[CONV2]], float* [[F]], align 4
// CHECK3-NEXT: ret void
//
//
// CHECK3-LABEL: define {{[^@]+}}@_ZN1SIiEC1Ei
// CHECK3-SAME: (%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
// CHECK3-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
// CHECK3-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4
// CHECK3-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
// CHECK3-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4
// CHECK3-NEXT: call void @_ZN1SIiEC2Ei(%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS1]], i32 noundef [[TMP0]])
// CHECK3-NEXT: ret void
//
//
// CHECK3-LABEL: define {{[^@]+}}@_ZN1SIiEC2Ei
// CHECK3-SAME: (%struct.S* noundef nonnull align 4 dereferenceable(12) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
// CHECK3-NEXT: entry:
// CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
// CHECK3-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
// CHECK3-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
// CHECK3-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4
// CHECK3-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
// CHECK3-NEXT: [[TMP0:%.*]] = bitcast %struct.S* [[THIS1]] to %struct.BaseS*
// CHECK3-NEXT: [[TMP1:%.*]] = bitcast %struct.S* [[THIS1]] to i8*
// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 4
// CHECK3-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to %struct.BaseS1*
// CHECK3-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[THIS1]], i32 0, i32 2
// CHECK3-NEXT: [[TMP4:%.*]] = load i32, i32* [[A_ADDR]], align 4
// CHECK3-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP4]] to double
// CHECK3-NEXT: [[TMP5:%.*]] = load volatile double, double* @g, align 8
// CHECK3-NEXT: [[ADD:%.*]] = fadd double [[CONV]], [[TMP5]]
// CHECK3-NEXT: [[CONV2:%.*]] = fptosi double [[ADD]] to i32
// CHECK3-NEXT: store i32 [[CONV2]], i32* [[F]], align 4
// CHECK3-NEXT: ret void
//