Skip site navigation (1)Skip section navigation (2)
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>