summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2011-09-22 23:41:28 +0000
committerEli Friedman <eli.friedman@gmail.com>2011-09-22 23:41:28 +0000
commita6176adc8aad5d37268f40e49ae58c0eae2323c2 (patch)
tree360347d149dd955dcfa4e6a6da041a0be097751f
parent40eda4626df06066006e60f25ee8868d3f70162c (diff)
downloadllvm-a6176adc8aad5d37268f40e49ae58c0eae2323c2.tar.gz
llvm-a6176adc8aad5d37268f40e49ae58c0eae2323c2.tar.bz2
llvm-a6176adc8aad5d37268f40e49ae58c0eae2323c2.tar.xz
PR10991: make fast-isel correctly check whether accessing a global through an alias involves thread-local storage. (I'm not entirely sure how this is supposed to work, but this patch makes fast-isel consistent with the normal isel path.)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140355 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/X86FastISel.cpp12
-rw-r--r--test/CodeGen/X86/fast-isel-tls.ll18
2 files changed, 28 insertions, 2 deletions
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index 457b74250c..aafa96389a 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<GlobalValue>(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<GlobalVariable>(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<GlobalAlias>(GV))
+ if (const GlobalVariable *GVar =
+ dyn_cast_or_null<GlobalVariable>(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 a5e6642e09..0963c5201c 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