[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