[llvm] e0a372f - [PowerPC] Extend .reloc directive on PowerPC

Stefan Pintilie via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 22 02:26:07 PDT 2020


Author: Stefan Pintilie
Date: 2020-07-22T04:25:54-05:00
New Revision: e0a372ff10c8cc076cfd44e540629b7d09000d5e

URL: https://github.com/llvm/llvm-project/commit/e0a372ff10c8cc076cfd44e540629b7d09000d5e
DIFF: https://github.com/llvm/llvm-project/commit/e0a372ff10c8cc076cfd44e540629b7d09000d5e.diff

LOG: [PowerPC] Extend .reloc directive on PowerPC

When the compiler generates a GOT indirect load it must generate two loads. One
that loads the address of the element from the GOT and a second to load the
actual element based on the address just loaded from the GOT. However, the
linker can optimize these two loads into one load if it knows that it is safe
to do so. The compiler can tell the linker that the optimization is safe
by using the R_PPC64_PCREL_OPT relocation.

This patch extends the .reloc directive to allow the following setup

  pld 3, vec at got@pcrel(0), 1
.Lpcrel1=.-8
      ... More instructions possible here ...
.reloc .Lpcrel1,R_PPC64_PCREL_OPT,.-.Lpcrel1
  lwa 3, 4(3)

Reviewers: nemanjai, lei, hfinkel, sfertile, efriedma, tstellar, grosbach, MaskRay

Reviewed By: nemanjai, MaskRay

Differential Revision: https://reviews.llvm.org/D79625

Added: 
    llvm/test/MC/PowerPC/ppc64-reloc-directive-pcrel.s

Modified: 
    llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
    llvm/lib/MC/MCObjectStreamer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
index e28c9caaefaf..ddcafa2065bd 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
@@ -97,6 +97,7 @@
 #undef R_PPC64_DTPREL16_HIGH
 #undef R_PPC64_DTPREL16_HIGHA
 #undef R_PPC64_REL24_NOTOC
+#undef R_PPC64_PCREL_OPT
 #undef R_PPC64_PCREL34
 #undef R_PPC64_GOT_PCREL34
 #undef R_PPC64_IRELATIVE
@@ -194,6 +195,7 @@ ELF_RELOC(R_PPC64_TPREL16_HIGHA,        113)
 ELF_RELOC(R_PPC64_DTPREL16_HIGH,        114)
 ELF_RELOC(R_PPC64_DTPREL16_HIGHA,       115)
 ELF_RELOC(R_PPC64_REL24_NOTOC,          116)
+ELF_RELOC(R_PPC64_PCREL_OPT,            123)
 ELF_RELOC(R_PPC64_PCREL34,              132)
 ELF_RELOC(R_PPC64_GOT_PCREL34,          133)
 ELF_RELOC(R_PPC64_IRELATIVE,            248)

diff  --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index e39c4a03bc1e..78ee215b59aa 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -665,6 +665,68 @@ void MCObjectStreamer::emitGPRel64Value(const MCExpr *Value) {
   DF->getContents().resize(DF->getContents().size() + 8, 0);
 }
 
+static Optional<std::pair<bool, std::string>>
+getOffsetAndDataFragment(const MCSymbol &Symbol, uint32_t &RelocOffset,
+                         MCDataFragment *&DF) {
+  if (Symbol.isVariable()) {
+    const MCExpr *SymbolExpr = Symbol.getVariableValue();
+    MCValue OffsetVal;
+    if(!SymbolExpr->evaluateAsRelocatable(OffsetVal, nullptr, nullptr))
+      return std::make_pair(false,
+                            std::string("symbol in .reloc offset is not "
+                                        "relocatable"));
+    if (OffsetVal.isAbsolute()) {
+      RelocOffset = OffsetVal.getConstant();
+      MCFragment *Fragment = Symbol.getFragment();
+      // FIXME Support symbols with no DF. For example:
+      // .reloc .data, ENUM_VALUE, <some expr>
+      if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
+        return std::make_pair(false,
+                              std::string("symbol in offset has no data "
+                                          "fragment"));
+      DF = cast<MCDataFragment>(Fragment);
+      return None;
+    }
+
+    if (OffsetVal.getSymB())
+      return std::make_pair(false,
+                            std::string(".reloc symbol offset is not "
+                                        "representable"));
+
+    const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*OffsetVal.getSymA());
+    if (!SRE.getSymbol().isDefined())
+      return std::make_pair(false,
+                            std::string("symbol used in the .reloc offset is "
+                                        "not defined"));
+
+    if (SRE.getSymbol().isVariable())
+      return std::make_pair(false,
+                            std::string("symbol used in the .reloc offset is "
+                                        "variable"));
+
+    MCFragment *Fragment = SRE.getSymbol().getFragment();
+    // FIXME Support symbols with no DF. For example:
+    // .reloc .data, ENUM_VALUE, <some expr>
+    if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
+      return std::make_pair(false,
+                            std::string("symbol in offset has no data "
+                                        "fragment"));
+    RelocOffset = SRE.getSymbol().getOffset() + OffsetVal.getConstant();
+    DF = cast<MCDataFragment>(Fragment);
+  } else {
+    RelocOffset = Symbol.getOffset();
+    MCFragment *Fragment = Symbol.getFragment();
+    // FIXME Support symbols with no DF. For example:
+    // .reloc .data, ENUM_VALUE, <some expr>
+    if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
+      return std::make_pair(false,
+                            std::string("symbol in offset has no data "
+                                        "fragment"));
+    DF = cast<MCDataFragment>(Fragment);
+  }
+  return None;
+}
+
 Optional<std::pair<bool, std::string>>
 MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
                                      const MCExpr *Expr, SMLoc Loc,
@@ -698,10 +760,17 @@ MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
                           std::string(".reloc offset is not representable"));
 
   const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*OffsetVal.getSymA());
-  if (SRE.getSymbol().isDefined()) {
-    // FIXME SRE.getSymbol() may not be relative to DF.
+  const MCSymbol &Symbol = SRE.getSymbol();
+  if (Symbol.isDefined()) {
+    uint32_t SymbolOffset = 0;
+    Optional<std::pair<bool, std::string>> Error;
+    Error = getOffsetAndDataFragment(Symbol, SymbolOffset, DF);
+
+    if (Error != None)
+      return Error;
+
     DF->getFixups().push_back(
-        MCFixup::create(SRE.getSymbol().getOffset() + OffsetVal.getConstant(),
+        MCFixup::create(SymbolOffset + OffsetVal.getConstant(),
                         Expr, Kind, Loc));
     return None;
   }

diff  --git a/llvm/test/MC/PowerPC/ppc64-reloc-directive-pcrel.s b/llvm/test/MC/PowerPC/ppc64-reloc-directive-pcrel.s
new file mode 100644
index 000000000000..c17445f0a502
--- /dev/null
+++ b/llvm/test/MC/PowerPC/ppc64-reloc-directive-pcrel.s
@@ -0,0 +1,401 @@
+# RUN: llvm-mc -triple=powerpc64le -filetype=obj %s | \
+# RUN: llvm-objdump -dr --mcpu=pwr10 - | FileCheck %s
+# RUN: llvm-mc -triple=powerpc64 -filetype=obj %s | \
+# RUN: llvm-objdump -dr --mcpu=pwr10 - | FileCheck %s
+
+
+##
+# This section of tests contains the MCBinaryExpr as the first parameter of the
+# .reloc relocation.
+##
+	.text
+	.abiversion 2
+	.globl	Minimal
+	.p2align	4
+	.type	Minimal, at function
+Minimal:
+.LMinimal$local:
+	pld 3, vec at got@pcrel(0), 1
+.Lpcrel1:
+	.reloc .Lpcrel1-8,R_PPC64_PCREL_OPT,.-(.Lpcrel1-8)
+	lwa 3, 4(3)
+	blr
+	.long	0
+	.quad	0
+# CHECK-LABEL:   Minimal
+# CHECK:         pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0x8
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr
+
+	.globl	SingleInsnBetween
+	.p2align	4
+	.type	SingleInsnBetween, at function
+SingleInsnBetween:
+.LSingleInsnBetween$local:
+	pld 3, vec at got@pcrel(0), 1
+.Lpcrel2:
+        addi 3, 3, 42
+	.reloc .Lpcrel2-8,R_PPC64_PCREL_OPT,.-(.Lpcrel2-8)
+	lwa 3, 4(3)
+	blr
+	.long	0
+	.quad	0
+# CHECK_LABEL:   SingleInsnBetween
+# CHECK:         pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0xc
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr
+
+
+	.globl	MultiInsnBetween                    # -- Begin function
+	.p2align	4
+	.type	MultiInsnBetween, at function
+MultiInsnBetween:
+.LMultiInsnBetween$local:
+	pld 3, vec at got@pcrel(0), 1
+.Lpcrel3:
+        addi 3, 3, 42
+        addi 3, 3, 42
+        addi 3, 3, 42
+        addi 3, 3, 42
+        addi 3, 3, 42
+	.reloc .Lpcrel3-8,R_PPC64_PCREL_OPT,.-(.Lpcrel3-8)
+	lwa 3, 4(3)
+	blr
+	.long	0
+	.quad	0
+# CHECK_LABEL:   MultiInsnBetween
+# CHECK:         pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0x1c
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr
+
+	.globl	PrefixInsnBetween
+	.p2align	6
+	.type	PrefixInsnBetween, at function
+        .space          48       # Add a space to force an alignment of a paddi.
+PrefixInsnBetween:
+.LPrefixInsnBetween$local:
+	pld 3, vec at got@pcrel(0), 1
+.Lpcrel4:
+        addi 3, 3, 42
+        paddi 3, 3, 42, 0
+        addi 3, 3, 42
+        paddi 3, 3, 42, 0
+        addi 3, 3, 42
+	.reloc .Lpcrel4-8,R_PPC64_PCREL_OPT,.-(.Lpcrel4-8)
+	lwa 3, 4(3)
+	blr
+	.long	0
+	.quad	0
+# CHECK_LABEL:   PrefixInsnBetween
+# CHECK:         pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0x28
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    nop
+# CHECK-NEXT:    paddi 3, 3, 42, 0
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    paddi 3, 3, 42, 0
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr
+
+
+	.globl	SpaceBetween                    # -- Begin function
+	.p2align	4
+	.type	SpaceBetween, at function
+SpaceBetween:
+.LSpaceBetween$local:
+	pld 3, vec at got@pcrel(0), 1
+.Lpcrel5:
+        addi 3, 3, 42
+        paddi 3, 3, 42, 0
+        addi 3, 3, 42
+        .space 40, 0
+        paddi 3, 3, 42, 0
+        addi 3, 3, 42
+	.reloc .Lpcrel5-8,R_PPC64_PCREL_OPT,.-(.Lpcrel5-8)
+	lwa 3, 4(3)
+	blr
+	.long	0
+	.quad	0
+# CHECK_LABEL:   SpaceBetween
+# CHECK:         pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0x50
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    nop
+# CHECK-NEXT:    paddi 3, 3, 42, 0
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK:         paddi 3, 3, 42, 0
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr
+
+
+	.globl	Plus
+	.p2align	4
+	.type	Plus, at function
+Plus:
+.LPlus$local:
+.Lpcrel6:
+        addi 3, 3, 42
+        addi 3, 3, 42
+	pld 3, vec at got@pcrel(0), 1
+	.reloc .Lpcrel6+8,R_PPC64_PCREL_OPT,.-(.Lpcrel6+8)
+	lwa 3, 4(3)
+	blr
+	.long	0
+	.quad	0
+# CHECK-LABEL:   Plus
+# CHECK:         pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0x8
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr
+
+##
+# This section of tests contains the variable MCSymbol as part of the
+# MCSymbolRefExpr for the first parameter of the .reloc relocation.
+##
+	.globl	VarLabelMinimal                    # -- Begin function
+	.p2align	4
+	.type	VarLabelMinimal, at function
+VarLabelMinimal:
+.LVarLabelMinimal$local:
+	pld 3, vec at got@pcrel(0), 1
+.Lpcrel101=.-8
+	.reloc .Lpcrel101,R_PPC64_PCREL_OPT,.-.Lpcrel101
+	lwa 3, 4(3)
+	blr
+	.long	0
+	.quad	0
+# CHECK-LABEL:   VarLabelMinimal
+# CHECK:         pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0x8
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr
+
+
+	.globl	VarLabelSingleInsnBetween
+	.p2align	4
+	.type	VarLabelSingleInsnBetween, at function
+VarLabelSingleInsnBetween:
+.LVarLabelSingleInsnBetween$local:
+	pld 3, vec at got@pcrel(0), 1
+.Lpcrel102=.-8
+        addi 3, 3, 42
+	.reloc .Lpcrel102,R_PPC64_PCREL_OPT,.-.Lpcrel102
+	lwa 3, 4(3)
+	blr
+	.long	0
+	.quad	0
+# CHECK_LABEL:   VarLabelSingleInsnBetween
+# CHECK:         pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0xc
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr
+
+	.globl	VarLabelMultiInsnBetween                    # -- Begin function
+	.p2align	4
+	.type	VarLabelMultiInsnBetween, at function
+VarLabelMultiInsnBetween:
+.LVarLabelMultiInsnBetween$local:
+	pld 3, vec at got@pcrel(0), 1
+.Lpcrel103=.-8
+        addi 3, 3, 42
+        addi 3, 3, 42
+        addi 3, 3, 42
+        addi 3, 3, 42
+        addi 3, 3, 42
+	.reloc .Lpcrel103,R_PPC64_PCREL_OPT,.-.Lpcrel103
+	lwa 3, 4(3)
+	blr
+	.long	0
+	.quad	0
+# CHECK_LABEL:   VarLabelMultiInsnBetween
+# CHECK:         pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0x1c
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr
+
+
+	.globl	VarLabelPrefixInsnBetween                    # -- Begin function
+	.p2align	4
+	.type	VarLabelPrefixInsnBetween, at function
+VarLabelPrefixInsnBetween:
+.LVarLabelPrefixInsnBetween$local:
+	pld 3, vec at got@pcrel(0), 1
+.Lpcrel104=.-8
+        addi 3, 3, 42
+        paddi 3, 3, 42, 0
+        addi 3, 3, 42
+        paddi 3, 3, 42, 0
+        addi 3, 3, 42
+	.reloc .Lpcrel104,R_PPC64_PCREL_OPT,.-.Lpcrel104
+	lwa 3, 4(3)
+	blr
+	.long	0
+	.quad	0
+# CHECK_LABEL:   VarLabelPrefixInsnBetween
+# CHECK:         pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0x24
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    paddi 3, 3, 42, 0
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    paddi 3, 3, 42, 0
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr
+
+
+	.globl	VarLabelSpaceBetween                    # -- Begin function
+	.p2align	4
+	.type	VarLabelSpaceBetween, at function
+VarLabelSpaceBetween:
+.LVarLabelSpaceBetween$local:
+	pld 3, vec at got@pcrel(0), 1
+.Lpcrel105=.-8
+        addi 3, 3, 42
+        paddi 3, 3, 42, 0
+        addi 3, 3, 42
+        .space 40, 0
+        paddi 3, 3, 42, 0
+        addi 3, 3, 42
+	.reloc .Lpcrel105,R_PPC64_PCREL_OPT,.-.Lpcrel105
+	lwa 3, 4(3)
+	blr
+	.long	0
+	.quad	0
+# CHECK_LABEL:   VarLabelSpaceBetween
+# CHECK:         pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0x4c
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    paddi 3, 3, 42, 0
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK:         paddi 3, 3, 42, 0
+# CHECK-NEXT:    addi 3, 3, 42
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr
+
+
+	.globl	VarLabelPlus
+	.p2align	4
+	.type	VarLabelPlus, at function
+VarLabelPlus:
+.LVarLabelPlus$local:
+.Lpcrel106:
+        addi 3, 3, 42
+        addi 3, 3, 42
+	pld 3, vec at got@pcrel(0), 1
+	.reloc .Lpcrel106+8,R_PPC64_PCREL_OPT,.-(.Lpcrel106+8)
+	lwa 3, 4(3)
+	blr
+	.long	0
+	.quad	0
+# CHECK-LABEL:   VarLabelPlus
+# CHECK:         pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0x8
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr
+
+# Check the situation where the PLD requires an alignment nop.
+	.globl	AlignPLD
+	.p2align	6
+	.type	AlignPLD, at function
+        .space          60      # Force the pld to require an alignment nop.
+AlignPLD:
+.LAlignPLD$local:
+	pld 3, vec at got@pcrel(0), 1
+.Lpcrel201:
+	.reloc .Lpcrel201-8,R_PPC64_PCREL_OPT,.-(.Lpcrel201-8)
+	lwa 3, 4(3)
+	blr
+# CHECK-LABEL:   AlignPLD
+# CHECK:         nop
+# CHECK-NEXT:    pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0x8
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr
+
+# The label and the pld are on the same line and so the nop is inserted before
+# the label and the relocation should work.
+	.globl	AlignPLDSameLine
+	.p2align	6
+	.type	AlignPLDSameLine, at function
+        .space          60      # Force the pld to require an alignment nop.
+AlignPLDSameLine:
+.LAlignPLDSameLine$local:
+.Lpcrel202: pld 3, vec at got@pcrel(0), 1
+	.reloc .Lpcrel202,R_PPC64_PCREL_OPT,.-.Lpcrel202
+	lwa 3, 4(3)
+	blr
+# CHECK-LABEL:   AlignPLDSameLine
+# CHECK:         nop
+# CHECK-NEXT:    pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0x8
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr
+
+	.globl	AlignPLDLabelBefore
+	.p2align	6
+	.type	AlignPLDLabelBefore, at function
+        .space          60      # Force the pld to require an alignment nop.
+AlignPLDLabelBefore:
+.LAlignPLDLabelBefore$local:
+.Label:
+	pld 3, vec at got@pcrel(0), 1
+.Lpcrel203:
+	.reloc .Lpcrel203-8,R_PPC64_PCREL_OPT,.-(.Lpcrel203-8)
+	lwa 3, 4(3)
+	blr
+# CHECK-LABEL:   AlignPLDLabelBefore
+# CHECK:         nop
+# CHECK-NEXT:    pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0x8
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr
+
+	.globl	AlignPLDLabelSameLine
+	.p2align	6
+	.type	AlignPLDLabelSameLine, at function
+        .space          60      # Force the pld to require an alignment nop.
+AlignPLDLabelSameLine:
+.Label2: pld 3, vec at got@pcrel(0), 1
+.Lpcrel204:
+	.reloc .Lpcrel204-8,R_PPC64_PCREL_OPT,.-(.Lpcrel204-8)
+	lwa 3, 4(3)
+	blr
+# CHECK-LABEL:   AlignPLDLabelSameLine
+# CHECK:         nop
+# CHECK-NEXT:    pld 3, 0(0), 1
+# CHECK-NEXT:    R_PPC64_GOT_PCREL34	vec
+# CHECK-NEXT:    R_PPC64_PCREL_OPT	*ABS*+0x8
+# CHECK-NEXT:    lwa 3, 4(3)
+# CHECK-NEXT:    blr


        


More information about the llvm-commits mailing list