[llvm] r185945 - [PowerPC] Revert r185476 and fix up TLS variant kinds

Ulrich Weigand ulrich.weigand at de.ibm.com
Tue Jul 9 09:41:10 PDT 2013


Author: uweigand
Date: Tue Jul  9 11:41:09 2013
New Revision: 185945

URL: http://llvm.org/viewvc/llvm-project?rev=185945&view=rev
Log:

[PowerPC] Revert r185476 and fix up TLS variant kinds

In the commit message to r185476 I wrote:

>The PowerPC-specific modifiers VK_PPC_TLSGD and VK_PPC_TLSLD
>correspond exactly to the generic modifiers VK_TLSGD and VK_TLSLD.
>This causes some confusion with the asm parser, since VK_PPC_TLSGD
>is output as @tlsgd, which is then read back in as VK_TLSGD.
>
>To avoid this confusion, this patch removes the PowerPC-specific
>modifiers and uses the generic modifiers throughout.  (The only
>drawback is that the generic modifiers are printed in upper case
>while the usual convention on PowerPC is to use lower-case modifiers.
>But this is just a cosmetic issue.)

This was unfortunately incorrect, there is is fact another,
serious drawback to using the default VK_TLSLD/VK_TLSGD
variant kinds: using these causes ELFObjectWriter::RelocNeedsGOT
to return true, which in turn causes the ELFObjectWriter to emit
an undefined reference to _GLOBAL_OFFSET_TABLE_.

This is a problem on powerpc64, because it uses the TOC instead
of the GOT, and the linker does not provide _GLOBAL_OFFSET_TABLE_,
so the symbol remains undefined.  This means shared libraries
using TLS built with the integrated assembler are currently
broken.

While the whole RelocNeedsGOT / _GLOBAL_OFFSET_TABLE_ situation
probably ought to be properly fixed at some point, for now I'm
simply reverting the r185476 commit.  Now this in turn exposes
the breakage of handling @tlsgd/@tlsld in the asm parser that
this check-in was originally intended to fix.

To avoid this regression, I'm also adding a different fix for
this problem: while common code now parses @tlsgd as VK_TLSGD,
a special hack in the asm parser translates this code to the
platform-specific VK_PPC_TLSGD that the back-end now expects.
While this is not really pretty, it's self-contained and
shouldn't hurt anything else for now.  One the underlying
problem is fixed, this hack can be reverted again.


Modified:
    llvm/trunk/include/llvm/MC/MCExpr.h
    llvm/trunk/lib/MC/MCELFStreamer.cpp
    llvm/trunk/lib/MC/MCExpr.cpp
    llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
    llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
    llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
    llvm/trunk/test/CodeGen/PowerPC/tls-gd.ll
    llvm/trunk/test/CodeGen/PowerPC/tls-ld-2.ll
    llvm/trunk/test/CodeGen/PowerPC/tls-ld.ll
    llvm/trunk/test/MC/PowerPC/ppc64-fixups.s

Modified: llvm/trunk/include/llvm/MC/MCExpr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCExpr.h?rev=185945&r1=185944&r2=185945&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCExpr.h (original)
+++ llvm/trunk/include/llvm/MC/MCExpr.h Tue Jul  9 11:41:09 2013
@@ -216,10 +216,12 @@ public:
     VK_PPC_GOT_TLSGD_LO,   // symbol at got@tlsgd at l
     VK_PPC_GOT_TLSGD_HI,   // symbol at got@tlsgd at h
     VK_PPC_GOT_TLSGD_HA,   // symbol at got@tlsgd at ha
+    VK_PPC_TLSGD,          // symbol at tlsgd
     VK_PPC_GOT_TLSLD,      // symbol at got@tlsld
     VK_PPC_GOT_TLSLD_LO,   // symbol at got@tlsld at l
     VK_PPC_GOT_TLSLD_HI,   // symbol at got@tlsld at h
     VK_PPC_GOT_TLSLD_HA,   // symbol at got@tlsld at ha
+    VK_PPC_TLSLD,          // symbol at tlsld
 
     VK_Mips_GPREL,
     VK_Mips_GOT_CALL,

Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFStreamer.cpp?rev=185945&r1=185944&r2=185945&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCELFStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCELFStreamer.cpp Tue Jul  9 11:41:09 2013
@@ -392,10 +392,12 @@ void  MCELFStreamer::fixSymbolsInTLSFixu
     case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
     case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
     case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
+    case MCSymbolRefExpr::VK_PPC_TLSGD:
     case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
     case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
     case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
     case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
+    case MCSymbolRefExpr::VK_PPC_TLSLD:
       break;
     }
     MCSymbolData &SD = getAssembler().getOrCreateSymbolData(symRef.getSymbol());

Modified: llvm/trunk/lib/MC/MCExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCExpr.cpp?rev=185945&r1=185944&r2=185945&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCExpr.cpp (original)
+++ llvm/trunk/lib/MC/MCExpr.cpp Tue Jul  9 11:41:09 2013
@@ -241,10 +241,12 @@ StringRef MCSymbolRefExpr::getVariantKin
   case VK_PPC_GOT_TLSGD_LO: return "got at tlsgd@l";
   case VK_PPC_GOT_TLSGD_HI: return "got at tlsgd@h";
   case VK_PPC_GOT_TLSGD_HA: return "got at tlsgd@ha";
+  case VK_PPC_TLSGD: return "tlsgd";
   case VK_PPC_GOT_TLSLD: return "got at tlsld";
   case VK_PPC_GOT_TLSLD_LO: return "got at tlsld@l";
   case VK_PPC_GOT_TLSLD_HI: return "got at tlsld@h";
   case VK_PPC_GOT_TLSLD_HA: return "got at tlsld@ha";
+  case VK_PPC_TLSLD: return "tlsld";
   case VK_Mips_GPREL: return "GPREL";
   case VK_Mips_GOT_CALL: return "GOT_CALL";
   case VK_Mips_GOT16: return "GOT16";

Modified: llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp?rev=185945&r1=185944&r2=185945&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp Tue Jul  9 11:41:09 2013
@@ -190,6 +190,7 @@ class PPCAsmParser : public MCTargetAsmP
 
   const MCExpr *ExtractModifierFromExpr(const MCExpr *E,
                                         PPCMCExpr::VariantKind &Variant);
+  const MCExpr *FixupVariantKind(const MCExpr *E);
   bool ParseExpression(const MCExpr *&EVal);
 
   bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
@@ -1006,6 +1007,57 @@ ExtractModifierFromExpr(const MCExpr *E,
   llvm_unreachable("Invalid expression kind!");
 }
 
+/// Find all VK_TLSGD/VK_TLSLD symbol references in expression and replace
+/// them by VK_PPC_TLSGD/VK_PPC_TLSLD.  This is necessary to avoid having
+/// _GLOBAL_OFFSET_TABLE_ created via ELFObjectWriter::RelocNeedsGOT.
+/// FIXME: This is a hack.
+const MCExpr *PPCAsmParser::
+FixupVariantKind(const MCExpr *E) {
+  MCContext &Context = getParser().getContext();
+
+  switch (E->getKind()) {
+  case MCExpr::Target:
+  case MCExpr::Constant:
+    return E;
+
+  case MCExpr::SymbolRef: {
+    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
+    MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
+
+    switch (SRE->getKind()) {
+    case MCSymbolRefExpr::VK_TLSGD:
+      Variant = MCSymbolRefExpr::VK_PPC_TLSGD;
+      break;
+    case MCSymbolRefExpr::VK_TLSLD:
+      Variant = MCSymbolRefExpr::VK_PPC_TLSLD;
+      break;
+    default:
+      return E;
+    }
+    return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, Context);
+  }
+
+  case MCExpr::Unary: {
+    const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
+    const MCExpr *Sub = FixupVariantKind(UE->getSubExpr());
+    if (Sub == UE->getSubExpr())
+      return E;
+    return MCUnaryExpr::Create(UE->getOpcode(), Sub, Context);
+  }
+
+  case MCExpr::Binary: {
+    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
+    const MCExpr *LHS = FixupVariantKind(BE->getLHS());
+    const MCExpr *RHS = FixupVariantKind(BE->getRHS());
+    if (LHS == BE->getLHS() && RHS == BE->getRHS())
+      return E;
+    return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, Context);
+  }
+  }
+
+  llvm_unreachable("Invalid expression kind!");
+}
+
 /// Parse an expression.  This differs from the default "parseExpression"
 /// in that it handles complex \code @l/@ha \endcode modifiers.
 bool PPCAsmParser::
@@ -1013,6 +1065,8 @@ ParseExpression(const MCExpr *&EVal) {
   if (getParser().parseExpression(EVal))
     return true;
 
+  EVal = FixupVariantKind(EVal);
+
   PPCMCExpr::VariantKind Variant;
   const MCExpr *E = ExtractModifierFromExpr(EVal, Variant);
   if (E)

Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp?rev=185945&r1=185944&r2=185945&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp Tue Jul  9 11:41:09 2013
@@ -312,10 +312,10 @@ unsigned PPCELFObjectWriter::getRelocTyp
     case PPC::fixup_ppc_nofixup:
       switch (Modifier) {
       default: llvm_unreachable("Unsupported Modifier");
-      case MCSymbolRefExpr::VK_TLSGD:
+      case MCSymbolRefExpr::VK_PPC_TLSGD:
         Type = ELF::R_PPC64_TLSGD;
         break;
-      case MCSymbolRefExpr::VK_TLSLD:
+      case MCSymbolRefExpr::VK_PPC_TLSLD:
         Type = ELF::R_PPC64_TLSLD;
         break;
       case MCSymbolRefExpr::VK_PPC_TLS:

Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp?rev=185945&r1=185944&r2=185945&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Tue Jul  9 11:41:09 2013
@@ -573,7 +573,8 @@ void PPCAsmPrinter::EmitInstruction(cons
     const GlobalValue *GValue = MO.getGlobal();
     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
     const MCExpr *SymVar =
-      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_TLSGD, OutContext);
+      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD,
+                              OutContext);
     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLS)
                                 .addExpr(TlsRef)
                                 .addExpr(SymVar));
@@ -624,7 +625,8 @@ void PPCAsmPrinter::EmitInstruction(cons
     const GlobalValue *GValue = MO.getGlobal();
     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
     const MCExpr *SymVar =
-      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_TLSLD, OutContext);
+      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD,
+                              OutContext);
     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLS)
                                 .addExpr(TlsRef)
                                 .addExpr(SymVar));

Modified: llvm/trunk/test/CodeGen/PowerPC/tls-gd.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/tls-gd.ll?rev=185945&r1=185944&r2=185945&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/tls-gd.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/tls-gd.ll Tue Jul  9 11:41:09 2013
@@ -18,6 +18,6 @@ entry:
 
 ; CHECK: addis [[REG:[0-9]+]], 2, a at got@tlsgd at ha
 ; CHECK-NEXT: addi 3, [[REG]], a at got@tlsgd at l
-; CHECK:      bl __tls_get_addr(a at TLSGD)
+; CHECK:      bl __tls_get_addr(a at tlsgd)
 ; CHECK-NEXT: nop
 

Modified: llvm/trunk/test/CodeGen/PowerPC/tls-ld-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/tls-ld-2.ll?rev=185945&r1=185944&r2=185945&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/tls-ld-2.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/tls-ld-2.ll Tue Jul  9 11:41:09 2013
@@ -18,7 +18,7 @@ entry:
 
 ; CHECK:      addis [[REG:[0-9]+]], 2, a at got@tlsld at ha
 ; CHECK-NEXT: addi 3, [[REG]], a at got@tlsld at l
-; CHECK:      bl __tls_get_addr(a at TLSLD)
+; CHECK:      bl __tls_get_addr(a at tlsld)
 ; CHECK-NEXT: nop
 ; CHECK:      addis [[REG2:[0-9]+]], 3, a at dtprel@ha
 ; CHECK-NEXT: lwa {{[0-9]+}}, a at dtprel@l([[REG2]])

Modified: llvm/trunk/test/CodeGen/PowerPC/tls-ld.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/tls-ld.ll?rev=185945&r1=185944&r2=185945&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/tls-ld.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/tls-ld.ll Tue Jul  9 11:41:09 2013
@@ -18,7 +18,7 @@ entry:
 
 ; CHECK:      addis [[REG:[0-9]+]], 2, a at got@tlsld at ha
 ; CHECK-NEXT: addi 3, [[REG]], a at got@tlsld at l
-; CHECK:      bl __tls_get_addr(a at TLSLD)
+; CHECK:      bl __tls_get_addr(a at tlsld)
 ; CHECK-NEXT: nop
 ; CHECK:      addis [[REG2:[0-9]+]], 3, a at dtprel@ha
 ; CHECK-NEXT: addi {{[0-9]+}}, [[REG2]], a at dtprel@l

Modified: llvm/trunk/test/MC/PowerPC/ppc64-fixups.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/PowerPC/ppc64-fixups.s?rev=185945&r1=185944&r2=185945&view=diff
==============================================================================
--- llvm/trunk/test/MC/PowerPC/ppc64-fixups.s (original)
+++ llvm/trunk/test/MC/PowerPC/ppc64-fixups.s Tue Jul  9 11:41:09 2013
@@ -404,15 +404,15 @@ base:
 # CHECK-REL:                             0x{{[0-9A-F]*[26AE]}} R_PPC64_GOT_TLSLD16 target 0x0
          addi 3, 3, target at got@tlsld
 
-# CHECK: bl __tls_get_addr(target at TLSGD) # encoding: [0b010010BB,B,B,0bBBBBBB01]
-# CHECK-NEXT:                            #   fixup A - offset: 0, value: target at TLSGD, kind: fixup_ppc_nofixup
+# CHECK: bl __tls_get_addr(target at tlsgd) # encoding: [0b010010BB,B,B,0bBBBBBB01]
+# CHECK-NEXT:                            #   fixup A - offset: 0, value: target at tlsgd, kind: fixup_ppc_nofixup
 # CHECK-NEXT:                            #   fixup B - offset: 0, value: __tls_get_addr, kind: fixup_ppc_br24
 # CHECK-REL:                             0x{{[0-9A-F]*[048C]}} R_PPC64_TLSGD target 0x0
 # CHECK-REL-NEXT:                        0x{{[0-9A-F]*[048C]}} R_PPC64_REL24 __tls_get_addr 0x0
          bl __tls_get_addr(target at tlsgd)
 
-# CHECK: bl __tls_get_addr(target at TLSLD) # encoding: [0b010010BB,B,B,0bBBBBBB01]
-# CHECK-NEXT:                            #   fixup A - offset: 0, value: target at TLSLD, kind: fixup_ppc_nofixup
+# CHECK: bl __tls_get_addr(target at tlsld) # encoding: [0b010010BB,B,B,0bBBBBBB01]
+# CHECK-NEXT:                            #   fixup A - offset: 0, value: target at tlsld, kind: fixup_ppc_nofixup
 # CHECK-NEXT:                            #   fixup B - offset: 0, value: __tls_get_addr, kind: fixup_ppc_br24
 # CHECK-REL:                             0x{{[0-9A-F]*[048C]}} R_PPC64_TLSLD target 0x0
 # CHECK-REL-NEXT:                        0x{{[0-9A-F]*[048C]}} R_PPC64_REL24 __tls_get_addr 0x0





More information about the llvm-commits mailing list