Skip to content

Commit

Permalink
[X86] Add TLS_(base_)addrX32 for X32 mode
Browse files Browse the repository at this point in the history
LLVM has TLS_(base_)addr32 for 32-bit TLS addresses in 32-bit mode, and
TLS_(base_)addr64 for 64-bit TLS addresses in 64-bit mode. x32 mode wants 32-bit
TLS addresses in 64-bit mode, which were not yet handled. This adds
TLS_(base_)addrX32 as copies of TLS_(base_)addr64, except that they use
tls32(base)addr rather than tls64(base)addr, and then restricts
TLS_(base_)addr64 to 64-bit LP64 mode, TLS_(base_)addrX32 to 64-bit ILP32 mode.

Reviewed By: RKSimon

Differential Revision: https://reviews.llvm.org/D92346
  • Loading branch information
hvdijk committed Dec 2, 2020
1 parent 18ce612 commit c9be4ef
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 7 deletions.
19 changes: 16 additions & 3 deletions llvm/lib/Target/X86/X86ISelLowering.cpp
Expand Up @@ -19123,14 +19123,22 @@ LowerToTLSGeneralDynamicModel32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
return GetTLSADDR(DAG, Chain, GA, &InFlag, PtrVT, X86::EAX, X86II::MO_TLSGD);
}

// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit
// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit LP64
static SDValue
LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
const EVT PtrVT) {
return GetTLSADDR(DAG, DAG.getEntryNode(), GA, nullptr, PtrVT,
X86::RAX, X86II::MO_TLSGD);
}

// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit ILP32
static SDValue
LowerToTLSGeneralDynamicModelX32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
const EVT PtrVT) {
return GetTLSADDR(DAG, DAG.getEntryNode(), GA, nullptr, PtrVT,
X86::EAX, X86II::MO_TLSGD);
}

static SDValue LowerToTLSLocalDynamicModel(GlobalAddressSDNode *GA,
SelectionDAG &DAG,
const EVT PtrVT,
Expand Down Expand Up @@ -19241,8 +19249,11 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
TLSModel::Model model = DAG.getTarget().getTLSModel(GV);
switch (model) {
case TLSModel::GeneralDynamic:
if (Subtarget.is64Bit())
return LowerToTLSGeneralDynamicModel64(GA, DAG, PtrVT);
if (Subtarget.is64Bit()) {
if (Subtarget.isTarget64BitLP64())
return LowerToTLSGeneralDynamicModel64(GA, DAG, PtrVT);
return LowerToTLSGeneralDynamicModelX32(GA, DAG, PtrVT);
}
return LowerToTLSGeneralDynamicModel32(GA, DAG, PtrVT);
case TLSModel::LocalDynamic:
return LowerToTLSLocalDynamicModel(GA, DAG, PtrVT,
Expand Down Expand Up @@ -33511,8 +33522,10 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
default: llvm_unreachable("Unexpected instr type to insert");
case X86::TLS_addr32:
case X86::TLS_addr64:
case X86::TLS_addrX32:
case X86::TLS_base_addr32:
case X86::TLS_base_addr64:
case X86::TLS_base_addrX32:
return EmitLoweredTLSAddr(MI, BB);
case X86::INDIRECT_THUNK_CALL32:
case X86::INDIRECT_THUNK_CALL64:
Expand Down
12 changes: 10 additions & 2 deletions llvm/lib/Target/X86/X86InstrCompiler.td
Expand Up @@ -467,11 +467,19 @@ let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
def TLS_addr64 : I<0, Pseudo, (outs), (ins i64mem:$sym),
"# TLS_addr64",
[(X86tlsaddr tls64addr:$sym)]>,
Requires<[In64BitMode]>;
Requires<[In64BitMode, IsLP64]>;
def TLS_base_addr64 : I<0, Pseudo, (outs), (ins i64mem:$sym),
"# TLS_base_addr64",
[(X86tlsbaseaddr tls64baseaddr:$sym)]>,
Requires<[In64BitMode]>;
Requires<[In64BitMode, IsLP64]>;
def TLS_addrX32 : I<0, Pseudo, (outs), (ins i32mem:$sym),
"# TLS_addrX32",
[(X86tlsaddr tls32addr:$sym)]>,
Requires<[In64BitMode, NotLP64]>;
def TLS_base_addrX32 : I<0, Pseudo, (outs), (ins i32mem:$sym),
"# TLS_base_addrX32",
[(X86tlsbaseaddr tls32baseaddr:$sym)]>,
Requires<[In64BitMode, NotLP64]>;
}

// Darwin TLS Support
Expand Down
8 changes: 6 additions & 2 deletions llvm/lib/Target/X86/X86MCInstLower.cpp
Expand Up @@ -977,20 +977,22 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
void X86AsmPrinter::LowerTlsAddr(X86MCInstLower &MCInstLowering,
const MachineInstr &MI) {
NoAutoPaddingScope NoPadScope(*OutStreamer);
bool Is64Bits = MI.getOpcode() == X86::TLS_addr64 ||
MI.getOpcode() == X86::TLS_base_addr64;
bool Is64Bits = MI.getOpcode() != X86::TLS_addr32 &&
MI.getOpcode() != X86::TLS_base_addr32;
MCContext &Ctx = OutStreamer->getContext();

MCSymbolRefExpr::VariantKind SRVK;
switch (MI.getOpcode()) {
case X86::TLS_addr32:
case X86::TLS_addr64:
case X86::TLS_addrX32:
SRVK = MCSymbolRefExpr::VK_TLSGD;
break;
case X86::TLS_base_addr32:
SRVK = MCSymbolRefExpr::VK_TLSLDM;
break;
case X86::TLS_base_addr64:
case X86::TLS_base_addrX32:
SRVK = MCSymbolRefExpr::VK_TLSLD;
break;
default:
Expand Down Expand Up @@ -2445,8 +2447,10 @@ void X86AsmPrinter::emitInstruction(const MachineInstr *MI) {

case X86::TLS_addr32:
case X86::TLS_addr64:
case X86::TLS_addrX32:
case X86::TLS_base_addr32:
case X86::TLS_base_addr64:
case X86::TLS_base_addrX32:
return LowerTlsAddr(MCInstLowering, *MI);

case X86::MOVPC32r: {
Expand Down
33 changes: 33 additions & 0 deletions llvm/test/CodeGen/X86/pic.ll
Expand Up @@ -252,3 +252,36 @@ declare void @foo6(...)
declare void @foo3(...)
declare void @foo4(...)
declare void @foo5(...)

;; Check TLS references
@tlsptr = external thread_local global i32*
@tlsdst = external thread_local global i32
@tlssrc = external thread_local global i32

define void @test8() nounwind {
entry:
store i32* @tlsdst, i32** @tlsptr
%tmp.s = load i32, i32* @tlssrc
store i32 %tmp.s, i32* @tlsdst
ret void

; CHECK-LABEL: test8:
; CHECK-I686: calll .L8$pb
; CHECK-I686-NEXT: .L8$pb:
; CHECK-I686-NEXT: popl
; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L8$pb), %ebx
; CHECK-I686-DAG: leal tlsdst@TLSGD(,%ebx), %eax
; CHECK-I686-DAG: calll ___tls_get_addr@PLT
; CHECK-I686-DAG: leal tlsptr@TLSGD(,%ebx), %eax
; CHECK-I686-DAG: calll ___tls_get_addr@PLT
; CHECK-I686-DAG: leal tlssrc@TLSGD(,%ebx), %eax
; CHECK-I686-DAG: calll ___tls_get_addr@PLT
; CHECK-X32-DAG: leaq tlsdst@TLSGD(%rip), %rdi
; CHECK-X32-DAG: callq __tls_get_addr@PLT
; CHECK-X32-DAG: leaq tlsptr@TLSGD(%rip), %rdi
; CHECK-X32-DAG: callq __tls_get_addr@PLT
; CHECK-X32-DAG: leaq tlssrc@TLSGD(%rip), %rdi
; CHECK-X32-DAG: callq __tls_get_addr@PLT
; CHECK-I686: ret
; CHECK-X32: retq
}

0 comments on commit c9be4ef

Please sign in to comment.