forked from OSchip/llvm-project
CodeGen: Don't drop thread_local when emitting __thread aliases
CodeGen wouldn't mark the aliasee as thread_local if the aliasee was a tentative definition. Even if the definition was already emitted, it would never mark the alias as thread_local. This fixes PR21288. llvm-svn: 219859
This commit is contained in:
parent
0b15e34bd1
commit
bb525f7c20
|
@ -523,11 +523,10 @@ static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(
|
|||
llvm_unreachable("Invalid TLS model!");
|
||||
}
|
||||
|
||||
void CodeGenModule::setTLSMode(llvm::GlobalVariable *GV,
|
||||
const VarDecl &D) const {
|
||||
void CodeGenModule::setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const {
|
||||
assert(D.getTLSKind() && "setting TLS mode on non-TLS var!");
|
||||
|
||||
llvm::GlobalVariable::ThreadLocalMode TLM;
|
||||
llvm::GlobalValue::ThreadLocalMode TLM;
|
||||
TLM = GetLLVMTLSModel(CodeGenOpts.getDefaultTLSModel());
|
||||
|
||||
// Override the TLS model if it is explicitly specified.
|
||||
|
@ -1942,10 +1941,9 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
|
|||
// has internal linkage; all accesses should just be calls to the
|
||||
// Itanium-specified entry point, which has the normal linkage of the
|
||||
// variable.
|
||||
if (const auto *VD = dyn_cast<VarDecl>(D))
|
||||
if (!VD->isStaticLocal() && VD->getTLSKind() == VarDecl::TLS_Dynamic &&
|
||||
Context.getTargetInfo().getTriple().isMacOSX())
|
||||
Linkage = llvm::GlobalValue::InternalLinkage;
|
||||
if (!D->isStaticLocal() && D->getTLSKind() == VarDecl::TLS_Dynamic &&
|
||||
Context.getTargetInfo().getTriple().isMacOSX())
|
||||
Linkage = llvm::GlobalValue::InternalLinkage;
|
||||
|
||||
GV->setLinkage(Linkage);
|
||||
if (D->hasAttr<DLLImportAttr>())
|
||||
|
@ -1959,6 +1957,12 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
|
|||
|
||||
setNonAliasAttributes(D, GV);
|
||||
|
||||
if (D->getTLSKind() && !GV->isThreadLocal()) {
|
||||
if (D->getTLSKind() == VarDecl::TLS_Dynamic)
|
||||
CXXThreadLocals.push_back(std::make_pair(D, GV));
|
||||
setTLSMode(GV, *D);
|
||||
}
|
||||
|
||||
// Emit the initializer function if necessary.
|
||||
if (NeedsGlobalCtor || NeedsGlobalDtor)
|
||||
EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor);
|
||||
|
@ -2326,7 +2330,7 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
|
|||
else
|
||||
Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
|
||||
llvm::PointerType::getUnqual(DeclTy),
|
||||
nullptr);
|
||||
/*D=*/nullptr);
|
||||
|
||||
// Create the new alias itself, but don't set a name yet.
|
||||
auto *GA = llvm::GlobalAlias::create(
|
||||
|
@ -2365,6 +2369,10 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
|
|||
GA->setLinkage(llvm::Function::WeakAnyLinkage);
|
||||
}
|
||||
|
||||
if (const auto *VD = dyn_cast<VarDecl>(D))
|
||||
if (VD->getTLSKind())
|
||||
setTLSMode(GA, *VD);
|
||||
|
||||
setAliasAttributes(D, GA);
|
||||
}
|
||||
|
||||
|
|
|
@ -652,9 +652,9 @@ public:
|
|||
/// Set the visibility for the given LLVM GlobalValue.
|
||||
void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const;
|
||||
|
||||
/// Set the TLS mode for the given LLVM GlobalVariable for the thread-local
|
||||
/// Set the TLS mode for the given LLVM GlobalValue for the thread-local
|
||||
/// variable declaration D.
|
||||
void setTLSMode(llvm::GlobalVariable *GV, const VarDecl &D) const;
|
||||
void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const;
|
||||
|
||||
static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V) {
|
||||
switch (V) {
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
int g0;
|
||||
// CHECKBASIC: @g0 = common global i32 0
|
||||
__thread int TL_WITH_ALIAS;
|
||||
// CHECKBASIC-DAG: @TL_WITH_ALIAS = thread_local global i32 0, align 4
|
||||
static int bar1 = 42;
|
||||
// CHECKBASIC: @bar1 = internal global i32 42
|
||||
|
||||
|
@ -10,6 +12,9 @@ extern int g1;
|
|||
extern int g1 __attribute((alias("g0")));
|
||||
// CHECKBASIC-DAG: @g1 = alias i32* @g0
|
||||
|
||||
extern __thread int __libc_errno __attribute__ ((alias ("TL_WITH_ALIAS")));
|
||||
// CHECKBASIC-DAG: @__libc_errno = thread_local alias i32* @TL_WITH_ALIAS
|
||||
|
||||
void f0(void) { }
|
||||
extern void f1(void);
|
||||
extern void f1(void) __attribute((alias("f0")));
|
||||
|
|
Loading…
Reference in New Issue