mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-25 20:59:51 +00:00
For general dynamic TLS access we must use
leaq foo@TLSGD(%rip), %rdi as part of the instruction sequence. Using a register other than %rdi and then copying it to %rdi is not valid. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69350 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c3a76ef955
commit
2ee3db3003
@ -4754,6 +4754,23 @@ X86TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) {
|
||||
return LowerGlobalAddress(GV, Op.getDebugLoc(), Offset, DAG);
|
||||
}
|
||||
|
||||
static SDValue
|
||||
GetTLSADDR(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA,
|
||||
SDValue *InFlag) {
|
||||
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
|
||||
DebugLoc dl = GA->getDebugLoc();
|
||||
SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(),
|
||||
GA->getValueType(0),
|
||||
GA->getOffset());
|
||||
if (InFlag) {
|
||||
SDValue Ops[] = { Chain, TGA, *InFlag };
|
||||
return DAG.getNode(X86ISD::TLSADDR, dl, NodeTys, Ops, 3);
|
||||
} else {
|
||||
SDValue Ops[] = { Chain, TGA };
|
||||
return DAG.getNode(X86ISD::TLSADDR, dl, NodeTys, Ops, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 32 bit
|
||||
static SDValue
|
||||
LowerToTLSGeneralDynamicModel32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
|
||||
@ -4766,22 +4783,10 @@ LowerToTLSGeneralDynamicModel32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
|
||||
PtrVT), InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
// emit leal symbol@TLSGD(,%ebx,1), %eax
|
||||
SDVTList NodeTys = DAG.getVTList(PtrVT, MVT::Other, MVT::Flag);
|
||||
SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(),
|
||||
GA->getValueType(0),
|
||||
GA->getOffset());
|
||||
SDValue Ops[] = { Chain, TGA, InFlag };
|
||||
SDValue Result = DAG.getNode(X86ISD::TLSADDR, dl, NodeTys, Ops, 3);
|
||||
InFlag = Result.getValue(2);
|
||||
Chain = Result.getValue(1);
|
||||
|
||||
// call ___tls_get_addr. This function receives its argument in
|
||||
// the register EAX.
|
||||
Chain = DAG.getCopyToReg(Chain, dl, X86::EAX, Result, InFlag);
|
||||
Chain = GetTLSADDR(DAG, Chain, GA, &InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
|
||||
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
|
||||
SDValue Ops1[] = { Chain,
|
||||
DAG.getTargetExternalSymbol("___tls_get_addr",
|
||||
PtrVT),
|
||||
@ -4801,22 +4806,10 @@ LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
|
||||
SDValue InFlag, Chain;
|
||||
DebugLoc dl = GA->getDebugLoc(); // ? function entry point might be better
|
||||
|
||||
// emit leaq symbol@TLSGD(%rip), %rdi
|
||||
SDVTList NodeTys = DAG.getVTList(PtrVT, MVT::Other, MVT::Flag);
|
||||
SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(),
|
||||
GA->getValueType(0),
|
||||
GA->getOffset());
|
||||
SDValue Ops[] = { DAG.getEntryNode(), TGA};
|
||||
SDValue Result = DAG.getNode(X86ISD::TLSADDR, dl, NodeTys, Ops, 2);
|
||||
Chain = Result.getValue(1);
|
||||
InFlag = Result.getValue(2);
|
||||
|
||||
// call __tls_get_addr. This function receives its argument in
|
||||
// the register RDI.
|
||||
Chain = DAG.getCopyToReg(Chain, dl, X86::RDI, Result, InFlag);
|
||||
Chain = GetTLSADDR(DAG, DAG.getEntryNode(), GA, NULL);
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
|
||||
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
|
||||
SDValue Ops1[] = { Chain,
|
||||
DAG.getTargetExternalSymbol("__tls_get_addr",
|
||||
PtrVT),
|
||||
|
@ -1303,9 +1303,11 @@ def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64i32imm:$src),
|
||||
// Thread Local Storage Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def TLS_addr64 : I<0, Pseudo, (outs GR64:$dst), (ins i64imm:$sym),
|
||||
".byte\t0x66; leaq\t${sym:mem}(%rip), $dst; .word\t0x6666; rex64",
|
||||
[(set GR64:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>;
|
||||
let hasSideEffects = 1, Uses = [RDI] in
|
||||
def TLS_addr64 : I<0, Pseudo, (outs), (ins i64imm:$sym),
|
||||
".byte\t0x66; leaq\t${sym:mem}(%rip), %rdi; .word\t0x6666; rex64",
|
||||
[(X86tlsaddr tglobaltlsaddr:$sym)]>,
|
||||
Requires<[In64BitMode]>;
|
||||
|
||||
let AddedComplexity = 5 in
|
||||
def MOV64GSrm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
|
||||
|
@ -63,7 +63,7 @@ def SDTX86RdTsc : SDTypeProfile<0, 0, []>;
|
||||
|
||||
def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
|
||||
|
||||
def SDT_X86TLSADDR : SDTypeProfile<1, 1, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
|
||||
def SDT_X86TLSADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
|
||||
|
||||
def SDT_X86SegmentBaseAddress : SDTypeProfile<1, 1, [SDTCisPtrTy<0>]>;
|
||||
|
||||
@ -2977,10 +2977,11 @@ def MOV32r0 : I<0x31, MRMInitReg, (outs GR32:$dst), (ins),
|
||||
// Thread Local Storage Instructions
|
||||
//
|
||||
|
||||
let Uses = [EBX] in
|
||||
def TLS_addr32 : I<0, Pseudo, (outs GR32:$dst), (ins i32imm:$sym),
|
||||
"leal\t${sym:mem}(,%ebx,1), $dst",
|
||||
[(set GR32:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>;
|
||||
let hasSideEffects = 1, Uses = [EAX, EBX] in
|
||||
def TLS_addr32 : I<0, Pseudo, (outs), (ins i32imm:$sym),
|
||||
"leal\t${sym:mem}(,%ebx,1), %eax",
|
||||
[(X86tlsaddr tglobaltlsaddr:$sym)]>,
|
||||
Requires<[In32BitMode]>;
|
||||
|
||||
let AddedComplexity = 5 in
|
||||
def GS_MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
|
||||
|
17
test/CodeGen/X86/2009-04-17-tls-fast.ll
Normal file
17
test/CodeGen/X86/2009-04-17-tls-fast.ll
Normal file
@ -0,0 +1,17 @@
|
||||
; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu -relocation-model=pic -regalloc=local > %t
|
||||
; RUN: grep {leaq foo@TLSGD(%rip), %rdi} %t
|
||||
|
||||
@foo = internal thread_local global i32 100
|
||||
|
||||
define void @f(i32 %n) nounwind {
|
||||
entry:
|
||||
%n_addr = alloca i32
|
||||
%p = alloca i32*
|
||||
%"alloca point" = bitcast i32 0 to i32
|
||||
store i32 %n, i32* %n_addr
|
||||
store i32* @foo, i32** %p, align 8
|
||||
br label %return
|
||||
|
||||
return:
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue
Block a user