[clang] 6b1e2fc - [FE] Manipulate the first byte of guard variable type in both load and store operation
Xiangling Liao via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 8 08:16:25 PST 2021
Author: Xiangling Liao
Date: 2021-02-08T11:14:34-05:00
New Revision: 6b1e2fc89327a64c9300d543e00f12435c32dfcf
URL: https://github.com/llvm/llvm-project/commit/6b1e2fc89327a64c9300d543e00f12435c32dfcf
DIFF: https://github.com/llvm/llvm-project/commit/6b1e2fc89327a64c9300d543e00f12435c32dfcf.diff
LOG: [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
Added:
Modified:
clang/lib/CodeGen/ItaniumCXXABI.cpp
clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
clang/test/CodeGenCXX/aix-static-init.cpp
clang/test/CodeGenCXX/cxx11-thread-local.cpp
clang/test/CodeGenCXX/global-init.cpp
clang/test/CodeGenCXX/static-data-member.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 50fb30a95cbb..b92801a516e9 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -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);
diff --git a/clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp b/clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
index f7e4c0a86b46..799b158bcf60 100644
--- a/clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
+++ b/clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
@@ -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:
diff --git a/clang/test/CodeGenCXX/aix-static-init.cpp b/clang/test/CodeGenCXX/aix-static-init.cpp
index f47329e99eee..dc0e9d39b7a3 100644
--- a/clang/test/CodeGenCXX/aix-static-init.cpp
+++ b/clang/test/CodeGenCXX/aix-static-init.cpp
@@ -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
diff --git a/clang/test/CodeGenCXX/cxx11-thread-local.cpp b/clang/test/CodeGenCXX/cxx11-thread-local.cpp
index 928ad9de4e6b..da200c61c5ea 100644
--- a/clang/test/CodeGenCXX/cxx11-thread-local.cpp
+++ b/clang/test/CodeGenCXX/cxx11-thread-local.cpp
@@ -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:.*]]()
diff --git a/clang/test/CodeGenCXX/global-init.cpp b/clang/test/CodeGenCXX/global-init.cpp
index 5752f549b1bf..f84ca3976324 100644
--- a/clang/test/CodeGenCXX/global-init.cpp
+++ b/clang/test/CodeGenCXX/global-init.cpp
@@ -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();
}
diff --git a/clang/test/CodeGenCXX/static-data-member.cpp b/clang/test/CodeGenCXX/static-data-member.cpp
index 6b352debf441..898fa21270c0 100644
--- a/clang/test/CodeGenCXX/static-data-member.cpp
+++ b/clang/test/CodeGenCXX/static-data-member.cpp
@@ -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
}
More information about the cfe-commits
mailing list