Use alias linkage and visibility to decide tls access mode.
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 23 May 2014 19:16:56 +0000 (19:16 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 23 May 2014 19:16:56 +0000 (19:16 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209543 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/TargetMachine.cpp
test/CodeGen/Mips/tls-alias.ll
test/CodeGen/X86/2008-03-12-ThreadLocalAlias.ll

index dbd433d5240c0afe4de031a24b250e39dc64449f..8365f64dc54acae7478386296a19f8de17fc8e18 100644 (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;
   }
 
-  // If the user specified a more specific model, use that.
-  TLSModel::Model SelectedModel = getSelectedTLSModel(Var);
-  if (SelectedModel > Model)
-    return SelectedModel;
+  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;
 }
index 3c810542cca31daef7b108c0b47b589fa5158876..80fbe87a8d61b95521fd212e0e21ade8ef2d4b95 100644 (file)
@@ -5,6 +5,6 @@
 
 define i32* @zed() {
 ; CHECK-DAG: __tls_get_addr
-; CHECK-DAG: %tlsgd(bar)
+; CHECK-DAG: %tlsldm(bar)
        ret i32* @bar
 }
index 6052c102af61edb7f5c3e70eeae01a515f2a59b7..e64375a2b361a04fec16667152c2be71b168ae26 100644 (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]