Use alias linkage and visibility to decide tls access mode.

This matches both what we do for the non-thread case and what gcc does.

With this patch clang would match gcc's behaviour in

static __thread int a = 42;
extern __thread int b __attribute__((alias("a")));
int *f(void) { return &a; }
int *g(void) { return &b; }

if not for pr19843. Manually writing the IL does produce the same access modes.

It is also a step in the direction of fixing pr19844.

llvm-svn: 209543
This commit is contained in:
Rafael Espindola 2014-05-23 19:16:56 +00:00
parent ffd8a3364c
commit a5bb2f61cf
3 changed files with 13 additions and 16 deletions

View File

@ -106,19 +106,13 @@ static TLSModel::Model getSelectedTLSModel(const GlobalVariable *Var) {
}
TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
// If GV is an alias then use the aliasee for determining
// thread-localness.
if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
GV = GA->getAliasee();
const GlobalVariable *Var = cast<GlobalVariable>(GV);
bool isLocal = Var->hasLocalLinkage();
bool isDeclaration = Var->isDeclaration();
bool isLocal = GV->hasLocalLinkage();
bool isDeclaration = GV->isDeclaration();
bool isPIC = getRelocationModel() == Reloc::PIC_;
bool isPIE = Options.PositionIndependentExecutable;
// FIXME: what should we do for protected and internal visibility?
// For variables, is internal different from hidden?
bool isHidden = Var->hasHiddenVisibility();
bool isHidden = GV->hasHiddenVisibility();
TLSModel::Model Model;
if (isPIC && !isPIE) {
@ -133,10 +127,13 @@ TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
Model = TLSModel::InitialExec;
}
const GlobalVariable *Var = dyn_cast<GlobalVariable>(GV);
if (Var) {
// If the user specified a more specific model, use that.
TLSModel::Model SelectedModel = getSelectedTLSModel(Var);
if (SelectedModel > Model)
return SelectedModel;
}
return Model;
}

View File

@ -5,6 +5,6 @@
define i32* @zed() {
; CHECK-DAG: __tls_get_addr
; CHECK-DAG: %tlsgd(bar)
; CHECK-DAG: %tlsldm(bar)
ret i32* @bar
}

View File

@ -12,7 +12,7 @@ target triple = "i386-pc-linux-gnu"
define i32 @foo() {
; CHECK-LABEL: foo:
; CHECK: leal __libc_resp@TLSGD
; CHECK: leal __libc_resp@TLSLD
entry:
%retval = alloca i32 ; <i32*> [#uses=1]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
@ -27,7 +27,7 @@ return: ; preds = %entry
define i32 @bar() {
; CHECK-LABEL: bar:
; CHECK: leal __libc_resp@TLSGD
; CHECK: leal __libc_resp@TLSLD
entry:
%retval = alloca i32 ; <i32*> [#uses=1]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]