mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-14 03:29:57 +00:00
[FE] Manipulate the first byte of guard variable type in both load and store operation
As Itanium ABI[http://itanium-cxx-abi.github.io/cxx-abi/abi.html#once-ctor] points out: "The size of the guard variable is 64 bits. The first byte (i.e. the byte at the address of the full variable) shall contain the value 0 prior to initialization of the associated variable, and 1 after initialization is complete." Differential Revision: https://reviews.llvm.org/D95822
This commit is contained in:
parent
ecc8ac3f08
commit
6b1e2fc893
@ -2472,7 +2472,10 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
|
||||
CGF.EmitNounwindRuntimeCall(getGuardReleaseFn(CGM, guardPtrTy),
|
||||
guardAddr.getPointer());
|
||||
} else {
|
||||
Builder.CreateStore(llvm::ConstantInt::get(guardTy, 1), guardAddr);
|
||||
// Store 1 into the first byte of the guard variable after initialization is
|
||||
// complete.
|
||||
Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
|
||||
Builder.CreateElementBitCast(guardAddr, CGM.Int8Ty));
|
||||
}
|
||||
|
||||
CGF.EmitBlock(EndBlock);
|
||||
|
@ -44,6 +44,9 @@ template <>
|
||||
A<int> A<int>::instance = bar();
|
||||
} // namespace test2
|
||||
|
||||
// CHECK: @_ZGVN5test12t2E = linkonce_odr global i64 0, align 8
|
||||
// CHECK: @_ZGVN5test21AIvE8instanceE = weak_odr global i64 0, align 8
|
||||
// CHECK: @_ZGVN5test12t1IiEE = linkonce_odr global i64 0, align 8
|
||||
// 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 }]
|
||||
|
||||
@ -77,7 +80,7 @@ A<int> A<int>::instance = bar();
|
||||
|
||||
// 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: %0 = load atomic i8, i8* bitcast (i64* @_ZGVN5test12t2E to i8*) acquire, align 8
|
||||
// CHECK: %guard.uninitialized = icmp eq i8 %0, 0
|
||||
// CHECK: br i1 %guard.uninitialized, label %init.check, label %init.end
|
||||
|
||||
@ -119,14 +122,14 @@ A<int> A<int>::instance = bar();
|
||||
|
||||
// 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: %0 = load i8, i8* bitcast (i64* @_ZGVN5test21AIvE8instanceE to i8*), align 8
|
||||
// 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: store i8 1, i8* bitcast (i64* @_ZGVN5test21AIvE8instanceE to i8*), align 8
|
||||
// CHECK: br label %init.end
|
||||
|
||||
// CHECK: init.end:
|
||||
@ -182,7 +185,7 @@ A<int> A<int>::instance = bar();
|
||||
|
||||
// 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: %0 = load i8, i8* bitcast (i64* @_ZGVN5test12t1IiEE to i8*), align 8
|
||||
// CHECK: %guard.uninitialized = icmp eq i8 %0, 0
|
||||
// CHECK: br i1 %guard.uninitialized, label %init.check, label %init.end
|
||||
|
||||
@ -190,7 +193,7 @@ A<int> A<int>::instance = bar();
|
||||
// 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: store i8 1, i8* bitcast (i64* @_ZGVN5test12t1IiEE to i8*), align 8
|
||||
// CHECK: br label %init.end
|
||||
|
||||
// CHECK: init.end:
|
||||
|
@ -38,6 +38,7 @@ namespace test4 {
|
||||
}
|
||||
} // namespace test4
|
||||
|
||||
// CHECK: @_ZGVZN5test41fEvE11staticLocal = internal global i64 0, align 8
|
||||
// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I__, i8* null }]
|
||||
// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__D_a, i8* null }]
|
||||
|
||||
@ -135,7 +136,7 @@ namespace test4 {
|
||||
|
||||
// CHECK: define void @_ZN5test41fEv() [[ATTR:#[0-9]+]] {
|
||||
// CHECK: entry:
|
||||
// CHECK: %0 = load atomic i8, i8* bitcast (i64* @_ZGVZN5test41fEvE11staticLocal to i8*) acquire
|
||||
// CHECK: %0 = load atomic i8, i8* bitcast (i64* @_ZGVZN5test41fEvE11staticLocal to i8*) acquire, align 8
|
||||
// CHECK: %guard.uninitialized = icmp eq i8 %0, 0
|
||||
// CHECK: br i1 %guard.uninitialized, label %init.check, label %init.end
|
||||
|
||||
|
@ -184,7 +184,7 @@ int f() {
|
||||
// need init:
|
||||
// CHECK: call i32 @_Z1gv()
|
||||
// CHECK: store i32 %{{.*}}, i32* @_ZN1VIfE1mE, align 4
|
||||
// CHECK: store i64 1, i64* @_ZGVN1VIfE1mE
|
||||
// CHECK: store i8 1, i8* bitcast (i64* @_ZGVN1VIfE1mE to i8*)
|
||||
// CHECK: br label
|
||||
|
||||
// LINUX: define internal void @[[XF_M_INIT]]()
|
||||
@ -197,7 +197,7 @@ int f() {
|
||||
// need init:
|
||||
// LINUX: call {{.*}}__cxa_thread_atexit
|
||||
// DARWIN: call {{.*}}_tlv_atexit
|
||||
// CHECK: store i64 1, i64* @_ZGVN1XIfE1mE
|
||||
// CHECK: store i8 1, i8* bitcast (i64* @_ZGVN1XIfE1mE to i8*)
|
||||
// CHECK: br label
|
||||
|
||||
// LINUX: declare i32 @__cxa_thread_atexit(void (i8*)*, i8*, i8*)
|
||||
@ -285,7 +285,7 @@ void set_anon_i() {
|
||||
// need init:
|
||||
// CHECK: call i32 @_Z1gv()
|
||||
// CHECK: store i32 %{{.*}}, i32* @_ZN1VIiE1mE, align 4
|
||||
// CHECK: store i64 1, i64* @_ZGVN1VIiE1mE
|
||||
// CHECK: store i8 1, i8* bitcast (i64* @_ZGVN1VIiE1mE to i8*)
|
||||
// CHECK: br label
|
||||
|
||||
// LINUX: define internal void @[[X_M_INIT]]()
|
||||
@ -298,7 +298,7 @@ void set_anon_i() {
|
||||
// need init:
|
||||
// LINUX: call {{.*}}__cxa_thread_atexit
|
||||
// DARWIN: call {{.*}}_tlv_atexit
|
||||
// CHECK: store i64 1, i64* @_ZGVN1XIiE1mE
|
||||
// CHECK: store i8 1, i8* bitcast (i64* @_ZGVN1XIiE1mE to i8*)
|
||||
// CHECK: br label
|
||||
|
||||
// CHECK: define {{.*}}@[[GLOBAL_INIT:.*]]()
|
||||
|
@ -78,10 +78,10 @@ namespace test4 {
|
||||
extern int foo();
|
||||
|
||||
// This needs an initialization function and guard variables.
|
||||
// CHECK: load i8, i8* bitcast (i64* @_ZGVN5test41xE
|
||||
// CHECK: load i8, i8* bitcast (i64* @_ZGVN5test41xE to i8*)
|
||||
// CHECK: [[CALL:%.*]] = call i32 @_ZN5test43fooEv
|
||||
// CHECK-NEXT: store i32 [[CALL]], i32* @_ZN5test41xE
|
||||
// CHECK-NEXT: store i64 1, i64* @_ZGVN5test41xE
|
||||
// CHECK-NEXT: store i8 1, i8* bitcast (i64* @_ZGVN5test41xE to i8*)
|
||||
__attribute__((weak)) int x = foo();
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ namespace test3 {
|
||||
// CHECK-NEXT: br i1 [[UNINITIALIZED]]
|
||||
// CHECK: [[TMP:%.*]] = call i32 @_ZN5test33fooEv()
|
||||
// CHECK-NEXT: store i32 [[TMP]], i32* @_ZN5test31AIiE1xE, align 4
|
||||
// CHECK-NEXT: store i64 1, i64* @_ZGVN5test31AIiE1xE
|
||||
// CHECK-NEXT: store i8 1, i8* bitcast (i64* @_ZGVN5test31AIiE1xE to i8*)
|
||||
// CHECK-NEXT: br label
|
||||
// CHECK: ret void
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user