forked from OSchip/llvm-project
[CodeGen][TLS] Set TLS Model for __tls_guard as well.
Differential Revision: https://reviews.llvm.org/D81543
This commit is contained in:
parent
0a5228a02c
commit
4a1776979f
|
@ -971,9 +971,9 @@ static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(StringRef S) {
|
|||
.Case("local-exec", llvm::GlobalVariable::LocalExecTLSModel);
|
||||
}
|
||||
|
||||
static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(
|
||||
CodeGenOptions::TLSModel M) {
|
||||
switch (M) {
|
||||
llvm::GlobalVariable::ThreadLocalMode
|
||||
CodeGenModule::GetDefaultLLVMTLSModel() const {
|
||||
switch (CodeGenOpts.getDefaultTLSModel()) {
|
||||
case CodeGenOptions::GeneralDynamicTLSModel:
|
||||
return llvm::GlobalVariable::GeneralDynamicTLSModel;
|
||||
case CodeGenOptions::LocalDynamicTLSModel:
|
||||
|
@ -990,7 +990,7 @@ void CodeGenModule::setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const {
|
|||
assert(D.getTLSKind() && "setting TLS mode on non-TLS var!");
|
||||
|
||||
llvm::GlobalValue::ThreadLocalMode TLM;
|
||||
TLM = GetLLVMTLSModel(CodeGenOpts.getDefaultTLSModel());
|
||||
TLM = GetDefaultLLVMTLSModel();
|
||||
|
||||
// Override the TLS model if it is explicitly specified.
|
||||
if (const TLSModelAttr *Attr = D.getAttr<TLSModelAttr>()) {
|
||||
|
|
|
@ -790,6 +790,9 @@ public:
|
|||
/// variable declaration D.
|
||||
void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const;
|
||||
|
||||
/// Get LLVM TLS mode from CodeGenOptions.
|
||||
llvm::GlobalVariable::ThreadLocalMode GetDefaultLLVMTLSModel() const;
|
||||
|
||||
static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V) {
|
||||
switch (V) {
|
||||
case DefaultVisibility: return llvm::GlobalValue::DefaultVisibility;
|
||||
|
|
|
@ -2687,6 +2687,7 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
|
|||
llvm::GlobalVariable::InternalLinkage,
|
||||
llvm::ConstantInt::get(CGM.Int8Ty, 0), "__tls_guard");
|
||||
Guard->setThreadLocal(true);
|
||||
Guard->setThreadLocalMode(CGM.GetDefaultLLVMTLSModel());
|
||||
|
||||
CharUnits GuardAlign = CharUnits::One();
|
||||
Guard->setAlignment(GuardAlign.getAsAlign());
|
||||
|
|
|
@ -2523,7 +2523,7 @@ void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
|
|||
GuardVar->setComdat(
|
||||
CGM.getModule().getOrInsertComdat(GuardVar->getName()));
|
||||
if (D.getTLSKind())
|
||||
GuardVar->setThreadLocal(true);
|
||||
CGM.setTLSMode(GuardVar, D);
|
||||
if (GI && !HasPerVariableGuard)
|
||||
GI->Guard = GuardVar;
|
||||
}
|
||||
|
|
|
@ -16,29 +16,52 @@ int f() {
|
|||
}
|
||||
int __thread __attribute__((tls_model("initial-exec"))) z;
|
||||
|
||||
struct S {
|
||||
S();
|
||||
~S();
|
||||
};
|
||||
struct T {
|
||||
~T();
|
||||
};
|
||||
|
||||
struct S thread_local s1;
|
||||
struct T thread_local t1;
|
||||
|
||||
// Note that unlike normal C uninitialized global variables,
|
||||
// uninitialized TLS variables do NOT have COMMON linkage.
|
||||
|
||||
// CHECK-GD: @z1 = global i32 0
|
||||
// CHECK-GD: @f.y = internal thread_local global i32 0
|
||||
// CHECK-GD: @z2 = global i32 0
|
||||
// CHECK-GD: @x = thread_local global i32 0
|
||||
// CHECK-GD: @_ZZ1fvE1y = internal thread_local global i32 0
|
||||
// CHECK-GD: @z = thread_local(initialexec) global i32 0
|
||||
// CHECK-GD: @s1 = thread_local global %struct.S zeroinitializer
|
||||
// CHECK-GD: @t1 = thread_local global %struct.T zeroinitializer
|
||||
// CHECK-GD: @__tls_guard = internal thread_local global i8 0
|
||||
|
||||
// CHECK-LD: @z1 = global i32 0
|
||||
// CHECK-LD: @f.y = internal thread_local(localdynamic) global i32 0
|
||||
// CHECK-LD: @z2 = global i32 0
|
||||
// CHECK-LD: @x = thread_local(localdynamic) global i32 0
|
||||
// CHECK-LD: @_ZZ1fvE1y = internal thread_local(localdynamic) global i32 0
|
||||
// CHECK-LD: @z = thread_local(initialexec) global i32 0
|
||||
// CHECK-LD: @s1 = thread_local(localdynamic) global %struct.S zeroinitializer
|
||||
// CHECK-LD: @t1 = thread_local(localdynamic) global %struct.T zeroinitializer
|
||||
// CHECK-LD: @__tls_guard = internal thread_local(localdynamic) global i8 0
|
||||
|
||||
// CHECK-IE: @z1 = global i32 0
|
||||
// CHECK-IE: @f.y = internal thread_local(initialexec) global i32 0
|
||||
// CHECK-IE: @z2 = global i32 0
|
||||
// CHECK-IE: @x = thread_local(initialexec) global i32 0
|
||||
// CHECK-IE: @_ZZ1fvE1y = internal thread_local(initialexec) global i32 0
|
||||
// CHECK-IE: @z = thread_local(initialexec) global i32 0
|
||||
// CHECK-IE: @s1 = thread_local(initialexec) global %struct.S zeroinitializer
|
||||
// CHECK-IE: @t1 = thread_local(initialexec) global %struct.T zeroinitializer
|
||||
// CHECK-IE: @__tls_guard = internal thread_local(initialexec) global i8 0
|
||||
|
||||
// CHECK-LE: @z1 = global i32 0
|
||||
// CHECK-LE: @f.y = internal thread_local(localexec) global i32 0
|
||||
// CHECK-LE: @z2 = global i32 0
|
||||
// CHECK-LE: @x = thread_local(localexec) global i32 0
|
||||
// CHECK-LE: @_ZZ1fvE1y = internal thread_local(localexec) global i32 0
|
||||
// CHECK-LE: @z = thread_local(initialexec) global i32 0
|
||||
// CHECK-LE: @s1 = thread_local(localexec) global %struct.S zeroinitializer
|
||||
// CHECK-LE: @t1 = thread_local(localexec) global %struct.T zeroinitializer
|
||||
// CHECK-LE: @__tls_guard = internal thread_local(localexec) global i8 0
|
|
@ -1,4 +1,5 @@
|
|||
// RUN: %clang_cc1 %s -std=c++1y -triple=i686-pc-win32 -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -std=c++1y -triple=i686-pc-win32 -ftls-model=local-dynamic -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-LD
|
||||
|
||||
struct A {
|
||||
A();
|
||||
|
@ -8,15 +9,22 @@ struct A {
|
|||
// CHECK-DAG: $"??$a@X@@3UA@@A" = comdat any
|
||||
// CHECK-DAG: @"??$a@X@@3UA@@A" = linkonce_odr dso_local thread_local global %struct.A zeroinitializer, comdat, align 1
|
||||
// CHECK-DAG: @"??__E?$a@X@@YAXXZ$initializer$" = internal constant void ()* @"??__E?$a@X@@YAXXZ", section ".CRT$XDU", comdat($"??$a@X@@3UA@@A")
|
||||
// CHECK-LD-DAG: $"??$a@X@@3UA@@A" = comdat any
|
||||
// CHECK-LD-DAG: @"??$a@X@@3UA@@A" = linkonce_odr dso_local thread_local(localdynamic) global %struct.A zeroinitializer, comdat, align 1
|
||||
// CHECK-LD-DAG: @"??__E?$a@X@@YAXXZ$initializer$" = internal constant void ()* @"??__E?$a@X@@YAXXZ", section ".CRT$XDU", comdat($"??$a@X@@3UA@@A")
|
||||
template <typename T>
|
||||
thread_local A a = A();
|
||||
|
||||
// CHECK-DAG: @"?b@@3UA@@A" = dso_local thread_local global %struct.A zeroinitializer, align 1
|
||||
// CHECK-DAG: @"__tls_init$initializer$" = internal constant void ()* @__tls_init, section ".CRT$XDU"
|
||||
// CHECK-LD-DAG: @"?b@@3UA@@A" = dso_local thread_local(localdynamic) global %struct.A zeroinitializer, align 1
|
||||
// CHECK-LD-DAG: @"__tls_init$initializer$" = internal constant void ()* @__tls_init, section ".CRT$XDU"
|
||||
thread_local A b;
|
||||
|
||||
// CHECK-LABEL: define internal void @__tls_init()
|
||||
// CHECK: call void @"??__Eb@@YAXXZ"
|
||||
// CHECK-LD-LABEL: define internal void @__tls_init()
|
||||
// CHECK-LD: call void @"??__Eb@@YAXXZ"
|
||||
|
||||
thread_local A &c = b;
|
||||
thread_local A &d = c;
|
||||
|
@ -29,3 +37,5 @@ A f() {
|
|||
|
||||
// CHECK: !llvm.linker.options = !{![[dyn_tls_init:[0-9]+]]}
|
||||
// CHECK: ![[dyn_tls_init]] = !{!"/include:___dyn_tls_init@12"}
|
||||
// CHECK-LD: !llvm.linker.options = !{![[dyn_tls_init:[0-9]+]]}
|
||||
// CHECK-LD: ![[dyn_tls_init]] = !{!"/include:___dyn_tls_init@12"}
|
||||
|
|
Loading…
Reference in New Issue