llvm-project/clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
Xiangling Liao 6ef801aa6b [AIX] Static init frontend recovery and backend support
On the frontend side, this patch recovers AIX static init implementation to
use the linkage type and function names Clang chooses for sinit related function.

On the backend side, this patch sets correct linkage and function names on aliases
created for sinit/sterm functions.

Differential Revision: https://reviews.llvm.org/D84534
2020-08-10 10:10:49 -04:00

233 lines
8.3 KiB
C++

// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
// RUN: -std=c++2a < %s | \
// RUN: FileCheck --check-prefixes=CHECK,CHECK32 %s
// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
// RUN: -std=c++2a < %s | \
// RUN: FileCheck --check-prefixes=CHECK,CHECK64 %s
namespace test1 {
struct Test1 {
Test1(int) {}
~Test1() {}
};
Test1 t0 = 2;
template <typename T>
Test1 t1 = 2;
inline Test1 t2 = 2;
void foo() {
(void)&t1<int>;
}
} // namespace test1
namespace test2 {
template <typename = void>
struct A {
A() {}
~A() {}
static A instance;
};
template <typename T>
A<T> A<T>::instance;
template A<> A<>::instance;
A<int> &bar() {
A<int> *a = new A<int>;
return *a;
}
template <>
A<int> A<int>::instance = bar();
} // namespace test2
// CHECK: @llvm.global_ctors = appending global [4 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__cxx_global_var_init.1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @__cxx_global_var_init.2, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @__cxx_global_var_init.4, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I__, i8* null }]
// CHECK: @llvm.global_dtors = appending global [4 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__finalize__ZN5test12t2E, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @__finalize__ZN5test21AIvE8instanceE, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @__finalize__ZN5test12t1IiEE, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__D_a, i8* null }]
// CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK32: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t0E, i32 2)
// CHECK64: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t0E, i32 signext 2)
// CHECK: %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t0E)
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @__dtor__ZN5test12t0E() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t0E)
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @__finalize__ZN5test12t0E() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t0E)
// CHECK: %needs_destruct = icmp eq i32 %0, 0
// CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end
// CHECK: destruct.call:
// CHECK: call void @__dtor__ZN5test12t0E()
// CHECK: br label %destruct.end
// CHECK: destruct.end:
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @__cxx_global_var_init.1() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: %0 = load atomic i8, i8* bitcast (i64* @_ZGVN5test12t2E to i8*) acquire
// CHECK: %guard.uninitialized = icmp eq i8 %0, 0
// CHECK: br i1 %guard.uninitialized, label %init.check, label %init.end
// CHECK: init.check:
// CHECK: %1 = call i32 @__cxa_guard_acquire(i64* @_ZGVN5test12t2E)
// CHECK: %tobool = icmp ne i32 %1, 0
// CHECK: br i1 %tobool, label %init, label %init.end
// CHECK: init:
// CHECK32: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t2E, i32 2)
// CHECK64: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t2E, i32 signext 2)
// CHECK: %2 = call i32 @atexit(void ()* @__dtor__ZN5test12t2E)
// CHECK: call void @__cxa_guard_release(i64* @_ZGVN5test12t2E)
// CHECK: br label %init.end
// CHECK: init.end:
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @__dtor__ZN5test12t2E() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @__finalize__ZN5test12t2E() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t2E)
// CHECK: %needs_destruct = icmp eq i32 %0, 0
// CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end
// CHECK: destruct.call:
// CHECK: call void @__dtor__ZN5test12t2E()
// CHECK: br label %destruct.end
// CHECK: destruct.end:
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @__cxx_global_var_init.2() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: %0 = load i8, i8* bitcast (i64* @_ZGVN5test21AIvE8instanceE to i8*)
// CHECK: %guard.uninitialized = icmp eq i8 %0, 0
// CHECK: br i1 %guard.uninitialized, label %init.check, label %init.end
// CHECK: init.check:
// CHECK: call void @_ZN5test21AIvEC1Ev(%"struct.test2::A"* @_ZN5test21AIvE8instanceE)
// CHECK: %1 = call i32 @atexit(void ()* @__dtor__ZN5test21AIvE8instanceE)
// CHECK: store i64 1, i64* @_ZGVN5test21AIvE8instanceE
// CHECK: br label %init.end
// CHECK: init.end:
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @__dtor__ZN5test21AIvE8instanceE() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: call void @_ZN5test21AIvED1Ev(%"struct.test2::A"* @_ZN5test21AIvE8instanceE)
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @__finalize__ZN5test21AIvE8instanceE() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test21AIvE8instanceE)
// CHECK: %needs_destruct = icmp eq i32 %0, 0
// CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end
// CHECK: destruct.call:
// CHECK: call void @__dtor__ZN5test21AIvE8instanceE()
// CHECK: br label %destruct.end
// CHECK: destruct.end:
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @__cxx_global_var_init.3() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: %call = call nonnull align 1 dereferenceable(1) %"struct.test2::A.0"* @_ZN5test23barEv()
// CHECK: %0 = call i32 @atexit(void ()* @__dtor__ZN5test21AIiE8instanceE)
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @__dtor__ZN5test21AIiE8instanceE() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: call void @_ZN5test21AIiED1Ev(%"struct.test2::A.0"* @_ZN5test21AIiE8instanceE)
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @__finalize__ZN5test21AIiE8instanceE() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test21AIiE8instanceE)
// CHECK: %needs_destruct = icmp eq i32 %0, 0
// CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end
// CHECK: destruct.call:
// CHECK: call void @__dtor__ZN5test21AIiE8instanceE()
// CHECK: br label %destruct.end
// CHECK: destruct.end:
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @__cxx_global_var_init.4() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: %0 = load i8, i8* bitcast (i64* @_ZGVN5test12t1IiEE to i8*)
// CHECK: %guard.uninitialized = icmp eq i8 %0, 0
// CHECK: br i1 %guard.uninitialized, label %init.check, label %init.end
// CHECK: init.check:
// CHECK32: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t1IiEE, i32 2)
// CHECK64: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t1IiEE, i32 signext 2)
// CHECK: %1 = call i32 @atexit(void ()* @__dtor__ZN5test12t1IiEE)
// CHECK: store i64 1, i64* @_ZGVN5test12t1IiEE
// CHECK: br label %init.end
// CHECK: init.end:
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @__dtor__ZN5test12t1IiEE() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t1IiEE)
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @__finalize__ZN5test12t1IiEE() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t1IiEE)
// CHECK: %needs_destruct = icmp eq i32 %0, 0
// CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end
// CHECK: destruct.call:
// CHECK: call void @__dtor__ZN5test12t1IiEE()
// CHECK: br label %destruct.end
// CHECK: destruct.end:
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @_GLOBAL__sub_I__() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: call void @__cxx_global_var_init()
// CHECK: call void @__cxx_global_var_init.3()
// CHECK: ret void
// CHECK: }
// CHECK: define internal void @_GLOBAL__D_a() [[ATTR:#[0-9]+]] {
// CHECK: entry:
// CHECK: call void @__finalize__ZN5test21AIiE8instanceE()
// CHECK: call void @__finalize__ZN5test12t0E()
// CHECK: ret void
// CHECK: }