svn commit: r276325 - projects/clang350-import/contrib/llvm/patches
Dimitry Andric
dim at FreeBSD.org
Sun Dec 28 02:33:15 UTC 2014
Author: dim
Date: Sun Dec 28 02:33:13 2014
New Revision: 276325
URL: https://svnweb.freebsd.org/changeset/base/276325
Log:
Add llvm patches corresponding to r276300, r276301 and r276324.
Added:
projects/clang350-import/contrib/llvm/patches/patch-26-llvm-r213890-ppc-eh_frame.diff
projects/clang350-import/contrib/llvm/patches/patch-27-llvm-r221703-ppc-tls_get_addr.diff
projects/clang350-import/contrib/llvm/patches/patch-28-llvm-r224890-ppc-ctr-tls-loop.diff
Added: projects/clang350-import/contrib/llvm/patches/patch-26-llvm-r213890-ppc-eh_frame.diff
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/clang350-import/contrib/llvm/patches/patch-26-llvm-r213890-ppc-eh_frame.diff Sun Dec 28 02:33:13 2014 (r276325)
@@ -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
Added: projects/clang350-import/contrib/llvm/patches/patch-27-llvm-r221703-ppc-tls_get_addr.diff
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/clang350-import/contrib/llvm/patches/patch-27-llvm-r221703-ppc-tls_get_addr.diff Sun Dec 28 02:33:13 2014 (r276325)
@@ -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 at tlsgd)
+- case PPC::GETtlsADDR32: {
+- // Transform: %R3 = GETtlsADDR32 %R3, <ga:@sym>
+- // Into: BL_TLS __tls_get_addr(sym at 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 at got@tlsld at 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 at tlsld)
+- case PPC::GETtlsldADDR32: {
+- // Transform: %R3 = GETtlsldADDR32 %R3, <ga:@sym>
+- // Into: BL_TLS __tls_get_addr(sym at 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 at 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.
++
++ at __once_callable = external thread_local global i8**
++ at __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 at got@tlsgd at ha
++; CHECK: addi 3, 3, __once_callable at got@tlsgd at l
++; CHECK: bl __tls_get_addr(__once_callable at tlsgd)
++; CHECK-NEXT: nop
++; CHECK: std {{[0-9]+}}, 0(3)
++; CHECK: addis 3, 2, __once_call at got@tlsgd at ha
++; CHECK: addi 3, 3, __once_call at got@tlsgd at l
++; CHECK: bl __tls_get_addr(__once_call at tlsgd)
++; CHECK-NEXT: nop
++; CHECK: std {{[0-9]+}}, 0(3)
++
++declare void @__once_call_impl()
Added: projects/clang350-import/contrib/llvm/patches/patch-28-llvm-r224890-ppc-ctr-tls-loop.diff
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/clang350-import/contrib/llvm/patches/patch-28-llvm-r224890-ppc-ctr-tls-loop.diff Sun Dec 28 02:33:13 2014 (r276325)
@@ -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
+ }
++
++ at 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
++}
More information about the svn-src-projects
mailing list