[llvm-branch-commits] [llvm] 29c8ea6 - [X86] Handle localdynamic TLS model in x32 mode
Harald van Dijk via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Dec 8 13:10:21 PST 2020
Author: Harald van Dijk
Date: 2020-12-08T21:06:00Z
New Revision: 29c8ea6f1abd6606b65dafd3db8f15c8104c2593
URL: https://github.com/llvm/llvm-project/commit/29c8ea6f1abd6606b65dafd3db8f15c8104c2593
DIFF: https://github.com/llvm/llvm-project/commit/29c8ea6f1abd6606b65dafd3db8f15c8104c2593.diff
LOG: [X86] Handle localdynamic TLS model in x32 mode
D92346 added TLS_(base_)addrX32 to handle TLS in x32 mode, but missed the
different TLS models. This diff fixes the logic for the local dynamic model
where `RAX` was used when `EAX` should be, and extends the tests to cover
all four TLS models.
Fixes https://bugs.llvm.org/show_bug.cgi?id=26472.
Reviewed By: RKSimon
Differential Revision: https://reviews.llvm.org/D92737
Added:
Modified:
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/pic.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index e97f4b12323d6..e437b9291148d 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -19142,9 +19142,8 @@ LowerToTLSGeneralDynamicModelX32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
}
static SDValue LowerToTLSLocalDynamicModel(GlobalAddressSDNode *GA,
- SelectionDAG &DAG,
- const EVT PtrVT,
- bool is64Bit) {
+ SelectionDAG &DAG, const EVT PtrVT,
+ bool Is64Bit, bool Is64BitLP64) {
SDLoc dl(GA);
// Get the start address of the TLS block for this module.
@@ -19153,8 +19152,9 @@ static SDValue LowerToTLSLocalDynamicModel(GlobalAddressSDNode *GA,
MFI->incNumLocalDynamicTLSAccesses();
SDValue Base;
- if (is64Bit) {
- Base = GetTLSADDR(DAG, DAG.getEntryNode(), GA, nullptr, PtrVT, X86::RAX,
+ if (Is64Bit) {
+ unsigned ReturnReg = Is64BitLP64 ? X86::RAX : X86::EAX;
+ Base = GetTLSADDR(DAG, DAG.getEntryNode(), GA, nullptr, PtrVT, ReturnReg,
X86II::MO_TLSLD, /*LocalDynamic=*/true);
} else {
SDValue InFlag;
@@ -19258,8 +19258,8 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
}
return LowerToTLSGeneralDynamicModel32(GA, DAG, PtrVT);
case TLSModel::LocalDynamic:
- return LowerToTLSLocalDynamicModel(GA, DAG, PtrVT,
- Subtarget.is64Bit());
+ return LowerToTLSLocalDynamicModel(GA, DAG, PtrVT, Subtarget.is64Bit(),
+ Subtarget.isTarget64BitLP64());
case TLSModel::InitialExec:
case TLSModel::LocalExec:
return LowerToTLSExecModel(GA, DAG, PtrVT, model, Subtarget.is64Bit(),
diff --git a/llvm/test/CodeGen/X86/pic.ll b/llvm/test/CodeGen/X86/pic.ll
index c936333a5726a..3f3417e89ad81 100644
--- a/llvm/test/CodeGen/X86/pic.ll
+++ b/llvm/test/CodeGen/X86/pic.ll
@@ -254,15 +254,24 @@ declare void @foo4(...)
declare void @foo5(...)
;; Check TLS references
- at tlsptr = external thread_local global i32*
- at tlsdst = external thread_local global i32
- at tlssrc = external thread_local global i32
+ at tlsptrgd = thread_local global i32* null
+ at tlsdstgd = thread_local global i32 0
+ at tlssrcgd = thread_local global i32 0
+ at tlsptrld = thread_local(localdynamic) global i32* null
+ at tlsdstld = thread_local(localdynamic) global i32 0
+ at tlssrcld = thread_local(localdynamic) global i32 0
+ at tlsptrie = thread_local(initialexec) global i32* null
+ at tlsdstie = thread_local(initialexec) global i32 0
+ at tlssrcie = thread_local(initialexec) global i32 0
+ at tlsptrle = thread_local(localexec) global i32* null
+ at tlsdstle = thread_local(localexec) global i32 0
+ at tlssrcle = thread_local(localexec) global i32 0
define void @test8() nounwind {
entry:
- store i32* @tlsdst, i32** @tlsptr
- %tmp.s = load i32, i32* @tlssrc
- store i32 %tmp.s, i32* @tlsdst
+ store i32* @tlsdstgd, i32** @tlsptrgd
+ %tmp.s = load i32, i32* @tlssrcgd
+ store i32 %tmp.s, i32* @tlsdstgd
ret void
; CHECK-LABEL: test8:
@@ -270,18 +279,95 @@ entry:
; CHECK-I686-NEXT: .L8$pb:
; CHECK-I686-NEXT: popl
; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L8$pb), %ebx
-; CHECK-I686-DAG: leal tlsdst at TLSGD(,%ebx), %eax
+; CHECK-I686-DAG: leal tlsdstgd at TLSGD(,%ebx), %eax
; CHECK-I686-DAG: calll ___tls_get_addr at PLT
-; CHECK-I686-DAG: leal tlsptr at TLSGD(,%ebx), %eax
+; CHECK-I686-DAG: leal tlsptrgd at TLSGD(,%ebx), %eax
; CHECK-I686-DAG: calll ___tls_get_addr at PLT
-; CHECK-I686-DAG: leal tlssrc at TLSGD(,%ebx), %eax
+; CHECK-I686-DAG: leal tlssrcgd at TLSGD(,%ebx), %eax
; CHECK-I686-DAG: calll ___tls_get_addr at PLT
-; CHECK-X32-DAG: leaq tlsdst at TLSGD(%rip), %rdi
+; CHECK-X32-DAG: leaq tlsdstgd at TLSGD(%rip), %rdi
; CHECK-X32-DAG: callq __tls_get_addr at PLT
-; CHECK-X32-DAG: leaq tlsptr at TLSGD(%rip), %rdi
+; CHECK-X32-DAG: leaq tlsptrgd at TLSGD(%rip), %rdi
; CHECK-X32-DAG: callq __tls_get_addr at PLT
-; CHECK-X32-DAG: leaq tlssrc at TLSGD(%rip), %rdi
+; CHECK-X32-DAG: leaq tlssrcgd at TLSGD(%rip), %rdi
; CHECK-X32-DAG: callq __tls_get_addr at PLT
; CHECK-I686: ret
; CHECK-X32: retq
}
+
+define void @test9() nounwind {
+entry:
+ store i32* @tlsdstld, i32** @tlsptrld
+ %tmp.s = load i32, i32* @tlssrcld
+ store i32 %tmp.s, i32* @tlsdstld
+ ret void
+
+; CHECK-LABEL: test9:
+; CHECK-I686: calll .L9$pb
+; CHECK-I686-NEXT: .L9$pb:
+; CHECK-I686-NEXT: popl
+; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L9$pb), %ebx
+; CHECK-I686: leal tlsdstld at TLSLDM(%ebx), %eax
+; CHECK-X32: leaq tlsdstld at TLSLD(%rip), %rdi
+; CHECK-I686: calll ___tls_get_addr at PLT
+; CHECK-X32: callq __tls_get_addr at PLT
+; CHECK: leal tlsdstld at DTPOFF(
+; CHECK: movl {{%.*}}, tlsptrld at DTPOFF(
+; CHECK: movl tlssrcld at DTPOFF(
+; CHECK: movl {{%.*}}, tlsdstld at DTPOFF(
+; CHECK-I686: ret
+; CHECK-X32: retq
+}
+
+define void @test10() nounwind {
+entry:
+ store i32* @tlsdstie, i32** @tlsptrie
+ %tmp.s = load i32, i32* @tlssrcie
+ store i32 %tmp.s, i32* @tlsdstie
+ ret void
+
+; CHECK-LABEL: test10:
+; CHECK-I686: calll .L10$pb
+; CHECK-I686-NEXT: .L10$pb:
+; CHECK-I686-NEXT: popl
+; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L10$pb),
+; CHECK-I686-DAG: movl tlsdstie at GOTNTPOFF(
+; CHECK-I686-DAG: movl %gs:0,
+; CHECK-X32-DAG: movl tlsdstie at GOTTPOFF(%rip),
+; CHECK-X32-DAG: movl %fs:0,
+; CHECK: addl
+; CHECK-I686: movl tlsptrie at GOTNTPOFF(
+; CHECK-X32: movl tlsptrie at GOTTPOFF(%rip),
+; CHECK-I686: movl {{%.*}}, %gs:(
+; CHECK-X32: movl {{%.*}}, %fs:(
+; CHECK-I686: movl tlssrcie at GOTNTPOFF(
+; CHECK-X32: movl tlssrcie at GOTTPOFF(%rip),
+; CHECK-I686: movl %gs:(
+; CHECK-X32: movl %fs:(
+; CHECK-I686: movl {{%.*}}, %gs:(
+; CHECK-X32: movl {{%.*}}, %fs:(
+; CHECK-I686: ret
+; CHECK-X32: retq
+}
+
+define void @test11() nounwind {
+entry:
+ store i32* @tlsdstle, i32** @tlsptrle
+ %tmp.s = load i32, i32* @tlssrcle
+ store i32 %tmp.s, i32* @tlsdstle
+ ret void
+
+; CHECK-LABEL: test11:
+; CHECK-I686: movl %gs:0,
+; CHECK-X32: movl %fs:0,
+; CHECK-I686: leal tlsdstle at NTPOFF(
+; CHECK-X32: leal tlsdstle at TPOFF(
+; CHECK-I686: movl {{%.*}}, %gs:tlsptrle at NTPOFF
+; CHECK-X32: movl {{%.*}}, %fs:tlsptrle at TPOFF
+; CHECK-I686: movl %gs:tlssrcle at NTPOFF,
+; CHECK-X32: movl %fs:tlssrcle at TPOFF,
+; CHECK-I686: movl {{%.*}}, %gs:tlsdstle at NTPOFF
+; CHECK-X32: movl {{%.*}}, %fs:tlsdstle at TPOFF
+; CHECK-I686: ret
+; CHECK-X32: retq
+}
More information about the llvm-branch-commits
mailing list