diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index 457b74250c8..aafa96389ac 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -22,6 +22,7 @@ #include "llvm/CallingConv.h" #include "llvm/DerivedTypes.h" #include "llvm/GlobalVariable.h" +#include "llvm/GlobalAlias.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" #include "llvm/Operator.h" @@ -467,14 +468,23 @@ bool X86FastISel::X86SelectAddress(const Value *V, X86AddressMode &AM) { // Handle constant address. if (const GlobalValue *GV = dyn_cast(V)) { - // Can't handle alternate code models or TLS yet. + // Can't handle alternate code models yet. if (TM.getCodeModel() != CodeModel::Small) return false; + // Can't handle TLS yet. if (const GlobalVariable *GVar = dyn_cast(GV)) if (GVar->isThreadLocal()) return false; + // Can't handle TLS yet, part 2 (this is slightly crazy, but this is how + // it works...). + if (const GlobalAlias *GA = dyn_cast(GV)) + if (const GlobalVariable *GVar = + dyn_cast_or_null(GA->resolveAliasedGlobal(false))) + if (GVar->isThreadLocal()) + return false; + // RIP-relative addresses can't have additional register operands, so if // we've already folded stuff into the addressing mode, just force the // global value into its own register, which we can use as the basereg. diff --git a/test/CodeGen/X86/fast-isel-tls.ll b/test/CodeGen/X86/fast-isel-tls.ll index a5e6642e09c..0963c5201c2 100644 --- a/test/CodeGen/X86/fast-isel-tls.ll +++ b/test/CodeGen/X86/fast-isel-tls.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 -relocation-model=pic -mtriple=i686-unknown-linux-gnu -fast-isel | grep __tls_get_addr +; RUN: llc < %s -march=x86 -relocation-model=pic -mtriple=i686-unknown-linux-gnu -fast-isel | FileCheck %s ; PR3654 @v = thread_local global i32 0 @@ -8,3 +8,19 @@ entry: %s = add i32 %t, 1 ret i32 %s } + +; CHECK: f: +; CHECK: leal v@TLSGD +; CHECK: __tls_get_addr + +@alias = alias internal i32* @v +define i32 @f_alias() nounwind { +entry: + %t = load i32* @v + %s = add i32 %t, 1 + ret i32 %s +} + +; CHECK: f_alias: +; CHECK: leal v@TLSGD +; CHECK: __tls_get_addr