The original change was reverted because it was discovered that clang mishandles thunks, and they receive wrong attributes for their this/return types - the ones for the function they will call, not the ones they have. While i have tried to fix this in https://reviews.llvm.org/D100388 that patch has been up and stuck for a month now, with little signs of progress. So while it will be good to solve this for real, for now we can simply avoid introducing the bug, by not annotating this/return for thunks. This reverts commit 6270b3a1eafaba4279e021418c5a2c5a35abc002, relanding 0aa0458f1429372038ca6a4edc7e94c96cd9a753.
1373 lines
83 KiB
C++
1373 lines
83 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 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1
|
|
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
|
|
// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK2
|
|
// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK3
|
|
// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK4
|
|
|
|
// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK5
|
|
// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
|
|
// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK6
|
|
// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK7
|
|
// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK8
|
|
// expected-no-diagnostics
|
|
#ifndef HEADER
|
|
#define HEADER
|
|
|
|
template <class T>
|
|
struct S {
|
|
T f;
|
|
S(T a) : f(a) {}
|
|
S() : f() {}
|
|
S<T> &operator=(const S<T> &);
|
|
operator T() { return T(); }
|
|
~S() {}
|
|
};
|
|
|
|
volatile int g = 1212;
|
|
float f;
|
|
char cnt;
|
|
|
|
template <typename T>
|
|
T tmain() {
|
|
S<T> test;
|
|
T *pvar = &test.f;
|
|
T lvar = T();
|
|
#pragma omp parallel for linear(pvar, lvar)
|
|
for (int i = 0; i < 2; ++i) {
|
|
++pvar, ++lvar;
|
|
}
|
|
return T();
|
|
}
|
|
|
|
int main() {
|
|
#ifdef LAMBDA
|
|
[&]() {
|
|
#pragma omp parallel for linear(g:5)
|
|
for (int i = 0; i < 2; ++i) {
|
|
g += 5;
|
|
[&]() {
|
|
g = 2;
|
|
}();
|
|
}
|
|
}();
|
|
return 0;
|
|
#elif defined(BLOCKS)
|
|
^{
|
|
#pragma omp parallel for linear(g:5)
|
|
for (int i = 0; i < 2; ++i) {
|
|
g += 5;
|
|
g = 1;
|
|
^{
|
|
g = 2;
|
|
}();
|
|
}
|
|
}();
|
|
return 0;
|
|
#else
|
|
S<float> test;
|
|
float *pvar = &test.f;
|
|
long long lvar = 0;
|
|
#pragma omp parallel for linear(pvar, lvar : 3)
|
|
for (int i = 0; i < 2; ++i) {
|
|
pvar += 3, lvar += 3;
|
|
}
|
|
return tmain<int>();
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check for default initialization.
|
|
|
|
|
|
|
|
// Check for default initialization.
|
|
#endif
|
|
|
|
// CHECK1-LABEL: define {{[^@]+}}@main
|
|
// CHECK1-SAME: () #[[ATTR0:[0-9]+]] {
|
|
// CHECK1-NEXT: entry:
|
|
// CHECK1-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// CHECK1-NEXT: [[TEST:%.*]] = alloca [[STRUCT_S:%.*]], align 4
|
|
// CHECK1-NEXT: [[PVAR:%.*]] = alloca float*, align 8
|
|
// CHECK1-NEXT: [[LVAR:%.*]] = alloca i64, align 8
|
|
// CHECK1-NEXT: store i32 0, i32* [[RETVAL]], align 4
|
|
// CHECK1-NEXT: call void @_ZN1SIfEC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TEST]])
|
|
// CHECK1-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TEST]], i32 0, i32 0
|
|
// CHECK1-NEXT: store float* [[F]], float** [[PVAR]], align 8
|
|
// CHECK1-NEXT: store i64 0, i64* [[LVAR]], align 8
|
|
// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float**, i64*)* @.omp_outlined. to void (i32*, i32*, ...)*), float** [[PVAR]], i64* [[LVAR]])
|
|
// CHECK1-NEXT: [[CALL:%.*]] = call i32 @_Z5tmainIiET_v()
|
|
// CHECK1-NEXT: store i32 [[CALL]], i32* [[RETVAL]], align 4
|
|
// CHECK1-NEXT: call void @_ZN1SIfED1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TEST]]) #[[ATTR4:[0-9]+]]
|
|
// CHECK1-NEXT: [[TMP0:%.*]] = load i32, i32* [[RETVAL]], align 4
|
|
// CHECK1-NEXT: ret i32 [[TMP0]]
|
|
//
|
|
//
|
|
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIfEC1Ev
|
|
// CHECK1-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[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 @_ZN1SIfEC2Ev(%struct.S* nonnull align 4 dereferenceable(4) [[THIS1]])
|
|
// CHECK1-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.
|
|
// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], float** nonnull align 8 dereferenceable(8) [[PVAR:%.*]], i64* nonnull align 8 dereferenceable(8) [[LVAR:%.*]]) #[[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: [[PVAR_ADDR:%.*]] = alloca float**, align 8
|
|
// CHECK1-NEXT: [[LVAR_ADDR:%.*]] = alloca i64*, align 8
|
|
// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
|
|
// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4
|
|
// CHECK1-NEXT: [[DOTLINEAR_START:%.*]] = alloca float*, align 8
|
|
// CHECK1-NEXT: [[DOTLINEAR_START1:%.*]] = alloca i64, align 8
|
|
// 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: [[I:%.*]] = alloca i32, align 4
|
|
// CHECK1-NEXT: [[PVAR2:%.*]] = alloca float*, align 8
|
|
// CHECK1-NEXT: [[LVAR3:%.*]] = alloca i64, 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** [[PVAR]], float*** [[PVAR_ADDR]], align 8
|
|
// CHECK1-NEXT: store i64* [[LVAR]], i64** [[LVAR_ADDR]], align 8
|
|
// CHECK1-NEXT: [[TMP0:%.*]] = load float**, float*** [[PVAR_ADDR]], align 8
|
|
// CHECK1-NEXT: [[TMP1:%.*]] = load i64*, i64** [[LVAR_ADDR]], align 8
|
|
// CHECK1-NEXT: [[TMP2:%.*]] = load float*, float** [[TMP0]], align 8
|
|
// CHECK1-NEXT: store float* [[TMP2]], float** [[DOTLINEAR_START]], align 8
|
|
// CHECK1-NEXT: [[TMP3:%.*]] = load i64, i64* [[TMP1]], align 8
|
|
// CHECK1-NEXT: store i64 [[TMP3]], i64* [[DOTLINEAR_START1]], 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: [[TMP4:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
|
|
// CHECK1-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP4]], align 4
|
|
// CHECK1-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 [[TMP5]])
|
|
// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 [[TMP5]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
|
|
// CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP6]], 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: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK1-NEXT: br label [[COND_END]]
|
|
// CHECK1: cond.end:
|
|
// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 1, [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ]
|
|
// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
|
|
// CHECK1-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
|
|
// CHECK1-NEXT: store i32 [[TMP8]], i32* [[DOTOMP_IV]], align 4
|
|
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
|
|
// CHECK1: omp.inner.for.cond:
|
|
// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK1-NEXT: [[CMP4:%.*]] = icmp sle i32 [[TMP9]], [[TMP10]]
|
|
// CHECK1-NEXT: br i1 [[CMP4]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
|
|
// CHECK1: omp.inner.for.body:
|
|
// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP11]], 1
|
|
// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
|
|
// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4
|
|
// CHECK1-NEXT: [[TMP12:%.*]] = load float*, float** [[DOTLINEAR_START]], align 8
|
|
// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK1-NEXT: [[MUL5:%.*]] = mul nsw i32 [[TMP13]], 3
|
|
// CHECK1-NEXT: [[IDX_EXT:%.*]] = sext i32 [[MUL5]] to i64
|
|
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds float, float* [[TMP12]], i64 [[IDX_EXT]]
|
|
// CHECK1-NEXT: store float* [[ADD_PTR]], float** [[PVAR2]], align 8
|
|
// CHECK1-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTLINEAR_START1]], align 8
|
|
// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK1-NEXT: [[MUL6:%.*]] = mul nsw i32 [[TMP15]], 3
|
|
// CHECK1-NEXT: [[CONV:%.*]] = sext i32 [[MUL6]] to i64
|
|
// CHECK1-NEXT: [[ADD7:%.*]] = add nsw i64 [[TMP14]], [[CONV]]
|
|
// CHECK1-NEXT: store i64 [[ADD7]], i64* [[LVAR3]], align 8
|
|
// CHECK1-NEXT: [[TMP16:%.*]] = load float*, float** [[PVAR2]], align 8
|
|
// CHECK1-NEXT: [[ADD_PTR8:%.*]] = getelementptr inbounds float, float* [[TMP16]], i64 3
|
|
// CHECK1-NEXT: store float* [[ADD_PTR8]], float** [[PVAR2]], align 8
|
|
// CHECK1-NEXT: [[TMP17:%.*]] = load i64, i64* [[LVAR3]], align 8
|
|
// CHECK1-NEXT: [[ADD9:%.*]] = add nsw i64 [[TMP17]], 3
|
|
// CHECK1-NEXT: store i64 [[ADD9]], i64* [[LVAR3]], align 8
|
|
// 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: [[ADD10:%.*]] = add nsw i32 [[TMP18]], 1
|
|
// CHECK1-NEXT: store i32 [[ADD10]], 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 [[TMP5]])
|
|
// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4
|
|
// CHECK1-NEXT: [[TMP20:%.*]] = icmp ne i32 [[TMP19]], 0
|
|
// CHECK1-NEXT: br i1 [[TMP20]], label [[DOTOMP_LINEAR_PU:%.*]], label [[DOTOMP_LINEAR_PU_DONE:%.*]]
|
|
// CHECK1: .omp.linear.pu:
|
|
// CHECK1-NEXT: [[TMP21:%.*]] = load float*, float** [[DOTLINEAR_START]], align 8
|
|
// CHECK1-NEXT: [[ADD_PTR11:%.*]] = getelementptr inbounds float, float* [[TMP21]], i64 6
|
|
// CHECK1-NEXT: store float* [[ADD_PTR11]], float** [[TMP0]], align 8
|
|
// CHECK1-NEXT: [[TMP22:%.*]] = load i64, i64* [[DOTLINEAR_START1]], align 8
|
|
// CHECK1-NEXT: [[ADD12:%.*]] = add nsw i64 [[TMP22]], 6
|
|
// CHECK1-NEXT: store i64 [[ADD12]], i64* [[TMP1]], align 8
|
|
// CHECK1-NEXT: br label [[DOTOMP_LINEAR_PU_DONE]]
|
|
// CHECK1: .omp.linear.pu.done:
|
|
// CHECK1-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK1-LABEL: define {{[^@]+}}@_Z5tmainIiET_v
|
|
// CHECK1-SAME: () #[[ATTR5:[0-9]+]] {
|
|
// CHECK1-NEXT: entry:
|
|
// CHECK1-NEXT: [[TEST:%.*]] = alloca [[STRUCT_S_0:%.*]], align 4
|
|
// CHECK1-NEXT: [[PVAR:%.*]] = alloca i32*, align 8
|
|
// CHECK1-NEXT: [[LVAR:%.*]] = alloca i32, align 4
|
|
// CHECK1-NEXT: call void @_ZN1SIiEC1Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[TEST]])
|
|
// CHECK1-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[TEST]], i32 0, i32 0
|
|
// CHECK1-NEXT: store i32* [[F]], i32** [[PVAR]], align 8
|
|
// CHECK1-NEXT: store i32 0, i32* [[LVAR]], align 4
|
|
// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32**, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*), i32** [[PVAR]], i32* [[LVAR]])
|
|
// CHECK1-NEXT: call void @_ZN1SIiED1Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[TEST]]) #[[ATTR4]]
|
|
// CHECK1-NEXT: ret i32 0
|
|
//
|
|
//
|
|
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIfED1Ev
|
|
// CHECK1-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[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 @_ZN1SIfED2Ev(%struct.S* nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR4]]
|
|
// CHECK1-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIfEC2Ev
|
|
// CHECK1-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[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: [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[THIS1]], i32 0, i32 0
|
|
// CHECK1-NEXT: store float 0.000000e+00, float* [[F]], align 4
|
|
// CHECK1-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiEC1Ev
|
|
// CHECK1-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[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 @_ZN1SIiEC2Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS1]])
|
|
// CHECK1-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..1
|
|
// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32** nonnull align 8 dereferenceable(8) [[PVAR:%.*]], i32* nonnull align 4 dereferenceable(4) [[LVAR:%.*]]) #[[ATTR2]] {
|
|
// CHECK1-NEXT: entry:
|
|
// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK1-NEXT: [[PVAR_ADDR:%.*]] = alloca i32**, align 8
|
|
// CHECK1-NEXT: [[LVAR_ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
|
|
// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4
|
|
// CHECK1-NEXT: [[DOTLINEAR_START:%.*]] = alloca i32*, align 8
|
|
// CHECK1-NEXT: [[DOTLINEAR_START1:%.*]] = 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: [[I:%.*]] = alloca i32, align 4
|
|
// CHECK1-NEXT: [[PVAR2:%.*]] = alloca i32*, align 8
|
|
// CHECK1-NEXT: [[LVAR3:%.*]] = alloca i32, 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 i32** [[PVAR]], i32*** [[PVAR_ADDR]], align 8
|
|
// CHECK1-NEXT: store i32* [[LVAR]], i32** [[LVAR_ADDR]], align 8
|
|
// CHECK1-NEXT: [[TMP0:%.*]] = load i32**, i32*** [[PVAR_ADDR]], align 8
|
|
// CHECK1-NEXT: [[TMP1:%.*]] = load i32*, i32** [[LVAR_ADDR]], align 8
|
|
// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[TMP0]], align 8
|
|
// CHECK1-NEXT: store i32* [[TMP2]], i32** [[DOTLINEAR_START]], align 8
|
|
// CHECK1-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP1]], align 4
|
|
// CHECK1-NEXT: store i32 [[TMP3]], i32* [[DOTLINEAR_START1]], align 4
|
|
// 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: [[TMP4:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
|
|
// CHECK1-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP4]], align 4
|
|
// CHECK1-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB1]], i32 [[TMP5]])
|
|
// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP5]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
|
|
// CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP6]], 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: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK1-NEXT: br label [[COND_END]]
|
|
// CHECK1: cond.end:
|
|
// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 1, [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ]
|
|
// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
|
|
// CHECK1-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
|
|
// CHECK1-NEXT: store i32 [[TMP8]], i32* [[DOTOMP_IV]], align 4
|
|
// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
|
|
// CHECK1: omp.inner.for.cond:
|
|
// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK1-NEXT: [[CMP4:%.*]] = icmp sle i32 [[TMP9]], [[TMP10]]
|
|
// CHECK1-NEXT: br i1 [[CMP4]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
|
|
// CHECK1: omp.inner.for.body:
|
|
// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP11]], 1
|
|
// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
|
|
// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4
|
|
// CHECK1-NEXT: [[TMP12:%.*]] = load i32*, i32** [[DOTLINEAR_START]], align 8
|
|
// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK1-NEXT: [[MUL5:%.*]] = mul nsw i32 [[TMP13]], 1
|
|
// CHECK1-NEXT: [[IDX_EXT:%.*]] = sext i32 [[MUL5]] to i64
|
|
// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[TMP12]], i64 [[IDX_EXT]]
|
|
// CHECK1-NEXT: store i32* [[ADD_PTR]], i32** [[PVAR2]], align 8
|
|
// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTLINEAR_START1]], align 4
|
|
// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK1-NEXT: [[MUL6:%.*]] = mul nsw i32 [[TMP15]], 1
|
|
// CHECK1-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP14]], [[MUL6]]
|
|
// CHECK1-NEXT: store i32 [[ADD7]], i32* [[LVAR3]], align 4
|
|
// CHECK1-NEXT: [[TMP16:%.*]] = load i32*, i32** [[PVAR2]], align 8
|
|
// CHECK1-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, i32* [[TMP16]], i32 1
|
|
// CHECK1-NEXT: store i32* [[INCDEC_PTR]], i32** [[PVAR2]], align 8
|
|
// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[LVAR3]], align 4
|
|
// CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP17]], 1
|
|
// CHECK1-NEXT: store i32 [[INC]], i32* [[LVAR3]], 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: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK1-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP18]], 1
|
|
// CHECK1-NEXT: store i32 [[ADD8]], 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 [[TMP5]])
|
|
// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4
|
|
// CHECK1-NEXT: [[TMP20:%.*]] = icmp ne i32 [[TMP19]], 0
|
|
// CHECK1-NEXT: br i1 [[TMP20]], label [[DOTOMP_LINEAR_PU:%.*]], label [[DOTOMP_LINEAR_PU_DONE:%.*]]
|
|
// CHECK1: .omp.linear.pu:
|
|
// CHECK1-NEXT: [[TMP21:%.*]] = load i32*, i32** [[DOTLINEAR_START]], align 8
|
|
// CHECK1-NEXT: [[ADD_PTR9:%.*]] = getelementptr inbounds i32, i32* [[TMP21]], i64 2
|
|
// CHECK1-NEXT: store i32* [[ADD_PTR9]], i32** [[TMP0]], align 8
|
|
// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTLINEAR_START1]], align 4
|
|
// CHECK1-NEXT: [[ADD10:%.*]] = add nsw i32 [[TMP22]], 2
|
|
// CHECK1-NEXT: store i32 [[ADD10]], i32* [[TMP1]], align 4
|
|
// CHECK1-NEXT: br label [[DOTOMP_LINEAR_PU_DONE]]
|
|
// CHECK1: .omp.linear.pu.done:
|
|
// CHECK1-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiED1Ev
|
|
// CHECK1-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[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 @_ZN1SIiED2Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR4]]
|
|
// CHECK1-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiEC2Ev
|
|
// CHECK1-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[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: [[F:%.*]] = getelementptr inbounds [[STRUCT_S_0:%.*]], %struct.S.0* [[THIS1]], i32 0, i32 0
|
|
// CHECK1-NEXT: store i32 0, i32* [[F]], align 4
|
|
// CHECK1-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK1-LABEL: define {{[^@]+}}@_ZN1SIiED2Ev
|
|
// CHECK1-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[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 {{[^@]+}}@_ZN1SIfED2Ev
|
|
// CHECK1-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[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
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@main
|
|
// CHECK2-SAME: () #[[ATTR0:[0-9]+]] {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[TEST:%.*]] = alloca [[STRUCT_S:%.*]], align 4
|
|
// CHECK2-NEXT: [[PVAR:%.*]] = alloca float*, align 8
|
|
// CHECK2-NEXT: [[LVAR:%.*]] = alloca i64, align 8
|
|
// CHECK2-NEXT: store i32 0, i32* [[RETVAL]], align 4
|
|
// CHECK2-NEXT: call void @_ZN1SIfEC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TEST]])
|
|
// CHECK2-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TEST]], i32 0, i32 0
|
|
// CHECK2-NEXT: store float* [[F]], float** [[PVAR]], align 8
|
|
// CHECK2-NEXT: store i64 0, i64* [[LVAR]], align 8
|
|
// CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float**, i64*)* @.omp_outlined. to void (i32*, i32*, ...)*), float** [[PVAR]], i64* [[LVAR]])
|
|
// CHECK2-NEXT: [[CALL:%.*]] = call i32 @_Z5tmainIiET_v()
|
|
// CHECK2-NEXT: store i32 [[CALL]], i32* [[RETVAL]], align 4
|
|
// CHECK2-NEXT: call void @_ZN1SIfED1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TEST]]) #[[ATTR4:[0-9]+]]
|
|
// CHECK2-NEXT: [[TMP0:%.*]] = load i32, i32* [[RETVAL]], align 4
|
|
// CHECK2-NEXT: ret i32 [[TMP0]]
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@_ZN1SIfEC1Ev
|
|
// CHECK2-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] align 2 {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
|
|
// CHECK2-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: call void @_ZN1SIfEC2Ev(%struct.S* nonnull align 4 dereferenceable(4) [[THIS1]])
|
|
// CHECK2-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.
|
|
// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], float** nonnull align 8 dereferenceable(8) [[PVAR:%.*]], i64* nonnull align 8 dereferenceable(8) [[LVAR:%.*]]) #[[ATTR2:[0-9]+]] {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK2-NEXT: [[PVAR_ADDR:%.*]] = alloca float**, align 8
|
|
// CHECK2-NEXT: [[LVAR_ADDR:%.*]] = alloca i64*, align 8
|
|
// CHECK2-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[TMP:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[DOTLINEAR_START:%.*]] = alloca float*, align 8
|
|
// CHECK2-NEXT: [[DOTLINEAR_START1:%.*]] = alloca i64, align 8
|
|
// CHECK2-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[PVAR2:%.*]] = alloca float*, align 8
|
|
// CHECK2-NEXT: [[LVAR3:%.*]] = alloca i64, align 8
|
|
// CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
|
|
// CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
|
|
// CHECK2-NEXT: store float** [[PVAR]], float*** [[PVAR_ADDR]], align 8
|
|
// CHECK2-NEXT: store i64* [[LVAR]], i64** [[LVAR_ADDR]], align 8
|
|
// CHECK2-NEXT: [[TMP0:%.*]] = load float**, float*** [[PVAR_ADDR]], align 8
|
|
// CHECK2-NEXT: [[TMP1:%.*]] = load i64*, i64** [[LVAR_ADDR]], align 8
|
|
// CHECK2-NEXT: [[TMP2:%.*]] = load float*, float** [[TMP0]], align 8
|
|
// CHECK2-NEXT: store float* [[TMP2]], float** [[DOTLINEAR_START]], align 8
|
|
// CHECK2-NEXT: [[TMP3:%.*]] = load i64, i64* [[TMP1]], align 8
|
|
// CHECK2-NEXT: store i64 [[TMP3]], i64* [[DOTLINEAR_START1]], align 8
|
|
// CHECK2-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
|
|
// CHECK2-NEXT: store i32 1, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK2-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
|
|
// CHECK2-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
|
|
// CHECK2-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
|
|
// CHECK2-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP4]], align 4
|
|
// CHECK2-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 [[TMP5]])
|
|
// CHECK2-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 [[TMP5]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
|
|
// CHECK2-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK2-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP6]], 1
|
|
// CHECK2-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
|
|
// CHECK2: cond.true:
|
|
// CHECK2-NEXT: br label [[COND_END:%.*]]
|
|
// CHECK2: cond.false:
|
|
// CHECK2-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK2-NEXT: br label [[COND_END]]
|
|
// CHECK2: cond.end:
|
|
// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ 1, [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ]
|
|
// CHECK2-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
|
|
// CHECK2-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
|
|
// CHECK2-NEXT: store i32 [[TMP8]], i32* [[DOTOMP_IV]], align 4
|
|
// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
|
|
// CHECK2: omp.inner.for.cond:
|
|
// CHECK2-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK2-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK2-NEXT: [[CMP4:%.*]] = icmp sle i32 [[TMP9]], [[TMP10]]
|
|
// CHECK2-NEXT: br i1 [[CMP4]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
|
|
// CHECK2: omp.inner.for.body:
|
|
// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP11]], 1
|
|
// CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
|
|
// CHECK2-NEXT: store i32 [[ADD]], i32* [[I]], align 4
|
|
// CHECK2-NEXT: [[TMP12:%.*]] = load float*, float** [[DOTLINEAR_START]], align 8
|
|
// CHECK2-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK2-NEXT: [[MUL5:%.*]] = mul nsw i32 [[TMP13]], 3
|
|
// CHECK2-NEXT: [[IDX_EXT:%.*]] = sext i32 [[MUL5]] to i64
|
|
// CHECK2-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds float, float* [[TMP12]], i64 [[IDX_EXT]]
|
|
// CHECK2-NEXT: store float* [[ADD_PTR]], float** [[PVAR2]], align 8
|
|
// CHECK2-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTLINEAR_START1]], align 8
|
|
// CHECK2-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK2-NEXT: [[MUL6:%.*]] = mul nsw i32 [[TMP15]], 3
|
|
// CHECK2-NEXT: [[CONV:%.*]] = sext i32 [[MUL6]] to i64
|
|
// CHECK2-NEXT: [[ADD7:%.*]] = add nsw i64 [[TMP14]], [[CONV]]
|
|
// CHECK2-NEXT: store i64 [[ADD7]], i64* [[LVAR3]], align 8
|
|
// CHECK2-NEXT: [[TMP16:%.*]] = load float*, float** [[PVAR2]], align 8
|
|
// CHECK2-NEXT: [[ADD_PTR8:%.*]] = getelementptr inbounds float, float* [[TMP16]], i64 3
|
|
// CHECK2-NEXT: store float* [[ADD_PTR8]], float** [[PVAR2]], align 8
|
|
// CHECK2-NEXT: [[TMP17:%.*]] = load i64, i64* [[LVAR3]], align 8
|
|
// CHECK2-NEXT: [[ADD9:%.*]] = add nsw i64 [[TMP17]], 3
|
|
// CHECK2-NEXT: store i64 [[ADD9]], i64* [[LVAR3]], align 8
|
|
// CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
|
|
// CHECK2: omp.body.continue:
|
|
// CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
|
|
// CHECK2: omp.inner.for.inc:
|
|
// CHECK2-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK2-NEXT: [[ADD10:%.*]] = add nsw i32 [[TMP18]], 1
|
|
// CHECK2-NEXT: store i32 [[ADD10]], i32* [[DOTOMP_IV]], align 4
|
|
// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]]
|
|
// CHECK2: omp.inner.for.end:
|
|
// CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
|
|
// CHECK2: omp.loop.exit:
|
|
// CHECK2-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP5]])
|
|
// CHECK2-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4
|
|
// CHECK2-NEXT: [[TMP20:%.*]] = icmp ne i32 [[TMP19]], 0
|
|
// CHECK2-NEXT: br i1 [[TMP20]], label [[DOTOMP_LINEAR_PU:%.*]], label [[DOTOMP_LINEAR_PU_DONE:%.*]]
|
|
// CHECK2: .omp.linear.pu:
|
|
// CHECK2-NEXT: [[TMP21:%.*]] = load float*, float** [[DOTLINEAR_START]], align 8
|
|
// CHECK2-NEXT: [[ADD_PTR11:%.*]] = getelementptr inbounds float, float* [[TMP21]], i64 6
|
|
// CHECK2-NEXT: store float* [[ADD_PTR11]], float** [[TMP0]], align 8
|
|
// CHECK2-NEXT: [[TMP22:%.*]] = load i64, i64* [[DOTLINEAR_START1]], align 8
|
|
// CHECK2-NEXT: [[ADD12:%.*]] = add nsw i64 [[TMP22]], 6
|
|
// CHECK2-NEXT: store i64 [[ADD12]], i64* [[TMP1]], align 8
|
|
// CHECK2-NEXT: br label [[DOTOMP_LINEAR_PU_DONE]]
|
|
// CHECK2: .omp.linear.pu.done:
|
|
// CHECK2-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@_Z5tmainIiET_v
|
|
// CHECK2-SAME: () #[[ATTR5:[0-9]+]] {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: [[TEST:%.*]] = alloca [[STRUCT_S_0:%.*]], align 4
|
|
// CHECK2-NEXT: [[PVAR:%.*]] = alloca i32*, align 8
|
|
// CHECK2-NEXT: [[LVAR:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: call void @_ZN1SIiEC1Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[TEST]])
|
|
// CHECK2-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[TEST]], i32 0, i32 0
|
|
// CHECK2-NEXT: store i32* [[F]], i32** [[PVAR]], align 8
|
|
// CHECK2-NEXT: store i32 0, i32* [[LVAR]], align 4
|
|
// CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32**, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*), i32** [[PVAR]], i32* [[LVAR]])
|
|
// CHECK2-NEXT: call void @_ZN1SIiED1Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[TEST]]) #[[ATTR4]]
|
|
// CHECK2-NEXT: ret i32 0
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@_ZN1SIfED1Ev
|
|
// CHECK2-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
|
|
// CHECK2-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: call void @_ZN1SIfED2Ev(%struct.S* nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR4]]
|
|
// CHECK2-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@_ZN1SIfEC2Ev
|
|
// CHECK2-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
|
|
// CHECK2-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[THIS1]], i32 0, i32 0
|
|
// CHECK2-NEXT: store float 0.000000e+00, float* [[F]], align 4
|
|
// CHECK2-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@_ZN1SIiEC1Ev
|
|
// CHECK2-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
|
|
// CHECK2-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: call void @_ZN1SIiEC2Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS1]])
|
|
// CHECK2-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..1
|
|
// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32** nonnull align 8 dereferenceable(8) [[PVAR:%.*]], i32* nonnull align 4 dereferenceable(4) [[LVAR:%.*]]) #[[ATTR2]] {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK2-NEXT: [[PVAR_ADDR:%.*]] = alloca i32**, align 8
|
|
// CHECK2-NEXT: [[LVAR_ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK2-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[TMP:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[DOTLINEAR_START:%.*]] = alloca i32*, align 8
|
|
// CHECK2-NEXT: [[DOTLINEAR_START1:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[PVAR2:%.*]] = alloca i32*, align 8
|
|
// CHECK2-NEXT: [[LVAR3:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
|
|
// CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
|
|
// CHECK2-NEXT: store i32** [[PVAR]], i32*** [[PVAR_ADDR]], align 8
|
|
// CHECK2-NEXT: store i32* [[LVAR]], i32** [[LVAR_ADDR]], align 8
|
|
// CHECK2-NEXT: [[TMP0:%.*]] = load i32**, i32*** [[PVAR_ADDR]], align 8
|
|
// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[LVAR_ADDR]], align 8
|
|
// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[TMP0]], align 8
|
|
// CHECK2-NEXT: store i32* [[TMP2]], i32** [[DOTLINEAR_START]], align 8
|
|
// CHECK2-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP1]], align 4
|
|
// CHECK2-NEXT: store i32 [[TMP3]], i32* [[DOTLINEAR_START1]], align 4
|
|
// CHECK2-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
|
|
// CHECK2-NEXT: store i32 1, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK2-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
|
|
// CHECK2-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
|
|
// CHECK2-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
|
|
// CHECK2-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP4]], align 4
|
|
// CHECK2-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB1]], i32 [[TMP5]])
|
|
// CHECK2-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP5]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
|
|
// CHECK2-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK2-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP6]], 1
|
|
// CHECK2-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
|
|
// CHECK2: cond.true:
|
|
// CHECK2-NEXT: br label [[COND_END:%.*]]
|
|
// CHECK2: cond.false:
|
|
// CHECK2-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK2-NEXT: br label [[COND_END]]
|
|
// CHECK2: cond.end:
|
|
// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ 1, [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ]
|
|
// CHECK2-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
|
|
// CHECK2-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
|
|
// CHECK2-NEXT: store i32 [[TMP8]], i32* [[DOTOMP_IV]], align 4
|
|
// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
|
|
// CHECK2: omp.inner.for.cond:
|
|
// CHECK2-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK2-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK2-NEXT: [[CMP4:%.*]] = icmp sle i32 [[TMP9]], [[TMP10]]
|
|
// CHECK2-NEXT: br i1 [[CMP4]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
|
|
// CHECK2: omp.inner.for.body:
|
|
// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP11]], 1
|
|
// CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
|
|
// CHECK2-NEXT: store i32 [[ADD]], i32* [[I]], align 4
|
|
// CHECK2-NEXT: [[TMP12:%.*]] = load i32*, i32** [[DOTLINEAR_START]], align 8
|
|
// CHECK2-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK2-NEXT: [[MUL5:%.*]] = mul nsw i32 [[TMP13]], 1
|
|
// CHECK2-NEXT: [[IDX_EXT:%.*]] = sext i32 [[MUL5]] to i64
|
|
// CHECK2-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[TMP12]], i64 [[IDX_EXT]]
|
|
// CHECK2-NEXT: store i32* [[ADD_PTR]], i32** [[PVAR2]], align 8
|
|
// CHECK2-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTLINEAR_START1]], align 4
|
|
// CHECK2-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK2-NEXT: [[MUL6:%.*]] = mul nsw i32 [[TMP15]], 1
|
|
// CHECK2-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP14]], [[MUL6]]
|
|
// CHECK2-NEXT: store i32 [[ADD7]], i32* [[LVAR3]], align 4
|
|
// CHECK2-NEXT: [[TMP16:%.*]] = load i32*, i32** [[PVAR2]], align 8
|
|
// CHECK2-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, i32* [[TMP16]], i32 1
|
|
// CHECK2-NEXT: store i32* [[INCDEC_PTR]], i32** [[PVAR2]], align 8
|
|
// CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[LVAR3]], align 4
|
|
// CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP17]], 1
|
|
// CHECK2-NEXT: store i32 [[INC]], i32* [[LVAR3]], align 4
|
|
// CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
|
|
// CHECK2: omp.body.continue:
|
|
// CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
|
|
// CHECK2: omp.inner.for.inc:
|
|
// CHECK2-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK2-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP18]], 1
|
|
// CHECK2-NEXT: store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4
|
|
// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]]
|
|
// CHECK2: omp.inner.for.end:
|
|
// CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
|
|
// CHECK2: omp.loop.exit:
|
|
// CHECK2-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP5]])
|
|
// CHECK2-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4
|
|
// CHECK2-NEXT: [[TMP20:%.*]] = icmp ne i32 [[TMP19]], 0
|
|
// CHECK2-NEXT: br i1 [[TMP20]], label [[DOTOMP_LINEAR_PU:%.*]], label [[DOTOMP_LINEAR_PU_DONE:%.*]]
|
|
// CHECK2: .omp.linear.pu:
|
|
// CHECK2-NEXT: [[TMP21:%.*]] = load i32*, i32** [[DOTLINEAR_START]], align 8
|
|
// CHECK2-NEXT: [[ADD_PTR9:%.*]] = getelementptr inbounds i32, i32* [[TMP21]], i64 2
|
|
// CHECK2-NEXT: store i32* [[ADD_PTR9]], i32** [[TMP0]], align 8
|
|
// CHECK2-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTLINEAR_START1]], align 4
|
|
// CHECK2-NEXT: [[ADD10:%.*]] = add nsw i32 [[TMP22]], 2
|
|
// CHECK2-NEXT: store i32 [[ADD10]], i32* [[TMP1]], align 4
|
|
// CHECK2-NEXT: br label [[DOTOMP_LINEAR_PU_DONE]]
|
|
// CHECK2: .omp.linear.pu.done:
|
|
// CHECK2-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@_ZN1SIiED1Ev
|
|
// CHECK2-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
|
|
// CHECK2-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: call void @_ZN1SIiED2Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR4]]
|
|
// CHECK2-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@_ZN1SIiEC2Ev
|
|
// CHECK2-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
|
|
// CHECK2-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S_0:%.*]], %struct.S.0* [[THIS1]], i32 0, i32 0
|
|
// CHECK2-NEXT: store i32 0, i32* [[F]], align 4
|
|
// CHECK2-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@_ZN1SIiED2Ev
|
|
// CHECK2-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
|
|
// CHECK2-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@_ZN1SIfED2Ev
|
|
// CHECK2-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
|
|
// CHECK2-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK2-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK3-LABEL: define {{[^@]+}}@main
|
|
// CHECK3-SAME: () #[[ATTR0:[0-9]+]] {
|
|
// CHECK3-NEXT: entry:
|
|
// CHECK3-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// CHECK3-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON:%.*]], align 1
|
|
// CHECK3-NEXT: store i32 0, i32* [[RETVAL]], align 4
|
|
// CHECK3-NEXT: call void @"_ZZ4mainENK3$_0clEv"(%class.anon* nonnull align 1 dereferenceable(1) [[REF_TMP]])
|
|
// CHECK3-NEXT: ret i32 0
|
|
//
|
|
//
|
|
// CHECK3-LABEL: define {{[^@]+}}@.omp_outlined.
|
|
// CHECK3-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[G:%.*]]) #[[ATTR2:[0-9]+]] {
|
|
// CHECK3-NEXT: entry:
|
|
// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK3-NEXT: [[G_ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
|
|
// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4
|
|
// CHECK3-NEXT: [[DOTLINEAR_START:%.*]] = alloca i32, align 4
|
|
// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
|
|
// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
|
|
// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
|
|
// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
|
|
// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4
|
|
// CHECK3-NEXT: [[G1:%.*]] = alloca i32, align 4
|
|
// CHECK3-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON_0:%.*]], align 8
|
|
// CHECK3-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
|
|
// CHECK3-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
|
|
// CHECK3-NEXT: store i32* [[G]], i32** [[G_ADDR]], align 8
|
|
// CHECK3-NEXT: [[TMP0:%.*]] = load i32*, i32** [[G_ADDR]], align 8
|
|
// CHECK3-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
|
|
// CHECK3-NEXT: store i32 [[TMP1]], i32* [[DOTLINEAR_START]], align 4
|
|
// CHECK3-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
|
|
// CHECK3-NEXT: store i32 1, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK3-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
|
|
// CHECK3-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
|
|
// CHECK3-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
|
|
// CHECK3-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
|
|
// CHECK3-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 [[TMP3]])
|
|
// CHECK3-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
|
|
// CHECK3-NEXT: [[TMP4:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 1
|
|
// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
|
|
// CHECK3: cond.true:
|
|
// CHECK3-NEXT: br label [[COND_END:%.*]]
|
|
// CHECK3: cond.false:
|
|
// CHECK3-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK3-NEXT: br label [[COND_END]]
|
|
// CHECK3: cond.end:
|
|
// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 1, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ]
|
|
// CHECK3-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
|
|
// CHECK3-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
|
|
// CHECK3-NEXT: store i32 [[TMP6]], i32* [[DOTOMP_IV]], align 4
|
|
// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
|
|
// CHECK3: omp.inner.for.cond:
|
|
// CHECK3-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK3-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]]
|
|
// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
|
|
// CHECK3: omp.inner.for.body:
|
|
// CHECK3-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1
|
|
// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
|
|
// CHECK3-NEXT: store i32 [[ADD]], i32* [[I]], align 4
|
|
// CHECK3-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4
|
|
// CHECK3-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK3-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP11]], 5
|
|
// CHECK3-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], [[MUL3]]
|
|
// CHECK3-NEXT: store i32 [[ADD4]], i32* [[G1]], align 4
|
|
// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[G1]], align 4
|
|
// CHECK3-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP12]], 5
|
|
// CHECK3-NEXT: store i32 [[ADD5]], i32* [[G1]], align 4
|
|
// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[REF_TMP]], i32 0, i32 0
|
|
// CHECK3-NEXT: store i32* [[G1]], i32** [[TMP13]], align 8
|
|
// CHECK3-NEXT: call void @"_ZZZ4mainENK3$_0clEvENKUlvE_clEv"(%class.anon.0* nonnull align 8 dereferenceable(8) [[REF_TMP]])
|
|
// 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: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK3-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP14]], 1
|
|
// CHECK3-NEXT: store i32 [[ADD6]], i32* [[DOTOMP_IV]], align 4
|
|
// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]]
|
|
// CHECK3: omp.inner.for.end:
|
|
// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
|
|
// CHECK3: omp.loop.exit:
|
|
// CHECK3-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP3]])
|
|
// CHECK3-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4
|
|
// CHECK3-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0
|
|
// CHECK3-NEXT: br i1 [[TMP16]], label [[DOTOMP_LINEAR_PU:%.*]], label [[DOTOMP_LINEAR_PU_DONE:%.*]]
|
|
// CHECK3: .omp.linear.pu:
|
|
// CHECK3-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4
|
|
// CHECK3-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP17]], 10
|
|
// CHECK3-NEXT: store i32 [[ADD7]], i32* [[TMP0]], align 4
|
|
// CHECK3-NEXT: br label [[DOTOMP_LINEAR_PU_DONE]]
|
|
// CHECK3: .omp.linear.pu.done:
|
|
// CHECK3-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK4-LABEL: define {{[^@]+}}@main
|
|
// CHECK4-SAME: () #[[ATTR1:[0-9]+]] {
|
|
// CHECK4-NEXT: entry:
|
|
// CHECK4-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// CHECK4-NEXT: store i32 0, i32* [[RETVAL]], align 4
|
|
// CHECK4-NEXT: [[TMP0:%.*]] = load i8*, i8** getelementptr inbounds ([[STRUCT___BLOCK_LITERAL_GENERIC:%.*]], %struct.__block_literal_generic* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor* }* @__block_literal_global to %struct.__block_literal_generic*), i32 0, i32 3), align 8
|
|
// CHECK4-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to void (i8*)*
|
|
// CHECK4-NEXT: call void [[TMP1]](i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor* }* @__block_literal_global to i8*))
|
|
// CHECK4-NEXT: ret i32 0
|
|
//
|
|
//
|
|
// CHECK4-LABEL: define {{[^@]+}}@__main_block_invoke
|
|
// CHECK4-SAME: (i8* [[DOTBLOCK_DESCRIPTOR:%.*]]) #[[ATTR2:[0-9]+]] {
|
|
// CHECK4-NEXT: entry:
|
|
// CHECK4-NEXT: [[DOTBLOCK_DESCRIPTOR_ADDR:%.*]] = alloca i8*, align 8
|
|
// CHECK4-NEXT: [[BLOCK_ADDR:%.*]] = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>*, align 8
|
|
// CHECK4-NEXT: store i8* [[DOTBLOCK_DESCRIPTOR]], i8** [[DOTBLOCK_DESCRIPTOR_ADDR]], align 8
|
|
// CHECK4-NEXT: [[BLOCK:%.*]] = bitcast i8* [[DOTBLOCK_DESCRIPTOR]] to <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>*
|
|
// CHECK4-NEXT: store <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>* [[BLOCK]], <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>** [[BLOCK_ADDR]], align 8
|
|
// CHECK4-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* @g)
|
|
// CHECK4-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK4-LABEL: define {{[^@]+}}@.omp_outlined.
|
|
// CHECK4-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[G:%.*]]) #[[ATTR3:[0-9]+]] {
|
|
// CHECK4-NEXT: entry:
|
|
// CHECK4-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK4-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK4-NEXT: [[G_ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK4-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
|
|
// CHECK4-NEXT: [[TMP:%.*]] = alloca i32, align 4
|
|
// CHECK4-NEXT: [[DOTLINEAR_START:%.*]] = alloca i32, align 4
|
|
// CHECK4-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
|
|
// CHECK4-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
|
|
// CHECK4-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
|
|
// CHECK4-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
|
|
// CHECK4-NEXT: [[I:%.*]] = alloca i32, align 4
|
|
// CHECK4-NEXT: [[G1:%.*]] = alloca i32, align 4
|
|
// CHECK4-NEXT: [[BLOCK:%.*]] = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, align 8
|
|
// CHECK4-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
|
|
// CHECK4-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
|
|
// CHECK4-NEXT: store i32* [[G]], i32** [[G_ADDR]], align 8
|
|
// CHECK4-NEXT: [[TMP0:%.*]] = load i32*, i32** [[G_ADDR]], align 8
|
|
// CHECK4-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
|
|
// CHECK4-NEXT: store i32 [[TMP1]], i32* [[DOTLINEAR_START]], align 4
|
|
// CHECK4-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
|
|
// CHECK4-NEXT: store i32 1, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK4-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
|
|
// CHECK4-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
|
|
// CHECK4-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
|
|
// CHECK4-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
|
|
// CHECK4-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 [[TMP3]])
|
|
// CHECK4-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
|
|
// CHECK4-NEXT: [[TMP4:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK4-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 1
|
|
// CHECK4-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
|
|
// CHECK4: cond.true:
|
|
// CHECK4-NEXT: br label [[COND_END:%.*]]
|
|
// CHECK4: cond.false:
|
|
// CHECK4-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK4-NEXT: br label [[COND_END]]
|
|
// CHECK4: cond.end:
|
|
// CHECK4-NEXT: [[COND:%.*]] = phi i32 [ 1, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ]
|
|
// CHECK4-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
|
|
// CHECK4-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
|
|
// CHECK4-NEXT: store i32 [[TMP6]], i32* [[DOTOMP_IV]], align 4
|
|
// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
|
|
// CHECK4: omp.inner.for.cond:
|
|
// CHECK4-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK4-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
|
|
// CHECK4-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]]
|
|
// CHECK4-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
|
|
// CHECK4: omp.inner.for.body:
|
|
// CHECK4-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK4-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1
|
|
// CHECK4-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
|
|
// CHECK4-NEXT: store i32 [[ADD]], i32* [[I]], align 4
|
|
// CHECK4-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4
|
|
// CHECK4-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK4-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP11]], 5
|
|
// CHECK4-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], [[MUL3]]
|
|
// CHECK4-NEXT: store i32 [[ADD4]], i32* [[G1]], align 4
|
|
// CHECK4-NEXT: [[TMP12:%.*]] = load i32, i32* [[G1]], align 4
|
|
// CHECK4-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP12]], 5
|
|
// CHECK4-NEXT: store i32 [[ADD5]], i32* [[G1]], align 4
|
|
// CHECK4-NEXT: store i32 1, i32* [[G1]], align 4
|
|
// CHECK4-NEXT: [[BLOCK_ISA:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK]], i32 0, i32 0
|
|
// CHECK4-NEXT: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*), i8** [[BLOCK_ISA]], align 8
|
|
// CHECK4-NEXT: [[BLOCK_FLAGS:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK]], i32 0, i32 1
|
|
// CHECK4-NEXT: store i32 1073741824, i32* [[BLOCK_FLAGS]], align 8
|
|
// CHECK4-NEXT: [[BLOCK_RESERVED:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK]], i32 0, i32 2
|
|
// CHECK4-NEXT: store i32 0, i32* [[BLOCK_RESERVED]], align 4
|
|
// CHECK4-NEXT: [[BLOCK_INVOKE:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK]], i32 0, i32 3
|
|
// CHECK4-NEXT: store i8* bitcast (void (i8*)* @g_block_invoke to i8*), i8** [[BLOCK_INVOKE]], align 8
|
|
// CHECK4-NEXT: [[BLOCK_DESCRIPTOR:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK]], i32 0, i32 4
|
|
// CHECK4-NEXT: store %struct.__block_descriptor* bitcast ({ i64, i64, i8*, i8* }* @__block_descriptor_tmp.1 to %struct.__block_descriptor*), %struct.__block_descriptor** [[BLOCK_DESCRIPTOR]], align 8
|
|
// CHECK4-NEXT: [[BLOCK_CAPTURED:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK]], i32 0, i32 5
|
|
// CHECK4-NEXT: [[TMP13:%.*]] = load volatile i32, i32* [[G1]], align 4
|
|
// CHECK4-NEXT: store volatile i32 [[TMP13]], i32* [[BLOCK_CAPTURED]], align 8
|
|
// CHECK4-NEXT: [[TMP14:%.*]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK]] to void ()*
|
|
// CHECK4-NEXT: [[BLOCK_LITERAL:%.*]] = bitcast void ()* [[TMP14]] to %struct.__block_literal_generic*
|
|
// CHECK4-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT___BLOCK_LITERAL_GENERIC:%.*]], %struct.__block_literal_generic* [[BLOCK_LITERAL]], i32 0, i32 3
|
|
// CHECK4-NEXT: [[TMP16:%.*]] = bitcast %struct.__block_literal_generic* [[BLOCK_LITERAL]] to i8*
|
|
// CHECK4-NEXT: [[TMP17:%.*]] = load i8*, i8** [[TMP15]], align 8
|
|
// CHECK4-NEXT: [[TMP18:%.*]] = bitcast i8* [[TMP17]] to void (i8*)*
|
|
// CHECK4-NEXT: call void [[TMP18]](i8* [[TMP16]])
|
|
// CHECK4-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
|
|
// CHECK4: omp.body.continue:
|
|
// CHECK4-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
|
|
// CHECK4: omp.inner.for.inc:
|
|
// CHECK4-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
|
|
// CHECK4-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP19]], 1
|
|
// CHECK4-NEXT: store i32 [[ADD6]], i32* [[DOTOMP_IV]], align 4
|
|
// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND]]
|
|
// CHECK4: omp.inner.for.end:
|
|
// CHECK4-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
|
|
// CHECK4: omp.loop.exit:
|
|
// CHECK4-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP3]])
|
|
// CHECK4-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4
|
|
// CHECK4-NEXT: [[TMP21:%.*]] = icmp ne i32 [[TMP20]], 0
|
|
// CHECK4-NEXT: br i1 [[TMP21]], label [[DOTOMP_LINEAR_PU:%.*]], label [[DOTOMP_LINEAR_PU_DONE:%.*]]
|
|
// CHECK4: .omp.linear.pu:
|
|
// CHECK4-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4
|
|
// CHECK4-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP22]], 10
|
|
// CHECK4-NEXT: store i32 [[ADD7]], i32* [[TMP0]], align 4
|
|
// CHECK4-NEXT: br label [[DOTOMP_LINEAR_PU_DONE]]
|
|
// CHECK4: .omp.linear.pu.done:
|
|
// CHECK4-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK4-LABEL: define {{[^@]+}}@g_block_invoke
|
|
// CHECK4-SAME: (i8* [[DOTBLOCK_DESCRIPTOR:%.*]]) #[[ATTR2]] {
|
|
// CHECK4-NEXT: entry:
|
|
// CHECK4-NEXT: [[DOTBLOCK_DESCRIPTOR_ADDR:%.*]] = alloca i8*, align 8
|
|
// CHECK4-NEXT: [[BLOCK_ADDR:%.*]] = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>*, align 8
|
|
// CHECK4-NEXT: store i8* [[DOTBLOCK_DESCRIPTOR]], i8** [[DOTBLOCK_DESCRIPTOR_ADDR]], align 8
|
|
// CHECK4-NEXT: [[BLOCK:%.*]] = bitcast i8* [[DOTBLOCK_DESCRIPTOR]] to <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>*
|
|
// CHECK4-NEXT: store <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK]], <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>** [[BLOCK_ADDR]], align 8
|
|
// CHECK4-NEXT: [[BLOCK_CAPTURE_ADDR:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK]], i32 0, i32 5
|
|
// CHECK4-NEXT: store i32 2, i32* [[BLOCK_CAPTURE_ADDR]], align 8
|
|
// CHECK4-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK5-LABEL: define {{[^@]+}}@main
|
|
// CHECK5-SAME: () #[[ATTR0:[0-9]+]] {
|
|
// CHECK5-NEXT: entry:
|
|
// CHECK5-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// CHECK5-NEXT: [[TEST:%.*]] = alloca [[STRUCT_S:%.*]], align 4
|
|
// CHECK5-NEXT: [[PVAR:%.*]] = alloca float*, align 8
|
|
// CHECK5-NEXT: [[LVAR:%.*]] = alloca i64, align 8
|
|
// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4
|
|
// CHECK5-NEXT: store i32 0, i32* [[RETVAL]], align 4
|
|
// CHECK5-NEXT: call void @_ZN1SIfEC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TEST]])
|
|
// CHECK5-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TEST]], i32 0, i32 0
|
|
// CHECK5-NEXT: store float* [[F]], float** [[PVAR]], align 8
|
|
// CHECK5-NEXT: store i64 0, i64* [[LVAR]], align 8
|
|
// CHECK5-NEXT: store i32 0, i32* [[I]], align 4
|
|
// CHECK5-NEXT: br label [[FOR_COND:%.*]]
|
|
// CHECK5: for.cond:
|
|
// CHECK5-NEXT: [[TMP0:%.*]] = load i32, i32* [[I]], align 4
|
|
// CHECK5-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 2
|
|
// CHECK5-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
|
// CHECK5: for.body:
|
|
// CHECK5-NEXT: [[TMP1:%.*]] = load float*, float** [[PVAR]], align 8
|
|
// CHECK5-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds float, float* [[TMP1]], i64 3
|
|
// CHECK5-NEXT: store float* [[ADD_PTR]], float** [[PVAR]], align 8
|
|
// CHECK5-NEXT: [[TMP2:%.*]] = load i64, i64* [[LVAR]], align 8
|
|
// CHECK5-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP2]], 3
|
|
// CHECK5-NEXT: store i64 [[ADD]], i64* [[LVAR]], align 8
|
|
// CHECK5-NEXT: br label [[FOR_INC:%.*]]
|
|
// CHECK5: for.inc:
|
|
// CHECK5-NEXT: [[TMP3:%.*]] = load i32, i32* [[I]], align 4
|
|
// CHECK5-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1
|
|
// CHECK5-NEXT: store i32 [[INC]], i32* [[I]], align 4
|
|
// CHECK5-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]]
|
|
// CHECK5: for.end:
|
|
// CHECK5-NEXT: [[CALL:%.*]] = call i32 @_Z5tmainIiET_v()
|
|
// CHECK5-NEXT: store i32 [[CALL]], i32* [[RETVAL]], align 4
|
|
// CHECK5-NEXT: call void @_ZN1SIfED1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TEST]]) #[[ATTR3:[0-9]+]]
|
|
// CHECK5-NEXT: [[TMP4:%.*]] = load i32, i32* [[RETVAL]], align 4
|
|
// CHECK5-NEXT: ret i32 [[TMP4]]
|
|
//
|
|
//
|
|
// CHECK5-LABEL: define {{[^@]+}}@_ZN1SIfEC1Ev
|
|
// CHECK5-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] align 2 {
|
|
// CHECK5-NEXT: entry:
|
|
// CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
|
|
// CHECK5-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: call void @_ZN1SIfEC2Ev(%struct.S* nonnull align 4 dereferenceable(4) [[THIS1]])
|
|
// CHECK5-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK5-LABEL: define {{[^@]+}}@_Z5tmainIiET_v
|
|
// CHECK5-SAME: () #[[ATTR2:[0-9]+]] {
|
|
// CHECK5-NEXT: entry:
|
|
// CHECK5-NEXT: [[TEST:%.*]] = alloca [[STRUCT_S_0:%.*]], align 4
|
|
// CHECK5-NEXT: [[PVAR:%.*]] = alloca i32*, align 8
|
|
// CHECK5-NEXT: [[LVAR:%.*]] = alloca i32, align 4
|
|
// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4
|
|
// CHECK5-NEXT: call void @_ZN1SIiEC1Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[TEST]])
|
|
// CHECK5-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[TEST]], i32 0, i32 0
|
|
// CHECK5-NEXT: store i32* [[F]], i32** [[PVAR]], align 8
|
|
// CHECK5-NEXT: store i32 0, i32* [[LVAR]], align 4
|
|
// CHECK5-NEXT: store i32 0, i32* [[I]], align 4
|
|
// CHECK5-NEXT: br label [[FOR_COND:%.*]]
|
|
// CHECK5: for.cond:
|
|
// CHECK5-NEXT: [[TMP0:%.*]] = load i32, i32* [[I]], align 4
|
|
// CHECK5-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 2
|
|
// CHECK5-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
|
// CHECK5: for.body:
|
|
// CHECK5-NEXT: [[TMP1:%.*]] = load i32*, i32** [[PVAR]], align 8
|
|
// CHECK5-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i32 1
|
|
// CHECK5-NEXT: store i32* [[INCDEC_PTR]], i32** [[PVAR]], align 8
|
|
// CHECK5-NEXT: [[TMP2:%.*]] = load i32, i32* [[LVAR]], align 4
|
|
// CHECK5-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
|
|
// CHECK5-NEXT: store i32 [[INC]], i32* [[LVAR]], align 4
|
|
// CHECK5-NEXT: br label [[FOR_INC:%.*]]
|
|
// CHECK5: for.inc:
|
|
// CHECK5-NEXT: [[TMP3:%.*]] = load i32, i32* [[I]], align 4
|
|
// CHECK5-NEXT: [[INC1:%.*]] = add nsw i32 [[TMP3]], 1
|
|
// CHECK5-NEXT: store i32 [[INC1]], i32* [[I]], align 4
|
|
// CHECK5-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
|
|
// CHECK5: for.end:
|
|
// CHECK5-NEXT: call void @_ZN1SIiED1Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[TEST]]) #[[ATTR3]]
|
|
// CHECK5-NEXT: ret i32 0
|
|
//
|
|
//
|
|
// CHECK5-LABEL: define {{[^@]+}}@_ZN1SIfED1Ev
|
|
// CHECK5-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK5-NEXT: entry:
|
|
// CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
|
|
// CHECK5-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: call void @_ZN1SIfED2Ev(%struct.S* nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR3]]
|
|
// CHECK5-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK5-LABEL: define {{[^@]+}}@_ZN1SIfEC2Ev
|
|
// CHECK5-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK5-NEXT: entry:
|
|
// CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
|
|
// CHECK5-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[THIS1]], i32 0, i32 0
|
|
// CHECK5-NEXT: store float 0.000000e+00, float* [[F]], align 4
|
|
// CHECK5-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK5-LABEL: define {{[^@]+}}@_ZN1SIfED2Ev
|
|
// CHECK5-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK5-NEXT: entry:
|
|
// CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
|
|
// CHECK5-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK5-LABEL: define {{[^@]+}}@_ZN1SIiEC1Ev
|
|
// CHECK5-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK5-NEXT: entry:
|
|
// CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
|
|
// CHECK5-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: call void @_ZN1SIiEC2Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS1]])
|
|
// CHECK5-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK5-LABEL: define {{[^@]+}}@_ZN1SIiED1Ev
|
|
// CHECK5-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK5-NEXT: entry:
|
|
// CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
|
|
// CHECK5-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: call void @_ZN1SIiED2Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR3]]
|
|
// CHECK5-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK5-LABEL: define {{[^@]+}}@_ZN1SIiEC2Ev
|
|
// CHECK5-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK5-NEXT: entry:
|
|
// CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
|
|
// CHECK5-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S_0:%.*]], %struct.S.0* [[THIS1]], i32 0, i32 0
|
|
// CHECK5-NEXT: store i32 0, i32* [[F]], align 4
|
|
// CHECK5-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK5-LABEL: define {{[^@]+}}@_ZN1SIiED2Ev
|
|
// CHECK5-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK5-NEXT: entry:
|
|
// CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
|
|
// CHECK5-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK5-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK6-LABEL: define {{[^@]+}}@main
|
|
// CHECK6-SAME: () #[[ATTR0:[0-9]+]] {
|
|
// CHECK6-NEXT: entry:
|
|
// CHECK6-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// CHECK6-NEXT: [[TEST:%.*]] = alloca [[STRUCT_S:%.*]], align 4
|
|
// CHECK6-NEXT: [[PVAR:%.*]] = alloca float*, align 8
|
|
// CHECK6-NEXT: [[LVAR:%.*]] = alloca i64, align 8
|
|
// CHECK6-NEXT: [[I:%.*]] = alloca i32, align 4
|
|
// CHECK6-NEXT: store i32 0, i32* [[RETVAL]], align 4
|
|
// CHECK6-NEXT: call void @_ZN1SIfEC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TEST]])
|
|
// CHECK6-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TEST]], i32 0, i32 0
|
|
// CHECK6-NEXT: store float* [[F]], float** [[PVAR]], align 8
|
|
// CHECK6-NEXT: store i64 0, i64* [[LVAR]], align 8
|
|
// CHECK6-NEXT: store i32 0, i32* [[I]], align 4
|
|
// CHECK6-NEXT: br label [[FOR_COND:%.*]]
|
|
// CHECK6: for.cond:
|
|
// CHECK6-NEXT: [[TMP0:%.*]] = load i32, i32* [[I]], align 4
|
|
// CHECK6-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 2
|
|
// CHECK6-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
|
// CHECK6: for.body:
|
|
// CHECK6-NEXT: [[TMP1:%.*]] = load float*, float** [[PVAR]], align 8
|
|
// CHECK6-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds float, float* [[TMP1]], i64 3
|
|
// CHECK6-NEXT: store float* [[ADD_PTR]], float** [[PVAR]], align 8
|
|
// CHECK6-NEXT: [[TMP2:%.*]] = load i64, i64* [[LVAR]], align 8
|
|
// CHECK6-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP2]], 3
|
|
// CHECK6-NEXT: store i64 [[ADD]], i64* [[LVAR]], align 8
|
|
// CHECK6-NEXT: br label [[FOR_INC:%.*]]
|
|
// CHECK6: for.inc:
|
|
// CHECK6-NEXT: [[TMP3:%.*]] = load i32, i32* [[I]], align 4
|
|
// CHECK6-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1
|
|
// CHECK6-NEXT: store i32 [[INC]], i32* [[I]], align 4
|
|
// CHECK6-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]]
|
|
// CHECK6: for.end:
|
|
// CHECK6-NEXT: [[CALL:%.*]] = call i32 @_Z5tmainIiET_v()
|
|
// CHECK6-NEXT: store i32 [[CALL]], i32* [[RETVAL]], align 4
|
|
// CHECK6-NEXT: call void @_ZN1SIfED1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TEST]]) #[[ATTR3:[0-9]+]]
|
|
// CHECK6-NEXT: [[TMP4:%.*]] = load i32, i32* [[RETVAL]], align 4
|
|
// CHECK6-NEXT: ret i32 [[TMP4]]
|
|
//
|
|
//
|
|
// CHECK6-LABEL: define {{[^@]+}}@_ZN1SIfEC1Ev
|
|
// CHECK6-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] align 2 {
|
|
// CHECK6-NEXT: entry:
|
|
// CHECK6-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
|
|
// CHECK6-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: call void @_ZN1SIfEC2Ev(%struct.S* nonnull align 4 dereferenceable(4) [[THIS1]])
|
|
// CHECK6-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK6-LABEL: define {{[^@]+}}@_Z5tmainIiET_v
|
|
// CHECK6-SAME: () #[[ATTR2:[0-9]+]] {
|
|
// CHECK6-NEXT: entry:
|
|
// CHECK6-NEXT: [[TEST:%.*]] = alloca [[STRUCT_S_0:%.*]], align 4
|
|
// CHECK6-NEXT: [[PVAR:%.*]] = alloca i32*, align 8
|
|
// CHECK6-NEXT: [[LVAR:%.*]] = alloca i32, align 4
|
|
// CHECK6-NEXT: [[I:%.*]] = alloca i32, align 4
|
|
// CHECK6-NEXT: call void @_ZN1SIiEC1Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[TEST]])
|
|
// CHECK6-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S_0]], %struct.S.0* [[TEST]], i32 0, i32 0
|
|
// CHECK6-NEXT: store i32* [[F]], i32** [[PVAR]], align 8
|
|
// CHECK6-NEXT: store i32 0, i32* [[LVAR]], align 4
|
|
// CHECK6-NEXT: store i32 0, i32* [[I]], align 4
|
|
// CHECK6-NEXT: br label [[FOR_COND:%.*]]
|
|
// CHECK6: for.cond:
|
|
// CHECK6-NEXT: [[TMP0:%.*]] = load i32, i32* [[I]], align 4
|
|
// CHECK6-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 2
|
|
// CHECK6-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
|
// CHECK6: for.body:
|
|
// CHECK6-NEXT: [[TMP1:%.*]] = load i32*, i32** [[PVAR]], align 8
|
|
// CHECK6-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i32 1
|
|
// CHECK6-NEXT: store i32* [[INCDEC_PTR]], i32** [[PVAR]], align 8
|
|
// CHECK6-NEXT: [[TMP2:%.*]] = load i32, i32* [[LVAR]], align 4
|
|
// CHECK6-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
|
|
// CHECK6-NEXT: store i32 [[INC]], i32* [[LVAR]], align 4
|
|
// CHECK6-NEXT: br label [[FOR_INC:%.*]]
|
|
// CHECK6: for.inc:
|
|
// CHECK6-NEXT: [[TMP3:%.*]] = load i32, i32* [[I]], align 4
|
|
// CHECK6-NEXT: [[INC1:%.*]] = add nsw i32 [[TMP3]], 1
|
|
// CHECK6-NEXT: store i32 [[INC1]], i32* [[I]], align 4
|
|
// CHECK6-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
|
|
// CHECK6: for.end:
|
|
// CHECK6-NEXT: call void @_ZN1SIiED1Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[TEST]]) #[[ATTR3]]
|
|
// CHECK6-NEXT: ret i32 0
|
|
//
|
|
//
|
|
// CHECK6-LABEL: define {{[^@]+}}@_ZN1SIfED1Ev
|
|
// CHECK6-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK6-NEXT: entry:
|
|
// CHECK6-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
|
|
// CHECK6-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: call void @_ZN1SIfED2Ev(%struct.S* nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR3]]
|
|
// CHECK6-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK6-LABEL: define {{[^@]+}}@_ZN1SIfEC2Ev
|
|
// CHECK6-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK6-NEXT: entry:
|
|
// CHECK6-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
|
|
// CHECK6-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[THIS1]], i32 0, i32 0
|
|
// CHECK6-NEXT: store float 0.000000e+00, float* [[F]], align 4
|
|
// CHECK6-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK6-LABEL: define {{[^@]+}}@_ZN1SIfED2Ev
|
|
// CHECK6-SAME: (%struct.S* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK6-NEXT: entry:
|
|
// CHECK6-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S*, align 8
|
|
// CHECK6-NEXT: store %struct.S* [[THIS]], %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK6-LABEL: define {{[^@]+}}@_ZN1SIiEC1Ev
|
|
// CHECK6-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK6-NEXT: entry:
|
|
// CHECK6-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
|
|
// CHECK6-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: call void @_ZN1SIiEC2Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS1]])
|
|
// CHECK6-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK6-LABEL: define {{[^@]+}}@_ZN1SIiED1Ev
|
|
// CHECK6-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK6-NEXT: entry:
|
|
// CHECK6-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
|
|
// CHECK6-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: call void @_ZN1SIiED2Ev(%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR3]]
|
|
// CHECK6-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK6-LABEL: define {{[^@]+}}@_ZN1SIiEC2Ev
|
|
// CHECK6-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK6-NEXT: entry:
|
|
// CHECK6-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
|
|
// CHECK6-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: [[F:%.*]] = getelementptr inbounds [[STRUCT_S_0:%.*]], %struct.S.0* [[THIS1]], i32 0, i32 0
|
|
// CHECK6-NEXT: store i32 0, i32* [[F]], align 4
|
|
// CHECK6-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK6-LABEL: define {{[^@]+}}@_ZN1SIiED2Ev
|
|
// CHECK6-SAME: (%struct.S.0* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 {
|
|
// CHECK6-NEXT: entry:
|
|
// CHECK6-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.S.0*, align 8
|
|
// CHECK6-NEXT: store %struct.S.0* [[THIS]], %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: [[THIS1:%.*]] = load %struct.S.0*, %struct.S.0** [[THIS_ADDR]], align 8
|
|
// CHECK6-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK7-LABEL: define {{[^@]+}}@main
|
|
// CHECK7-SAME: () #[[ATTR0:[0-9]+]] {
|
|
// CHECK7-NEXT: entry:
|
|
// CHECK7-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// CHECK7-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON:%.*]], align 1
|
|
// CHECK7-NEXT: store i32 0, i32* [[RETVAL]], align 4
|
|
// CHECK7-NEXT: call void @"_ZZ4mainENK3$_0clEv"(%class.anon* nonnull align 1 dereferenceable(1) [[REF_TMP]])
|
|
// CHECK7-NEXT: ret i32 0
|
|
//
|
|
//
|
|
// CHECK8-LABEL: define {{[^@]+}}@main
|
|
// CHECK8-SAME: () #[[ATTR1:[0-9]+]] {
|
|
// CHECK8-NEXT: entry:
|
|
// CHECK8-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// CHECK8-NEXT: store i32 0, i32* [[RETVAL]], align 4
|
|
// CHECK8-NEXT: [[TMP0:%.*]] = load i8*, i8** getelementptr inbounds ([[STRUCT___BLOCK_LITERAL_GENERIC:%.*]], %struct.__block_literal_generic* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor* }* @__block_literal_global to %struct.__block_literal_generic*), i32 0, i32 3), align 8
|
|
// CHECK8-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to void (i8*)*
|
|
// CHECK8-NEXT: call void [[TMP1]](i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor* }* @__block_literal_global to i8*))
|
|
// CHECK8-NEXT: ret i32 0
|
|
//
|
|
//
|
|
// CHECK8-LABEL: define {{[^@]+}}@__main_block_invoke
|
|
// CHECK8-SAME: (i8* [[DOTBLOCK_DESCRIPTOR:%.*]]) #[[ATTR2:[0-9]+]] {
|
|
// CHECK8-NEXT: entry:
|
|
// CHECK8-NEXT: [[DOTBLOCK_DESCRIPTOR_ADDR:%.*]] = alloca i8*, align 8
|
|
// CHECK8-NEXT: [[BLOCK_ADDR:%.*]] = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>*, align 8
|
|
// CHECK8-NEXT: [[I:%.*]] = alloca i32, align 4
|
|
// CHECK8-NEXT: [[BLOCK1:%.*]] = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, align 8
|
|
// CHECK8-NEXT: store i8* [[DOTBLOCK_DESCRIPTOR]], i8** [[DOTBLOCK_DESCRIPTOR_ADDR]], align 8
|
|
// CHECK8-NEXT: [[BLOCK:%.*]] = bitcast i8* [[DOTBLOCK_DESCRIPTOR]] to <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>*
|
|
// CHECK8-NEXT: store <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>* [[BLOCK]], <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>** [[BLOCK_ADDR]], align 8
|
|
// CHECK8-NEXT: store i32 0, i32* [[I]], align 4
|
|
// CHECK8-NEXT: br label [[FOR_COND:%.*]]
|
|
// CHECK8: for.cond:
|
|
// CHECK8-NEXT: [[TMP0:%.*]] = load i32, i32* [[I]], align 4
|
|
// CHECK8-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 2
|
|
// CHECK8-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
|
// CHECK8: for.body:
|
|
// CHECK8-NEXT: [[TMP1:%.*]] = load i32, i32* @g, align 4
|
|
// CHECK8-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP1]], 5
|
|
// CHECK8-NEXT: store i32 [[ADD]], i32* @g, align 4
|
|
// CHECK8-NEXT: store i32 1, i32* @g, align 4
|
|
// CHECK8-NEXT: [[BLOCK_ISA:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK1]], i32 0, i32 0
|
|
// CHECK8-NEXT: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*), i8** [[BLOCK_ISA]], align 8
|
|
// CHECK8-NEXT: [[BLOCK_FLAGS:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK1]], i32 0, i32 1
|
|
// CHECK8-NEXT: store i32 1073741824, i32* [[BLOCK_FLAGS]], align 8
|
|
// CHECK8-NEXT: [[BLOCK_RESERVED:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK1]], i32 0, i32 2
|
|
// CHECK8-NEXT: store i32 0, i32* [[BLOCK_RESERVED]], align 4
|
|
// CHECK8-NEXT: [[BLOCK_INVOKE:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK1]], i32 0, i32 3
|
|
// CHECK8-NEXT: store i8* bitcast (void (i8*)* @__main_block_invoke_2 to i8*), i8** [[BLOCK_INVOKE]], align 8
|
|
// CHECK8-NEXT: [[BLOCK_DESCRIPTOR:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK1]], i32 0, i32 4
|
|
// CHECK8-NEXT: store %struct.__block_descriptor* bitcast ({ i64, i64, i8*, i8* }* @__block_descriptor_tmp.1 to %struct.__block_descriptor*), %struct.__block_descriptor** [[BLOCK_DESCRIPTOR]], align 8
|
|
// CHECK8-NEXT: [[BLOCK_CAPTURED:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK1]], i32 0, i32 5
|
|
// CHECK8-NEXT: [[TMP2:%.*]] = load volatile i32, i32* @g, align 4
|
|
// CHECK8-NEXT: store volatile i32 [[TMP2]], i32* [[BLOCK_CAPTURED]], align 8
|
|
// CHECK8-NEXT: [[TMP3:%.*]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK1]] to void ()*
|
|
// CHECK8-NEXT: [[BLOCK_LITERAL:%.*]] = bitcast void ()* [[TMP3]] to %struct.__block_literal_generic*
|
|
// CHECK8-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT___BLOCK_LITERAL_GENERIC:%.*]], %struct.__block_literal_generic* [[BLOCK_LITERAL]], i32 0, i32 3
|
|
// CHECK8-NEXT: [[TMP5:%.*]] = bitcast %struct.__block_literal_generic* [[BLOCK_LITERAL]] to i8*
|
|
// CHECK8-NEXT: [[TMP6:%.*]] = load i8*, i8** [[TMP4]], align 8
|
|
// CHECK8-NEXT: [[TMP7:%.*]] = bitcast i8* [[TMP6]] to void (i8*)*
|
|
// CHECK8-NEXT: call void [[TMP7]](i8* [[TMP5]])
|
|
// CHECK8-NEXT: br label [[FOR_INC:%.*]]
|
|
// CHECK8: for.inc:
|
|
// CHECK8-NEXT: [[TMP8:%.*]] = load i32, i32* [[I]], align 4
|
|
// CHECK8-NEXT: [[INC:%.*]] = add nsw i32 [[TMP8]], 1
|
|
// CHECK8-NEXT: store i32 [[INC]], i32* [[I]], align 4
|
|
// CHECK8-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]]
|
|
// CHECK8: for.end:
|
|
// CHECK8-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK8-LABEL: define {{[^@]+}}@__main_block_invoke_2
|
|
// CHECK8-SAME: (i8* [[DOTBLOCK_DESCRIPTOR:%.*]]) #[[ATTR2]] {
|
|
// CHECK8-NEXT: entry:
|
|
// CHECK8-NEXT: [[DOTBLOCK_DESCRIPTOR_ADDR:%.*]] = alloca i8*, align 8
|
|
// CHECK8-NEXT: [[BLOCK_ADDR:%.*]] = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>*, align 8
|
|
// CHECK8-NEXT: store i8* [[DOTBLOCK_DESCRIPTOR]], i8** [[DOTBLOCK_DESCRIPTOR_ADDR]], align 8
|
|
// CHECK8-NEXT: [[BLOCK:%.*]] = bitcast i8* [[DOTBLOCK_DESCRIPTOR]] to <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>*
|
|
// CHECK8-NEXT: store <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK]], <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>** [[BLOCK_ADDR]], align 8
|
|
// CHECK8-NEXT: [[BLOCK_CAPTURE_ADDR:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* [[BLOCK]], i32 0, i32 5
|
|
// CHECK8-NEXT: store i32 2, i32* [[BLOCK_CAPTURE_ADDR]], align 8
|
|
// CHECK8-NEXT: ret void
|
|
//
|