Date: Sun, 28 Dec 2014 02:33:14 +0000 (UTC) From: Dimitry Andric <dim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r276325 - projects/clang350-import/contrib/llvm/patches Message-ID: <201412280233.sBS2XE28055150@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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@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() 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 + } ++ ++@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 ++}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201412280233.sBS2XE28055150>