Add llvm patches corresponding to r276300, r276301 and r276324.
This commit is contained in:
parent
c1ddc1e628
commit
55b7c2bcf9
21
contrib/llvm/patches/patch-26-llvm-r213890-ppc-eh_frame.diff
Normal file
21
contrib/llvm/patches/patch-26-llvm-r213890-ppc-eh_frame.diff
Normal file
@ -0,0 +1,21 @@
|
||||
Pull in r213890 from upstream llvm trunk (by Jörg Sonnenberger):
|
||||
|
||||
Use the same .eh_frame encoding for 32bit PPC as on i386.
|
||||
|
||||
This fixes DT_TEXTREL errors when linking C++ objects using exceptions
|
||||
on PowerPC.
|
||||
|
||||
Introduced here: http://svnweb.freebsd.org/changeset/base/276300
|
||||
|
||||
Index: lib/MC/MCObjectFileInfo.cpp
|
||||
===================================================================
|
||||
--- lib/MC/MCObjectFileInfo.cpp
|
||||
+++ lib/MC/MCObjectFileInfo.cpp
|
||||
@@ -287,6 +287,7 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Tri
|
||||
if (Ctx->getAsmInfo()->getExceptionHandlingType() == ExceptionHandling::ARM)
|
||||
break;
|
||||
// Fallthrough if not using EHABI
|
||||
+ case Triple::ppc:
|
||||
case Triple::x86:
|
||||
PersonalityEncoding = (RelocM == Reloc::PIC_)
|
||||
? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
|
504
contrib/llvm/patches/patch-27-llvm-r221703-ppc-tls_get_addr.diff
Normal file
504
contrib/llvm/patches/patch-27-llvm-r221703-ppc-tls_get_addr.diff
Normal file
@ -0,0 +1,504 @@
|
||||
Pull in r221703 from upstream llvm trunk (by Bill Schmidt):
|
||||
|
||||
[PowerPC] Replace foul hackery with real calls to __tls_get_addr
|
||||
|
||||
My original support for the general dynamic and local dynamic TLS
|
||||
models contained some fairly obtuse hacks to generate calls to
|
||||
__tls_get_addr when lowering a TargetGlobalAddress. Rather than
|
||||
generating real calls, special GET_TLS_ADDR nodes were used to wrap
|
||||
the calls and only reveal them at assembly time. I attempted to
|
||||
provide correct parameter and return values by chaining CopyToReg and
|
||||
CopyFromReg nodes onto the GET_TLS_ADDR nodes, but this was also not
|
||||
fully correct. Problems were seen with two back-to-back stores to TLS
|
||||
variables, where the call sequences ended up overlapping with unhappy
|
||||
results. Additionally, since these weren't real calls, the proper
|
||||
register side effects of a call were not recorded, so clobbered values
|
||||
were kept live across the calls.
|
||||
|
||||
The proper thing to do is to lower these into calls in the first
|
||||
place. This is relatively straightforward; see the changes to
|
||||
PPCTargetLowering::LowerGlobalTLSAddress() in PPCISelLowering.cpp.
|
||||
The changes here are standard call lowering, except that we need to
|
||||
track the fact that these calls will require a relocation. This is
|
||||
done by adding a machine operand flag of MO_TLSLD or MO_TLSGD to the
|
||||
TargetGlobalAddress operand that appears earlier in the sequence.
|
||||
|
||||
The calls to LowerCallTo() eventually find their way to
|
||||
LowerCall_64SVR4() or LowerCall_32SVR4(), which call FinishCall(),
|
||||
which calls PrepareCall(). In PrepareCall(), we detect the calls to
|
||||
__tls_get_addr and immediately snag the TargetGlobalTLSAddress with
|
||||
the annotated relocation information. This becomes an extra operand
|
||||
on the call following the callee, which is expected for nodes of type
|
||||
tlscall. We change the call opcode to CALL_TLS for this case. Back
|
||||
in FinishCall(), we change it again to CALL_NOP_TLS for 64-bit only,
|
||||
since we require a TOC-restore nop following the call for the 64-bit
|
||||
ABIs.
|
||||
|
||||
During selection, patterns in PPCInstrInfo.td and PPCInstr64Bit.td
|
||||
convert the CALL_TLS nodes into BL_TLS nodes, and convert the
|
||||
CALL_NOP_TLS nodes into BL8_NOP_TLS nodes. This replaces the code
|
||||
removed from PPCAsmPrinter.cpp, as the BL_TLS or BL8_NOP_TLS
|
||||
nodes can now be emitted normally using their patterns and the
|
||||
associated printTLSCall print method.
|
||||
|
||||
Finally, as a result of these changes, all references to get-tls-addr
|
||||
in its various guises are no longer used, so they have been removed.
|
||||
|
||||
There are existing TLS tests to verify the changes haven't messed
|
||||
anything up). I've added one new test that verifies that the problem
|
||||
with the original code has been fixed.
|
||||
|
||||
This fixes a fatal "Bad machine code" error when compiling parts of
|
||||
libgomp for 32-bit PowerPC.
|
||||
|
||||
Introduced here: http://svnweb.freebsd.org/changeset/base/276301
|
||||
|
||||
Index: lib/Target/PowerPC/PPC.h
|
||||
===================================================================
|
||||
--- lib/Target/PowerPC/PPC.h
|
||||
+++ lib/Target/PowerPC/PPC.h
|
||||
@@ -96,7 +96,12 @@ namespace llvm {
|
||||
MO_TOC_LO = 7 << 4,
|
||||
|
||||
// Symbol for VK_PPC_TLS fixup attached to an ADD instruction
|
||||
- MO_TLS = 8 << 4
|
||||
+ MO_TLS = 8 << 4,
|
||||
+
|
||||
+ // Symbols for VK_PPC_TLSGD and VK_PPC_TLSLD in __tls_get_addr
|
||||
+ // call sequences.
|
||||
+ MO_TLSLD = 9 << 4,
|
||||
+ MO_TLSGD = 10 << 4
|
||||
};
|
||||
} // end namespace PPCII
|
||||
|
||||
Index: lib/Target/PowerPC/PPCAsmPrinter.cpp
|
||||
===================================================================
|
||||
--- lib/Target/PowerPC/PPCAsmPrinter.cpp
|
||||
+++ lib/Target/PowerPC/PPCAsmPrinter.cpp
|
||||
@@ -689,35 +689,6 @@ void PPCAsmPrinter::EmitInstruction(const MachineI
|
||||
.addExpr(SymGotTlsGD));
|
||||
return;
|
||||
}
|
||||
- case PPC::GETtlsADDR:
|
||||
- // Transform: %X3 = GETtlsADDR %X3, <ga:@sym>
|
||||
- // Into: BL8_NOP_TLS __tls_get_addr(sym@tlsgd)
|
||||
- case PPC::GETtlsADDR32: {
|
||||
- // Transform: %R3 = GETtlsADDR32 %R3, <ga:@sym>
|
||||
- // Into: BL_TLS __tls_get_addr(sym@tlsgd)@PLT
|
||||
-
|
||||
- StringRef Name = "__tls_get_addr";
|
||||
- MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
|
||||
- MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
|
||||
-
|
||||
- if (!Subtarget.isPPC64() && !Subtarget.isDarwin() &&
|
||||
- TM.getRelocationModel() == Reloc::PIC_)
|
||||
- Kind = MCSymbolRefExpr::VK_PLT;
|
||||
- const MCSymbolRefExpr *TlsRef =
|
||||
- MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext);
|
||||
- const MachineOperand &MO = MI->getOperand(2);
|
||||
- const GlobalValue *GValue = MO.getGlobal();
|
||||
- MCSymbol *MOSymbol = getSymbol(GValue);
|
||||
- const MCExpr *SymVar =
|
||||
- MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD,
|
||||
- OutContext);
|
||||
- EmitToStreamer(OutStreamer,
|
||||
- MCInstBuilder(Subtarget.isPPC64() ?
|
||||
- PPC::BL8_NOP_TLS : PPC::BL_TLS)
|
||||
- .addExpr(TlsRef)
|
||||
- .addExpr(SymVar));
|
||||
- return;
|
||||
- }
|
||||
case PPC::ADDIStlsldHA: {
|
||||
// Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym>
|
||||
// Into: %Xd = ADDIS8 %X2, sym@got@tlsld@ha
|
||||
@@ -755,36 +726,6 @@ void PPCAsmPrinter::EmitInstruction(const MachineI
|
||||
.addExpr(SymGotTlsLD));
|
||||
return;
|
||||
}
|
||||
- case PPC::GETtlsldADDR:
|
||||
- // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym>
|
||||
- // Into: BL8_NOP_TLS __tls_get_addr(sym@tlsld)
|
||||
- case PPC::GETtlsldADDR32: {
|
||||
- // Transform: %R3 = GETtlsldADDR32 %R3, <ga:@sym>
|
||||
- // Into: BL_TLS __tls_get_addr(sym@tlsld)@PLT
|
||||
-
|
||||
- StringRef Name = "__tls_get_addr";
|
||||
- MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
|
||||
- MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
|
||||
-
|
||||
- if (!Subtarget.isPPC64() && !Subtarget.isDarwin() &&
|
||||
- TM.getRelocationModel() == Reloc::PIC_)
|
||||
- Kind = MCSymbolRefExpr::VK_PLT;
|
||||
-
|
||||
- const MCSymbolRefExpr *TlsRef =
|
||||
- MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext);
|
||||
- const MachineOperand &MO = MI->getOperand(2);
|
||||
- const GlobalValue *GValue = MO.getGlobal();
|
||||
- MCSymbol *MOSymbol = getSymbol(GValue);
|
||||
- const MCExpr *SymVar =
|
||||
- MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD,
|
||||
- OutContext);
|
||||
- EmitToStreamer(OutStreamer,
|
||||
- MCInstBuilder(Subtarget.isPPC64() ?
|
||||
- PPC::BL8_NOP_TLS : PPC::BL_TLS)
|
||||
- .addExpr(TlsRef)
|
||||
- .addExpr(SymVar));
|
||||
- return;
|
||||
- }
|
||||
case PPC::ADDISdtprelHA:
|
||||
// Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym>
|
||||
// Into: %Xd = ADDIS8 %X3, sym@dtprel@ha
|
||||
Index: lib/Target/PowerPC/PPCISelLowering.cpp
|
||||
===================================================================
|
||||
--- lib/Target/PowerPC/PPCISelLowering.cpp
|
||||
+++ lib/Target/PowerPC/PPCISelLowering.cpp
|
||||
@@ -781,6 +781,8 @@ const char *PPCTargetLowering::getTargetNodeName(u
|
||||
case PPCISD::SHL: return "PPCISD::SHL";
|
||||
case PPCISD::CALL: return "PPCISD::CALL";
|
||||
case PPCISD::CALL_NOP: return "PPCISD::CALL_NOP";
|
||||
+ case PPCISD::CALL_TLS: return "PPCISD::CALL_TLS";
|
||||
+ case PPCISD::CALL_NOP_TLS: return "PPCISD::CALL_NOP_TLS";
|
||||
case PPCISD::MTCTR: return "PPCISD::MTCTR";
|
||||
case PPCISD::BCTRL: return "PPCISD::BCTRL";
|
||||
case PPCISD::RET_FLAG: return "PPCISD::RET_FLAG";
|
||||
@@ -810,10 +812,8 @@ const char *PPCTargetLowering::getTargetNodeName(u
|
||||
case PPCISD::ADD_TLS: return "PPCISD::ADD_TLS";
|
||||
case PPCISD::ADDIS_TLSGD_HA: return "PPCISD::ADDIS_TLSGD_HA";
|
||||
case PPCISD::ADDI_TLSGD_L: return "PPCISD::ADDI_TLSGD_L";
|
||||
- case PPCISD::GET_TLS_ADDR: return "PPCISD::GET_TLS_ADDR";
|
||||
case PPCISD::ADDIS_TLSLD_HA: return "PPCISD::ADDIS_TLSLD_HA";
|
||||
case PPCISD::ADDI_TLSLD_L: return "PPCISD::ADDI_TLSLD_L";
|
||||
- case PPCISD::GET_TLSLD_ADDR: return "PPCISD::GET_TLSLD_ADDR";
|
||||
case PPCISD::ADDIS_DTPREL_HA: return "PPCISD::ADDIS_DTPREL_HA";
|
||||
case PPCISD::ADDI_DTPREL_L: return "PPCISD::ADDI_DTPREL_L";
|
||||
case PPCISD::VADD_SPLAT: return "PPCISD::VADD_SPLAT";
|
||||
@@ -1641,6 +1641,27 @@ SDValue PPCTargetLowering::LowerBlockAddress(SDVal
|
||||
return LowerLabelRef(TgtBAHi, TgtBALo, isPIC, DAG);
|
||||
}
|
||||
|
||||
+// Generate a call to __tls_get_addr for the given GOT entry Op.
|
||||
+std::pair<SDValue,SDValue>
|
||||
+PPCTargetLowering::lowerTLSCall(SDValue Op, SDLoc dl,
|
||||
+ SelectionDAG &DAG) const {
|
||||
+
|
||||
+ Type *IntPtrTy = getDataLayout()->getIntPtrType(*DAG.getContext());
|
||||
+ TargetLowering::ArgListTy Args;
|
||||
+ TargetLowering::ArgListEntry Entry;
|
||||
+ Entry.Node = Op;
|
||||
+ Entry.Ty = IntPtrTy;
|
||||
+ Args.push_back(Entry);
|
||||
+
|
||||
+ TargetLowering::CallLoweringInfo CLI(DAG);
|
||||
+ CLI.setDebugLoc(dl).setChain(DAG.getEntryNode())
|
||||
+ .setCallee(CallingConv::C, IntPtrTy,
|
||||
+ DAG.getTargetExternalSymbol("__tls_get_addr", getPointerTy()),
|
||||
+ std::move(Args), 0);
|
||||
+
|
||||
+ return LowerCallTo(CLI);
|
||||
+}
|
||||
+
|
||||
SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
|
||||
@@ -1686,7 +1707,8 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(S
|
||||
}
|
||||
|
||||
if (Model == TLSModel::GeneralDynamic) {
|
||||
- SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
|
||||
+ SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
|
||||
+ PPCII::MO_TLSGD);
|
||||
SDValue GOTPtr;
|
||||
if (is64bit) {
|
||||
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
|
||||
@@ -1700,26 +1722,13 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(S
|
||||
}
|
||||
SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSGD_L, dl, PtrVT,
|
||||
GOTPtr, TGA);
|
||||
-
|
||||
- // We need a chain node, and don't have one handy. The underlying
|
||||
- // call has no side effects, so using the function entry node
|
||||
- // suffices.
|
||||
- SDValue Chain = DAG.getEntryNode();
|
||||
- Chain = DAG.getCopyToReg(Chain, dl,
|
||||
- is64bit ? PPC::X3 : PPC::R3, GOTEntry);
|
||||
- SDValue ParmReg = DAG.getRegister(is64bit ? PPC::X3 : PPC::R3,
|
||||
- is64bit ? MVT::i64 : MVT::i32);
|
||||
- SDValue TLSAddr = DAG.getNode(PPCISD::GET_TLS_ADDR, dl,
|
||||
- PtrVT, ParmReg, TGA);
|
||||
- // The return value from GET_TLS_ADDR really is in X3 already, but
|
||||
- // some hacks are needed here to tie everything together. The extra
|
||||
- // copies dissolve during subsequent transforms.
|
||||
- Chain = DAG.getCopyToReg(Chain, dl, is64bit ? PPC::X3 : PPC::R3, TLSAddr);
|
||||
- return DAG.getCopyFromReg(Chain, dl, is64bit ? PPC::X3 : PPC::R3, PtrVT);
|
||||
+ std::pair<SDValue, SDValue> CallResult = lowerTLSCall(GOTEntry, dl, DAG);
|
||||
+ return CallResult.first;
|
||||
}
|
||||
|
||||
if (Model == TLSModel::LocalDynamic) {
|
||||
- SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
|
||||
+ SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
|
||||
+ PPCII::MO_TLSLD);
|
||||
SDValue GOTPtr;
|
||||
if (is64bit) {
|
||||
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
|
||||
@@ -1733,23 +1742,11 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(S
|
||||
}
|
||||
SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSLD_L, dl, PtrVT,
|
||||
GOTPtr, TGA);
|
||||
-
|
||||
- // We need a chain node, and don't have one handy. The underlying
|
||||
- // call has no side effects, so using the function entry node
|
||||
- // suffices.
|
||||
- SDValue Chain = DAG.getEntryNode();
|
||||
- Chain = DAG.getCopyToReg(Chain, dl,
|
||||
- is64bit ? PPC::X3 : PPC::R3, GOTEntry);
|
||||
- SDValue ParmReg = DAG.getRegister(is64bit ? PPC::X3 : PPC::R3,
|
||||
- is64bit ? MVT::i64 : MVT::i32);
|
||||
- SDValue TLSAddr = DAG.getNode(PPCISD::GET_TLSLD_ADDR, dl,
|
||||
- PtrVT, ParmReg, TGA);
|
||||
- // The return value from GET_TLSLD_ADDR really is in X3 already, but
|
||||
- // some hacks are needed here to tie everything together. The extra
|
||||
- // copies dissolve during subsequent transforms.
|
||||
- Chain = DAG.getCopyToReg(Chain, dl, is64bit ? PPC::X3 : PPC::R3, TLSAddr);
|
||||
+ std::pair<SDValue, SDValue> CallResult = lowerTLSCall(GOTEntry, dl, DAG);
|
||||
+ SDValue TLSAddr = CallResult.first;
|
||||
+ SDValue Chain = CallResult.second;
|
||||
SDValue DtvOffsetHi = DAG.getNode(PPCISD::ADDIS_DTPREL_HA, dl, PtrVT,
|
||||
- Chain, ParmReg, TGA);
|
||||
+ Chain, TLSAddr, TGA);
|
||||
return DAG.getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
|
||||
}
|
||||
|
||||
@@ -3712,6 +3709,23 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &C
|
||||
if (Callee.getNode()) {
|
||||
Ops.push_back(Chain);
|
||||
Ops.push_back(Callee);
|
||||
+
|
||||
+ // If this is a call to __tls_get_addr, find the symbol whose address
|
||||
+ // is to be taken and add it to the list. This will be used to
|
||||
+ // generate __tls_get_addr(<sym>@tlsgd) or __tls_get_addr(<sym>@tlsld).
|
||||
+ // We find the symbol by walking the chain to the CopyFromReg, walking
|
||||
+ // back from the CopyFromReg to the ADDI_TLSGD_L or ADDI_TLSLD_L, and
|
||||
+ // pulling the symbol from that node.
|
||||
+ if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
|
||||
+ if (!strcmp(S->getSymbol(), "__tls_get_addr")) {
|
||||
+ assert(!needIndirectCall && "Indirect call to __tls_get_addr???");
|
||||
+ SDNode *AddI = Chain.getNode()->getOperand(2).getNode();
|
||||
+ SDValue TGTAddr = AddI->getOperand(1);
|
||||
+ assert(TGTAddr.getNode()->getOpcode() == ISD::TargetGlobalTLSAddress &&
|
||||
+ "Didn't find target global TLS address where we expected one");
|
||||
+ Ops.push_back(TGTAddr);
|
||||
+ CallOpc = PPCISD::CALL_TLS;
|
||||
+ }
|
||||
}
|
||||
// If this is a tail call add stack pointer delta.
|
||||
if (isTailCall)
|
||||
@@ -3863,7 +3877,9 @@ PPCTargetLowering::FinishCall(CallingConv::ID Call
|
||||
DAG.getTarget().getRelocationModel() == Reloc::PIC_)) {
|
||||
// Otherwise insert NOP for non-local calls.
|
||||
CallOpc = PPCISD::CALL_NOP;
|
||||
- }
|
||||
+ } else if (CallOpc == PPCISD::CALL_TLS)
|
||||
+ // For 64-bit SVR4, TLS calls are always non-local.
|
||||
+ CallOpc = PPCISD::CALL_NOP_TLS;
|
||||
}
|
||||
|
||||
Chain = DAG.getNode(CallOpc, dl, NodeTys, Ops);
|
||||
Index: lib/Target/PowerPC/PPCISelLowering.h
|
||||
===================================================================
|
||||
--- lib/Target/PowerPC/PPCISelLowering.h
|
||||
+++ lib/Target/PowerPC/PPCISelLowering.h
|
||||
@@ -99,6 +99,10 @@ namespace llvm {
|
||||
/// SVR4 calls.
|
||||
CALL, CALL_NOP,
|
||||
|
||||
+ /// CALL_TLS and CALL_NOP_TLS - Versions of CALL and CALL_NOP used
|
||||
+ /// to access TLS variables.
|
||||
+ CALL_TLS, CALL_NOP_TLS,
|
||||
+
|
||||
/// CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a
|
||||
/// MTCTR instruction.
|
||||
MTCTR,
|
||||
@@ -214,10 +218,6 @@ namespace llvm {
|
||||
/// sym\@got\@tlsgd\@l.
|
||||
ADDI_TLSGD_L,
|
||||
|
||||
- /// G8RC = GET_TLS_ADDR %X3, Symbol - For the general-dynamic TLS
|
||||
- /// model, produces a call to __tls_get_addr(sym\@tlsgd).
|
||||
- GET_TLS_ADDR,
|
||||
-
|
||||
/// G8RC = ADDIS_TLSLD_HA %X2, Symbol - For the local-dynamic TLS
|
||||
/// model, produces an ADDIS8 instruction that adds the GOT base
|
||||
/// register to sym\@got\@tlsld\@ha.
|
||||
@@ -228,10 +228,6 @@ namespace llvm {
|
||||
/// sym\@got\@tlsld\@l.
|
||||
ADDI_TLSLD_L,
|
||||
|
||||
- /// G8RC = GET_TLSLD_ADDR %X3, Symbol - For the local-dynamic TLS
|
||||
- /// model, produces a call to __tls_get_addr(sym\@tlsld).
|
||||
- GET_TLSLD_ADDR,
|
||||
-
|
||||
/// G8RC = ADDIS_DTPREL_HA %X3, Symbol, Chain - For the
|
||||
/// local-dynamic TLS model, produces an ADDIS8 instruction
|
||||
/// that adds X3 to sym\@dtprel\@ha. The Chain operand is needed
|
||||
@@ -552,6 +548,8 @@ namespace llvm {
|
||||
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
+ std::pair<SDValue,SDValue> lowerTLSCall(SDValue Op, SDLoc dl,
|
||||
+ SelectionDAG &DAG) const;
|
||||
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
|
||||
Index: lib/Target/PowerPC/PPCInstr64Bit.td
|
||||
===================================================================
|
||||
--- lib/Target/PowerPC/PPCInstr64Bit.td
|
||||
+++ lib/Target/PowerPC/PPCInstr64Bit.td
|
||||
@@ -188,6 +188,9 @@ def : Pat<(PPCcall (i64 texternalsym:$dst)),
|
||||
def : Pat<(PPCcall_nop (i64 texternalsym:$dst)),
|
||||
(BL8_NOP texternalsym:$dst)>;
|
||||
|
||||
+def : Pat<(PPCcall_nop_tls texternalsym:$func, tglobaltlsaddr:$sym),
|
||||
+ (BL8_NOP_TLS texternalsym:$func, tglobaltlsaddr:$sym)>;
|
||||
+
|
||||
// Atomic operations
|
||||
let usesCustomInserter = 1 in {
|
||||
let Defs = [CR0] in {
|
||||
@@ -872,11 +875,6 @@ def ADDItlsgdL : Pseudo<(outs g8rc:$rD), (ins g8rc
|
||||
[(set i64:$rD,
|
||||
(PPCaddiTlsgdL i64:$reg, tglobaltlsaddr:$disp))]>,
|
||||
isPPC64;
|
||||
-def GETtlsADDR : Pseudo<(outs g8rc:$rD), (ins g8rc:$reg, tlsgd:$sym),
|
||||
- "#GETtlsADDR",
|
||||
- [(set i64:$rD,
|
||||
- (PPCgetTlsAddr i64:$reg, tglobaltlsaddr:$sym))]>,
|
||||
- isPPC64;
|
||||
def ADDIStlsldHA: Pseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, s16imm64:$disp),
|
||||
"#ADDIStlsldHA",
|
||||
[(set i64:$rD,
|
||||
@@ -887,11 +885,6 @@ def ADDItlsldL : Pseudo<(outs g8rc:$rD), (ins g8rc
|
||||
[(set i64:$rD,
|
||||
(PPCaddiTlsldL i64:$reg, tglobaltlsaddr:$disp))]>,
|
||||
isPPC64;
|
||||
-def GETtlsldADDR : Pseudo<(outs g8rc:$rD), (ins g8rc:$reg, tlsgd:$sym),
|
||||
- "#GETtlsldADDR",
|
||||
- [(set i64:$rD,
|
||||
- (PPCgetTlsldAddr i64:$reg, tglobaltlsaddr:$sym))]>,
|
||||
- isPPC64;
|
||||
def ADDISdtprelHA: Pseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, s16imm64:$disp),
|
||||
"#ADDISdtprelHA",
|
||||
[(set i64:$rD,
|
||||
Index: lib/Target/PowerPC/PPCInstrInfo.td
|
||||
===================================================================
|
||||
--- lib/Target/PowerPC/PPCInstrInfo.td
|
||||
+++ lib/Target/PowerPC/PPCInstrInfo.td
|
||||
@@ -110,10 +110,8 @@ def PPCldGotTprelL : SDNode<"PPCISD::LD_GOT_TPREL_
|
||||
def PPCaddTls : SDNode<"PPCISD::ADD_TLS", SDTIntBinOp, []>;
|
||||
def PPCaddisTlsgdHA : SDNode<"PPCISD::ADDIS_TLSGD_HA", SDTIntBinOp>;
|
||||
def PPCaddiTlsgdL : SDNode<"PPCISD::ADDI_TLSGD_L", SDTIntBinOp>;
|
||||
-def PPCgetTlsAddr : SDNode<"PPCISD::GET_TLS_ADDR", SDTIntBinOp>;
|
||||
def PPCaddisTlsldHA : SDNode<"PPCISD::ADDIS_TLSLD_HA", SDTIntBinOp>;
|
||||
def PPCaddiTlsldL : SDNode<"PPCISD::ADDI_TLSLD_L", SDTIntBinOp>;
|
||||
-def PPCgetTlsldAddr : SDNode<"PPCISD::GET_TLSLD_ADDR", SDTIntBinOp>;
|
||||
def PPCaddisDtprelHA : SDNode<"PPCISD::ADDIS_DTPREL_HA", SDTIntBinOp,
|
||||
[SDNPHasChain]>;
|
||||
def PPCaddiDtprelL : SDNode<"PPCISD::ADDI_DTPREL_L", SDTIntBinOp>;
|
||||
@@ -136,9 +134,15 @@ def SDT_PPCCall : SDTypeProfile<0, -1, [SDTCisIn
|
||||
def PPCcall : SDNode<"PPCISD::CALL", SDT_PPCCall,
|
||||
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
|
||||
SDNPVariadic]>;
|
||||
+def PPCcall_tls : SDNode<"PPCISD::CALL_TLS", SDT_PPCCall,
|
||||
+ [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
|
||||
+ SDNPVariadic]>;
|
||||
def PPCcall_nop : SDNode<"PPCISD::CALL_NOP", SDT_PPCCall,
|
||||
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
|
||||
SDNPVariadic]>;
|
||||
+def PPCcall_nop_tls : SDNode<"PPCISD::CALL_NOP_TLS", SDT_PPCCall,
|
||||
+ [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
|
||||
+ SDNPVariadic]>;
|
||||
def PPCload : SDNode<"PPCISD::LOAD", SDTypeProfile<1, 1, []>,
|
||||
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
|
||||
def PPCload_toc : SDNode<"PPCISD::LOAD_TOC", SDTypeProfile<0, 1, []>,
|
||||
@@ -2369,6 +2373,8 @@ def : Pat<(PPCcall (i32 tglobaladdr:$dst)),
|
||||
def : Pat<(PPCcall (i32 texternalsym:$dst)),
|
||||
(BL texternalsym:$dst)>;
|
||||
|
||||
+def : Pat<(PPCcall_tls texternalsym:$func, tglobaltlsaddr:$sym),
|
||||
+ (BL_TLS texternalsym:$func, tglobaltlsaddr:$sym)>;
|
||||
|
||||
def : Pat<(PPCtc_return (i32 tglobaladdr:$dst), imm:$imm),
|
||||
(TCRETURNdi tglobaladdr:$dst, imm:$imm)>;
|
||||
@@ -2424,18 +2430,10 @@ def ADDItlsgdL32 : Pseudo<(outs gprc:$rD), (ins gp
|
||||
"#ADDItlsgdL32",
|
||||
[(set i32:$rD,
|
||||
(PPCaddiTlsgdL i32:$reg, tglobaltlsaddr:$disp))]>;
|
||||
-def GETtlsADDR32 : Pseudo<(outs gprc:$rD), (ins gprc:$reg, tlsgd32:$sym),
|
||||
- "#GETtlsADDR32",
|
||||
- [(set i32:$rD,
|
||||
- (PPCgetTlsAddr i32:$reg, tglobaltlsaddr:$sym))]>;
|
||||
def ADDItlsldL32 : Pseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp),
|
||||
"#ADDItlsldL32",
|
||||
[(set i32:$rD,
|
||||
(PPCaddiTlsldL i32:$reg, tglobaltlsaddr:$disp))]>;
|
||||
-def GETtlsldADDR32 : Pseudo<(outs gprc:$rD), (ins gprc:$reg, tlsgd32:$sym),
|
||||
- "#GETtlsldADDR32",
|
||||
- [(set i32:$rD,
|
||||
- (PPCgetTlsldAddr i32:$reg, tglobaltlsaddr:$sym))]>;
|
||||
def ADDIdtprelL32 : Pseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp),
|
||||
"#ADDIdtprelL32",
|
||||
[(set i32:$rD,
|
||||
Index: lib/Target/PowerPC/PPCMCInstLower.cpp
|
||||
===================================================================
|
||||
--- lib/Target/PowerPC/PPCMCInstLower.cpp
|
||||
+++ lib/Target/PowerPC/PPCMCInstLower.cpp
|
||||
@@ -137,6 +137,12 @@ static MCOperand GetSymbolRef(const MachineOperand
|
||||
case PPCII::MO_TLS:
|
||||
RefKind = MCSymbolRefExpr::VK_PPC_TLS;
|
||||
break;
|
||||
+ case PPCII::MO_TLSGD:
|
||||
+ RefKind = MCSymbolRefExpr::VK_PPC_TLSGD;
|
||||
+ break;
|
||||
+ case PPCII::MO_TLSLD:
|
||||
+ RefKind = MCSymbolRefExpr::VK_PPC_TLSLD;
|
||||
+ break;
|
||||
}
|
||||
|
||||
if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB && !isDarwin)
|
||||
Index: test/CodeGen/PowerPC/tls-store2.ll
|
||||
===================================================================
|
||||
--- test/CodeGen/PowerPC/tls-store2.ll
|
||||
+++ test/CodeGen/PowerPC/tls-store2.ll
|
||||
@@ -0,0 +1,33 @@
|
||||
+; RUN: llc -march=ppc64 -mcpu=pwr7 -O2 -relocation-model=pic < %s | FileCheck %s
|
||||
+
|
||||
+target datalayout = "e-m:e-i64:64-n32:64"
|
||||
+target triple = "powerpc64le-unknown-linux-gnu"
|
||||
+
|
||||
+; Test back-to-back stores of TLS variables to ensure call sequences no
|
||||
+; longer overlap.
|
||||
+
|
||||
+@__once_callable = external thread_local global i8**
|
||||
+@__once_call = external thread_local global void ()*
|
||||
+
|
||||
+define i64 @call_once(i64 %flag, i8* %ptr) {
|
||||
+entry:
|
||||
+ %var = alloca i8*, align 8
|
||||
+ store i8* %ptr, i8** %var, align 8
|
||||
+ store i8** %var, i8*** @__once_callable, align 8
|
||||
+ store void ()* @__once_call_impl, void ()** @__once_call, align 8
|
||||
+ ret i64 %flag
|
||||
+}
|
||||
+
|
||||
+; CHECK-LABEL: call_once:
|
||||
+; CHECK: addis 3, 2, __once_callable@got@tlsgd@ha
|
||||
+; CHECK: addi 3, 3, __once_callable@got@tlsgd@l
|
||||
+; CHECK: bl __tls_get_addr(__once_callable@tlsgd)
|
||||
+; CHECK-NEXT: nop
|
||||
+; CHECK: std {{[0-9]+}}, 0(3)
|
||||
+; CHECK: addis 3, 2, __once_call@got@tlsgd@ha
|
||||
+; CHECK: addi 3, 3, __once_call@got@tlsgd@l
|
||||
+; CHECK: bl __tls_get_addr(__once_call@tlsgd)
|
||||
+; CHECK-NEXT: nop
|
||||
+; CHECK: std {{[0-9]+}}, 0(3)
|
||||
+
|
||||
+declare void @__once_call_impl()
|
@ -0,0 +1,95 @@
|
||||
Pull in r224890 from upstream llvm trunk (by David Majnemer):
|
||||
|
||||
PowerPC: CTR shouldn't fire if a TLS call is in the loop
|
||||
|
||||
Determining the address of a TLS variable results in a function call in
|
||||
certain TLS models. This means that a simple ICmpInst might actually
|
||||
result in invalidating the CTR register.
|
||||
|
||||
In such cases, do not attempt to rely on the CTR register for loop
|
||||
optimization purposes.
|
||||
|
||||
This fixes PR22034.
|
||||
|
||||
Differential Revision: http://reviews.llvm.org/D6786
|
||||
|
||||
This fixes a "Invalid PPC CTR loop" error when compiling parts of libc
|
||||
for PowerPC-32.
|
||||
|
||||
Introduced here: http://svnweb.freebsd.org/changeset/base/276324
|
||||
|
||||
Index: lib/Target/PowerPC/PPCCTRLoops.cpp
|
||||
===================================================================
|
||||
--- lib/Target/PowerPC/PPCCTRLoops.cpp
|
||||
+++ lib/Target/PowerPC/PPCCTRLoops.cpp
|
||||
@@ -194,6 +194,21 @@ static bool isLargeIntegerTy(bool Is32Bit, Type *T
|
||||
return false;
|
||||
}
|
||||
|
||||
+// Determining the address of a TLS variable results in a function call in
|
||||
+// certain TLS models.
|
||||
+static bool memAddrUsesCTR(const PPCTargetMachine *TM,
|
||||
+ const llvm::Value *MemAddr) {
|
||||
+ const auto *GV = dyn_cast<GlobalValue>(MemAddr);
|
||||
+ if (!GV)
|
||||
+ return false;
|
||||
+ if (!GV->isThreadLocal())
|
||||
+ return false;
|
||||
+ if (!TM)
|
||||
+ return true;
|
||||
+ TLSModel::Model Model = TM->getTLSModel(GV);
|
||||
+ return Model == TLSModel::GeneralDynamic || Model == TLSModel::LocalDynamic;
|
||||
+}
|
||||
+
|
||||
bool PPCCTRLoops::mightUseCTR(const Triple &TT, BasicBlock *BB) {
|
||||
for (BasicBlock::iterator J = BB->begin(), JE = BB->end();
|
||||
J != JE; ++J) {
|
||||
@@ -390,6 +405,9 @@ bool PPCCTRLoops::mightUseCTR(const Triple &TT, Ba
|
||||
SI->getNumCases()+1 >= (unsigned) TLI->getMinimumJumpTableEntries())
|
||||
return true;
|
||||
}
|
||||
+ for (Value *Operand : J->operands())
|
||||
+ if (memAddrUsesCTR(TM, Operand))
|
||||
+ return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
Index: test/CodeGen/PowerPC/ctrloops.ll
|
||||
===================================================================
|
||||
--- test/CodeGen/PowerPC/ctrloops.ll
|
||||
+++ test/CodeGen/PowerPC/ctrloops.ll
|
||||
@@ -1,6 +1,6 @@
|
||||
target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
|
||||
target triple = "powerpc64-unknown-freebsd10.0"
|
||||
-; RUN: llc < %s -march=ppc64 | FileCheck %s
|
||||
+; RUN: llc < %s -march=ppc64 -relocation-model=pic | FileCheck %s
|
||||
|
||||
@a = common global i32 0, align 4
|
||||
|
||||
@@ -73,3 +73,26 @@ for.end:
|
||||
; CHECK-NOT: cmplwi
|
||||
; CHECK: bdnz
|
||||
}
|
||||
+
|
||||
+@tls_var = external thread_local global i8
|
||||
+
|
||||
+define i32 @test4() {
|
||||
+entry:
|
||||
+ br label %for.body
|
||||
+
|
||||
+for.body: ; preds = %for.body, %entry
|
||||
+ %phi = phi i32 [ %dec, %for.body ], [ undef, %entry ]
|
||||
+ %load = ptrtoint i8* @tls_var to i32
|
||||
+ %dec = add i32 %phi, -1
|
||||
+ %cmp = icmp sgt i32 %phi, 1
|
||||
+ br i1 %cmp, label %for.body, label %return
|
||||
+
|
||||
+return: ; preds = %for.body
|
||||
+ ret i32 %load
|
||||
+; CHECK-LABEL: @test4
|
||||
+; CHECK-NOT: mtctr
|
||||
+; CHECK: addi {{[0-9]+}}
|
||||
+; CHECK: cmpwi
|
||||
+; CHECK-NOT: bdnz
|
||||
+; CHECK: bgt
|
||||
+}
|
Loading…
x
Reference in New Issue
Block a user