Fix PR 4004 by including the call to __tls_get_addr in X86tlsaddr. This is not
very elegant, but neither is the tls specification :-(
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69968 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index d51435c..5c9b7bf 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -4745,7 +4745,7 @@
static SDValue
GetTLSADDR(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA,
- SDValue *InFlag) {
+ SDValue *InFlag, const MVT PtrVT, unsigned ReturnReg) {
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
DebugLoc dl = GA->getDebugLoc();
SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(),
@@ -4753,11 +4753,13 @@
GA->getOffset());
if (InFlag) {
SDValue Ops[] = { Chain, TGA, *InFlag };
- return DAG.getNode(X86ISD::TLSADDR, dl, NodeTys, Ops, 3);
+ Chain = DAG.getNode(X86ISD::TLSADDR, dl, NodeTys, Ops, 3);
} else {
SDValue Ops[] = { Chain, TGA };
- return DAG.getNode(X86ISD::TLSADDR, dl, NodeTys, Ops, 2);
+ Chain = DAG.getNode(X86ISD::TLSADDR, dl, NodeTys, Ops, 2);
}
+ SDValue Flag = Chain.getValue(1);
+ return DAG.getCopyFromReg(Chain, dl, ReturnReg, PtrVT, Flag);
}
// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 32 bit
@@ -4772,42 +4774,14 @@
PtrVT), InFlag);
InFlag = Chain.getValue(1);
- Chain = GetTLSADDR(DAG, Chain, GA, &InFlag);
- InFlag = Chain.getValue(1);
-
- SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
- SDValue Ops1[] = { Chain,
- DAG.getTargetExternalSymbol("___tls_get_addr",
- PtrVT),
- DAG.getRegister(X86::EAX, PtrVT),
- DAG.getRegister(X86::EBX, PtrVT),
- InFlag };
- Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, Ops1, 5);
- InFlag = Chain.getValue(1);
-
- return DAG.getCopyFromReg(Chain, dl, X86::EAX, PtrVT, InFlag);
+ return GetTLSADDR(DAG, Chain, GA, &InFlag, PtrVT, X86::EAX);
}
// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit
static SDValue
LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
const MVT PtrVT) {
- SDValue InFlag, Chain;
- DebugLoc dl = GA->getDebugLoc(); // ? function entry point might be better
-
- Chain = GetTLSADDR(DAG, DAG.getEntryNode(), GA, NULL);
- InFlag = Chain.getValue(1);
-
- SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
- SDValue Ops1[] = { Chain,
- DAG.getTargetExternalSymbol("__tls_get_addr",
- PtrVT),
- DAG.getRegister(X86::RDI, PtrVT),
- InFlag };
- Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, Ops1, 4);
- InFlag = Chain.getValue(1);
-
- return DAG.getCopyFromReg(Chain, dl, X86::RAX, PtrVT, InFlag);
+ return GetTLSADDR(DAG, DAG.getEntryNode(), GA, NULL, PtrVT, X86::RAX);
}
// Lower ISD::GlobalTLSAddress using the "initial exec" (for no-pic) or
diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td
index e84d136..728811e 100644
--- a/lib/Target/X86/X86Instr64bit.td
+++ b/lib/Target/X86/X86Instr64bit.td
@@ -1303,9 +1303,17 @@
// Thread Local Storage Instructions
//===----------------------------------------------------------------------===//
-let hasSideEffects = 1, Defs = [RDI] in
+// All calls clobber the non-callee saved registers. RSP is marked as
+// a use to prevent stack-pointer assignments that appear immediately
+// before calls from potentially appearing dead.
+let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
+ FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, ST1,
+ MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
+ XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
+ XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
+ Uses = [RSP] in
def TLS_addr64 : I<0, Pseudo, (outs), (ins i64imm:$sym),
- ".byte\t0x66; leaq\t${sym:mem}(%rip), %rdi; .word\t0x6666; rex64",
+ ".byte\t0x66; leaq\t${sym:mem}(%rip), %rdi; .word\t0x6666; rex64;call\t__tls_get_addr@PLT",
[(X86tlsaddr tglobaltlsaddr:$sym)]>,
Requires<[In64BitMode]>;
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 462433b..3aa3447 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -2977,9 +2977,16 @@
// Thread Local Storage Instructions
//
-let hasSideEffects = 1, Uses = [EBX], Defs = [EAX] in
+// All calls clobber the non-callee saved registers. ESP is marked as
+// a use to prevent stack-pointer assignments that appear immediately
+// before calls from potentially appearing dead.
+let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
+ MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
+ XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
+ XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
+ Uses = [ESP, EBX] in
def TLS_addr32 : I<0, Pseudo, (outs), (ins i32imm:$sym),
- "leal\t${sym:mem}(,%ebx,1), %eax",
+ "leal\t${sym:mem}(,%ebx,1), %eax; call\t___tls_get_addr@PLT",
[(X86tlsaddr tglobaltlsaddr:$sym)]>,
Requires<[In32BitMode]>;