[llvm] 3437003 - [AsmPrinter] Emit PCs into requested PCSections

Marco Elver via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 7 02:38:20 PDT 2022


Author: Marco Elver
Date: 2022-09-07T11:36:02+02:00
New Revision: 343700358feb45ccc15182462ddf63a368623040

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

LOG: [AsmPrinter] Emit PCs into requested PCSections

Interpret MD_pcsections in AsmPrinter emitting the requested metadata to
the associated sections. Functions and normal instructions are handled.

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

Added: 
    llvm/test/CodeGen/AArch64/pcsections.ll
    llvm/test/CodeGen/X86/pcsections.ll

Modified: 
    llvm/include/llvm/CodeGen/AsmPrinter.h
    llvm/include/llvm/MC/MCObjectFileInfo.h
    llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/lib/MC/MCObjectFileInfo.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index f19f526435363..0d3ac9ea5464f 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -15,6 +15,8 @@
 #ifndef LLVM_CODEGEN_ASMPRINTER_H
 #define LLVM_CODEGEN_ASMPRINTER_H
 
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/BinaryFormat/Dwarf.h"
@@ -189,6 +191,9 @@ class AsmPrinter : public MachineFunctionPass {
   /// Output stream for the stack usage file (i.e., .su file).
   std::unique_ptr<raw_fd_ostream> StackUsageStream;
 
+  /// List of symbols to be inserted into PC sections.
+  DenseMap<const MDNode *, SmallVector<const MCSymbol *>> PCSectionsSymbols;
+
   static char ID;
 
 protected:
@@ -413,6 +418,12 @@ class AsmPrinter : public MachineFunctionPass {
 
   void emitRemarksSection(remarks::RemarkStreamer &RS);
 
+  /// Emits a label as reference for PC sections.
+  void emitPCSectionsLabel(const MachineFunction &MF, const MDNode &MD);
+
+  /// Emits the PC sections collected from instructions.
+  void emitPCSections(const MachineFunction &MF);
+
   /// Get the CFISection type for a function.
   CFISection getFunctionCFISectionType(const Function &F) const;
 

diff  --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h
index c1c7dd30a648d..eae2fc2ffbf1b 100644
--- a/llvm/include/llvm/MC/MCObjectFileInfo.h
+++ b/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -366,6 +366,8 @@ class MCObjectFileInfo {
 
   MCSection *getPseudoProbeDescSection(StringRef FuncName) const;
 
+  MCSection *getPCSection(StringRef Name, const MCSection *TextSec) const;
+
   // ELF specific sections.
   MCSection *getDataRelROSection() const { return DataRelROSection; }
   const MCSection *getMergeableConst4Section() const {

diff  --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 48c96678385dd..5863ce046c2aa 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1454,9 +1454,87 @@ void AsmPrinter::emitStackUsage(const MachineFunction &MF) {
     *StackUsageStream << "static\n";
 }
 
-static bool needFuncLabelsForEHOrDebugInfo(const MachineFunction &MF) {
+void AsmPrinter::emitPCSectionsLabel(const MachineFunction &MF,
+                                     const MDNode &MD) {
+  MCSymbol *S = MF.getContext().createTempSymbol("pcsection");
+  OutStreamer->emitLabel(S);
+  PCSectionsSymbols[&MD].emplace_back(S);
+}
+
+void AsmPrinter::emitPCSections(const MachineFunction &MF) {
+  const Function &F = MF.getFunction();
+  if (PCSectionsSymbols.empty() && !F.hasMetadata(LLVMContext::MD_pcsections))
+    return;
+
+  const CodeModel::Model CM = MF.getTarget().getCodeModel();
+  const unsigned RelativeRelocSize =
+      (CM == CodeModel::Medium || CM == CodeModel::Large) ? getPointerSize()
+                                                          : 4;
+
+  // Switch to PCSection, short-circuiting the common case where the current
+  // section is still valid (assume most MD_pcsections contain just 1 section).
+  auto SwitchSection = [&, Prev = StringRef()](const StringRef &Sec) mutable {
+    if (Sec == Prev)
+      return;
+    MCSection *S = getObjFileLowering().getPCSection(Sec, MF.getSection());
+    assert(S && "PC section is not initialized");
+    OutStreamer->switchSection(S);
+    Prev = Sec;
+  };
+  // Emit symbols into sections and data as specified in the pcsections MDNode.
+  auto EmitForMD = [&](const MDNode &MD, ArrayRef<const MCSymbol *> Syms,
+                       bool Deltas) {
+    // Expect the first operand to be a section name. After that, a tuple of
+    // constants may appear, which will simply be emitted into the current
+    // section (the user of MD_pcsections decides the format of encoded data).
+    assert(isa<MDString>(MD.getOperand(0)) && "first operand not a string");
+    for (const MDOperand &MDO : MD.operands()) {
+      if (auto *S = dyn_cast<MDString>(MDO)) {
+        SwitchSection(S->getString());
+        const MCSymbol *Prev = Syms.front();
+        for (const MCSymbol *Sym : Syms) {
+          if (Sym == Prev || !Deltas) {
+            // Use the entry itself as the base of the relative offset.
+            MCSymbol *Base = MF.getContext().createTempSymbol("pcsection_base");
+            OutStreamer->emitLabel(Base);
+            // Emit relative relocation `addr - base`, which avoids a dynamic
+            // relocation in the final binary. User will get the address with
+            // `base + addr`.
+            emitLabelDifference(Sym, Base, RelativeRelocSize);
+          } else {
+            emitLabelDifference(Sym, Prev, 4);
+          }
+          Prev = Sym;
+        }
+      } else {
+        assert(isa<MDNode>(MDO) && "expecting either string or tuple");
+        const auto *AuxMDs = cast<MDNode>(MDO);
+        for (const MDOperand &AuxMDO : AuxMDs->operands()) {
+          assert(isa<ConstantAsMetadata>(AuxMDO) && "expecting a constant");
+          const auto *C = cast<ConstantAsMetadata>(AuxMDO);
+          emitGlobalConstant(F.getParent()->getDataLayout(), C->getValue());
+        }
+      }
+    }
+  };
+
+  OutStreamer->pushSection();
+  // Emit PCs for function start and function size.
+  if (const MDNode *MD = F.getMetadata(LLVMContext::MD_pcsections))
+    EmitForMD(*MD, {getFunctionBegin(), getFunctionEnd()}, true);
+  // Emit PCs for instructions collected.
+  for (const auto &MS : PCSectionsSymbols)
+    EmitForMD(*MS.first, MS.second, false);
+  OutStreamer->popSection();
+  PCSectionsSymbols.clear();
+}
+
+/// Returns true if function begin and end labels should be emitted.
+static bool needFuncLabels(const MachineFunction &MF) {
   MachineModuleInfo &MMI = MF.getMMI();
-  if (!MF.getLandingPads().empty() || MF.hasEHFunclets() || MMI.hasDebugInfo())
+  if (!MF.getLandingPads().empty() || MF.hasEHFunclets() ||
+      MMI.hasDebugInfo() ||
+      MF.getFunction().hasMetadata(LLVMContext::MD_pcsections))
     return true;
 
   // We might emit an EH table that uses function begin and end labels even if
@@ -1514,6 +1592,9 @@ void AsmPrinter::emitFunctionBody() {
       if (MCSymbol *S = MI.getPreInstrSymbol())
         OutStreamer->emitLabel(S);
 
+      if (MDNode *MD = MI.getPCSections())
+        emitPCSectionsLabel(*MF, *MD);
+
       for (const HandlerInfo &HI : Handlers) {
         NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
                            HI.TimerGroupDescription, TimePassesIsEnabled);
@@ -1703,7 +1784,7 @@ void AsmPrinter::emitFunctionBody() {
   // are automatically sized.
   bool EmitFunctionSize = MAI->hasDotTypeDotSizeDirective() && !TT.isWasm();
 
-  if (needFuncLabelsForEHOrDebugInfo(*MF) || EmitFunctionSize) {
+  if (needFuncLabels(*MF) || EmitFunctionSize) {
     // Create a symbol for the end of function.
     CurrentFnEnd = createTempSymbol("func_end");
     OutStreamer->emitLabel(CurrentFnEnd);
@@ -1746,6 +1827,9 @@ void AsmPrinter::emitFunctionBody() {
   if (MF->hasBBLabels() && HasAnyRealCode)
     emitBBAddrMapSection(*MF);
 
+  // Emit sections containing instruction and function PCs.
+  emitPCSections(*MF);
+
   // Emit section containing stack size metadata.
   emitStackSizeSection(*MF);
 
@@ -2265,7 +2349,7 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
   if (F.hasFnAttribute("patchable-function-entry") ||
       F.hasFnAttribute("function-instrument") ||
       F.hasFnAttribute("xray-instruction-threshold") ||
-      needFuncLabelsForEHOrDebugInfo(MF) || NeedsLocalForSize ||
+      needFuncLabels(MF) || NeedsLocalForSize ||
       MF.getTarget().Options.EmitStackSizeSection || MF.hasBBLabels()) {
     CurrentFnBegin = createTempSymbol("func_begin");
     if (NeedsLocalForSize)

diff  --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 03ee0c0e32faa..1c032369a4e6e 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -1198,3 +1198,25 @@ MCObjectFileInfo::getPseudoProbeDescSection(StringRef FuncName) const {
   }
   return PseudoProbeDescSection;
 }
+
+MCSection *MCObjectFileInfo::getPCSection(StringRef Name,
+                                          const MCSection *TextSec) const {
+  if (Ctx->getObjectFileType() != MCContext::IsELF)
+    return nullptr;
+
+  // SHF_WRITE for relocations, and let user post-process data in-place.
+  unsigned Flags = ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER;
+
+  if (!TextSec)
+    TextSec = getTextSection();
+
+  StringRef GroupName;
+  const auto &ElfSec = static_cast<const MCSectionELF &>(*TextSec);
+  if (const MCSymbol *Group = ElfSec.getGroup()) {
+    GroupName = Group->getName();
+    Flags |= ELF::SHF_GROUP;
+  }
+  return Ctx->getELFSection(Name, ELF::SHT_PROGBITS, Flags, 0, GroupName, true,
+                            ElfSec.getUniqueID(),
+                            cast<MCSymbolELF>(TextSec->getBeginSymbol()));
+}

diff  --git a/llvm/test/CodeGen/AArch64/pcsections.ll b/llvm/test/CodeGen/AArch64/pcsections.ll
new file mode 100644
index 0000000000000..265b42ba1848b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/pcsections.ll
@@ -0,0 +1,117 @@
+; RUN: llc -O0 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-UNOPT,DEFCM
+; RUN: llc -O1 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-OPT,DEFCM
+; RUN: llc -O2 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-OPT,DEFCM
+; RUN: llc -O3 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-OPT,DEFCM
+; RUN: llc -O1 -code-model=large < %s | FileCheck %s --check-prefixes=CHECK,CHECK-OPT,LARGE
+
+target triple = "aarch64-unknown-linux-gnu"
+
+ at foo = dso_local global i64 0, align 8
+ at bar = dso_local global i64 0, align 8
+
+define i64 @multiple() !pcsections !0 {
+; CHECK-LABEL: multiple:
+; CHECK:       .Lfunc_begin0:
+; CHECK:       // %bb.0: // %entry
+; CHECK:       .Lpcsection0:
+; CHECK-NEXT:    ldr
+; CHECK-NEXT:    ret
+; CHECK:       .section	section_no_aux,"awo", at progbits,.text
+; CHECK-NEXT:  .Lpcsection_base0:
+; DEFCM-NEXT:  .word	.Lfunc_begin0-.Lpcsection_base0
+; LARGE-NEXT:  .xword	.Lfunc_begin0-.Lpcsection_base0
+; CHECK-NEXT:  .word	.Lfunc_end0-.Lfunc_begin0
+; CHECK-NEXT:  .section	section_aux_42,"awo", at progbits,.text
+; CHECK-NEXT:  .Lpcsection_base1:
+; DEFCM-NEXT:  .word	.Lpcsection0-.Lpcsection_base1
+; LARGE-NEXT:  .xword	.Lpcsection0-.Lpcsection_base1
+; CHECK-NEXT:  .word	42
+; CHECK-NEXT:  .section	section_aux_21264,"awo", at progbits,.text
+; CHECK-NEXT:  .Lpcsection_base2:
+; DEFCM-NEXT:  .word	.Lpcsection0-.Lpcsection_base2
+; LARGE-NEXT:  .xword	.Lpcsection0-.Lpcsection_base2
+; CHECK-NEXT:  .word	21264
+; CHECK-NEXT:  .text
+entry:
+  %0 = load i64, i64* @bar, align 8, !pcsections !1
+  ret i64 %0
+}
+
+define i64 @test_simple_atomic() {
+; CHECK-LABEL: test_simple_atomic:
+; CHECK:       .Lpcsection1:
+; CHECK-NEXT:    ldr
+; CHECK-NOT:   .Lpcsection2
+; CHECK:         ldr
+; CHECK:         add
+; CHECK-NEXT:    ret
+; CHECK:       .section	section_no_aux,"awo", at progbits,.text
+; CHECK-NEXT:  .Lpcsection_base3:
+; DEFCM-NEXT:  .word	.Lpcsection1-.Lpcsection_base3
+; LARGE-NEXT:  .xword	.Lpcsection1-.Lpcsection_base3
+; CHECK-NEXT:  .text
+entry:
+  %0 = load atomic i64, i64* @foo monotonic, align 8, !pcsections !0
+  %1 = load i64, i64* @bar, align 8
+  %add = add nsw i64 %1, %0
+  ret i64 %add
+}
+
+define i64 @test_complex_atomic() {
+; CHECK-LABEL: test_complex_atomic:
+; ---
+; CHECK-OPT:       .Lpcsection2:
+; CHECK-OPT-NEXT:    ldxr
+; CHECK-OPT:       .Lpcsection3:
+; CHECK-OPT-NEXT:    add
+; CHECK-OPT:       .Lpcsection4:
+; CHECK-OPT-NEXT:    stxr
+; CHECK-OPT:       .Lpcsection5:
+; CHECK-OPT-NEXT:    cbnz
+; ---
+; CHECK-UNOPT:     .Lpcsection2:
+; CHECK-UNOPT-NEXT:  ldr
+; CHECK-UNOPT:     .Lpcsection4:
+; CHECK-UNOPT-NEXT:  add
+; CHECK-UNOPT:     .Lpcsection5:
+; CHECK-UNOPT-NEXT:  ldaxr
+; CHECK-UNOPT:     .Lpcsection6:
+; CHECK-UNOPT-NEXT:  cmp
+; CHECK-UNOPT:     .Lpcsection8:
+; CHECK-UNOPT-NEXT:  stlxr
+; CHECK-UNOPT:     .Lpcsection9:
+; CHECK-UNOPT-NEXT:  cbnz
+; CHECK-UNOPT:     .Lpcsection12:
+; CHECK-UNOPT-NEXT:  b
+; ---
+; CHECK-NOT:   .Lpcsection
+; CHECK:         ldr
+; CHECK:         ret
+; CHECK:       .section	section_no_aux,"awo", at progbits,.text
+; CHECK-NEXT:  .Lpcsection_base4:
+; DEFCM-NEXT:  .word	.Lpcsection2-.Lpcsection_base4
+; LARGE-NEXT:  .xword	.Lpcsection2-.Lpcsection_base4
+; CHECK-NEXT:  .Lpcsection_base5:
+; DEFCM-NEXT:  .word	.Lpcsection3-.Lpcsection_base5
+; LARGE-NEXT:  .xword	.Lpcsection3-.Lpcsection_base5
+; CHECK-NEXT:  .Lpcsection_base6:
+; DEFCM-NEXT:  .word	.Lpcsection4-.Lpcsection_base6
+; LARGE-NEXT:  .xword	.Lpcsection4-.Lpcsection_base6
+; CHECK-NEXT:  .Lpcsection_base7:
+; DEFCM-NEXT:  .word	.Lpcsection5-.Lpcsection_base7
+; LARGE-NEXT:  .xword	.Lpcsection5-.Lpcsection_base7
+; CHECK-UNOPT: .word	.Lpcsection12-.Lpcsection_base14
+; CHECK-NEXT:  .text
+entry:
+  %0 = atomicrmw add i64* @foo, i64 1 monotonic, align 8, !pcsections !0
+  %1 = load i64, i64* @bar, align 8
+  %inc = add nsw i64 %1, 1
+  store i64 %inc, i64* @bar, align 8
+  %add = add nsw i64 %1, %0
+  ret i64 %add
+}
+
+!0 = !{!"section_no_aux"}
+!1 = !{!"section_aux_42", !2, !"section_aux_21264", !3}
+!2 = !{i32 42}
+!3 = !{i32 21264}

diff  --git a/llvm/test/CodeGen/X86/pcsections.ll b/llvm/test/CodeGen/X86/pcsections.ll
new file mode 100644
index 0000000000000..412c0bf777daf
--- /dev/null
+++ b/llvm/test/CodeGen/X86/pcsections.ll
@@ -0,0 +1,125 @@
+; RUN: llc -O0 < %s | FileCheck %s --check-prefixes=CHECK,DEFCM
+; RUN: llc -O1 < %s | FileCheck %s --check-prefixes=CHECK,DEFCM
+; RUN: llc -O2 < %s | FileCheck %s --check-prefixes=CHECK,DEFCM
+; RUN: llc -O3 < %s | FileCheck %s --check-prefixes=CHECK,DEFCM
+; RUN: llc -O1 -code-model=large < %s | FileCheck %s --check-prefixes=CHECK,LARGE
+
+target triple = "x86_64-unknown-linux-gnu"
+
+ at foo = dso_local global i64 0, align 8
+ at bar = dso_local global i64 0, align 8
+
+define void @empty_no_aux() !pcsections !0 {
+; CHECK-LABEL: empty_no_aux:
+; CHECK-NEXT:  .Lfunc_begin0
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    retq
+; CHECK-NEXT:  .Lfunc_end0:
+; CHECK:       .section	section_no_aux,"awo", at progbits,.text
+; CHECK-NEXT:  .Lpcsection_base0:
+; DEFCM-NEXT:  .long	.Lfunc_begin0-.Lpcsection_base0
+; LARGE-NEXT:  .quad	.Lfunc_begin0-.Lpcsection_base0
+; CHECK-NEXT:  .long	.Lfunc_end0-.Lfunc_begin0
+; CHECK-NEXT:  .text
+entry:
+  ret void
+}
+
+define void @empty_aux() !pcsections !1 {
+; CHECK-LABEL: empty_aux:
+; CHECK-NEXT:  .Lfunc_begin1
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    retq
+; CHECK-NEXT:  .Lfunc_end1:
+; CHECK:       .section	section_aux,"awo", at progbits,.text
+; CHECK-NEXT:  .Lpcsection_base1:
+; DEFCM-NEXT:  .long	.Lfunc_begin1-.Lpcsection_base1
+; LARGE-NEXT:  .quad	.Lfunc_begin1-.Lpcsection_base1
+; CHECK-NEXT:  .long	.Lfunc_end1-.Lfunc_begin1
+; CHECK-NEXT:  .long	10
+; CHECK-NEXT:  .long	20
+; CHECK-NEXT:  .long	30
+; CHECK-NEXT:  .text
+entry:
+  ret void
+}
+
+define i64 @multiple() !pcsections !0 {
+; CHECK-LABEL: multiple:
+; CHECK-NEXT:  .Lfunc_begin2
+; CHECK:       # %bb.0: # %entry
+; CHECK:       .Lpcsection0:
+; CHECK-NEXT:    movq
+; CHECK-NEXT:    retq
+; CHECK-NEXT:  .Lfunc_end2:
+; CHECK:       .section	section_no_aux,"awo", at progbits,.text
+; CHECK-NEXT:  .Lpcsection_base2:
+; DEFCM-NEXT:  .long	.Lfunc_begin2-.Lpcsection_base2
+; LARGE-NEXT:  .quad	.Lfunc_begin2-.Lpcsection_base2
+; CHECK-NEXT:  .long	.Lfunc_end2-.Lfunc_begin2
+; CHECK-NEXT:  .section	section_aux_42,"awo", at progbits,.text
+; CHECK-NEXT:  .Lpcsection_base3:
+; DEFCM-NEXT:  .long	.Lpcsection0-.Lpcsection_base3
+; LARGE-NEXT:  .quad	.Lpcsection0-.Lpcsection_base3
+; CHECK-NEXT:  .long	42
+; CHECK-NEXT:  .section	section_aux_21264,"awo", at progbits,.text
+; CHECK-NEXT:  .Lpcsection_base4:
+; DEFCM-NEXT:  .long	.Lpcsection0-.Lpcsection_base4
+; LARGE-NEXT:  .quad	.Lpcsection0-.Lpcsection_base4
+; CHECK-NEXT:  .long	21264
+; CHECK-NEXT:  .text
+entry:
+  %0 = load i64, i64* @bar, align 8, !pcsections !2
+  ret i64 %0
+}
+
+define i64 @test_simple_atomic() {
+; CHECK-LABEL: test_simple_atomic:
+; CHECK:       .Lpcsection1:
+; CHECK-NEXT:    movq
+; CHECK-NOT:   .Lpcsection
+; CHECK:         addq
+; CHECK-NEXT:    retq
+; CHECK-NEXT:  .Lfunc_end3:
+; CHECK:       .section	section_no_aux,"awo", at progbits,.text
+; CHECK-NEXT:  .Lpcsection_base5:
+; DEFCM-NEXT:  .long	.Lpcsection1-.Lpcsection_base5
+; LARGE-NEXT:  .quad	.Lpcsection1-.Lpcsection_base5
+; CHECK-NEXT:  .text
+entry:
+  %0 = load atomic i64, i64* @foo monotonic, align 8, !pcsections !0
+  %1 = load i64, i64* @bar, align 8
+  %add = add nsw i64 %1, %0
+  ret i64 %add
+}
+
+define i64 @test_complex_atomic() {
+; CHECK-LABEL: test_complex_atomic:
+; CHECK:         movl $1
+; CHECK-NEXT:  .Lpcsection2:
+; CHECK-NEXT:    lock xaddq
+; CHECK-NOT:   .Lpcsection
+; CHECK:         movq
+; CHECK:         addq
+; CHECK:         retq
+; CHECK-NEXT:  .Lfunc_end4:
+; CHECK:       .section	section_no_aux,"awo", at progbits,.text
+; CHECK-NEXT:  .Lpcsection_base6:
+; DEFCM-NEXT:  .long	.Lpcsection2-.Lpcsection_base6
+; LARGE-NEXT:  .quad	.Lpcsection2-.Lpcsection_base6
+; CHECK-NEXT:  .text
+entry:
+  %0 = atomicrmw add i64* @foo, i64 1 monotonic, align 8, !pcsections !0
+  %1 = load i64, i64* @bar, align 8
+  %inc = add nsw i64 %1, 1
+  store i64 %inc, i64* @bar, align 8
+  %add = add nsw i64 %1, %0
+  ret i64 %add
+}
+
+!0 = !{!"section_no_aux"}
+!1 = !{!"section_aux", !3}
+!2 = !{!"section_aux_42", !4, !"section_aux_21264", !5}
+!3 = !{i32 10, i32 20, i32 30}
+!4 = !{i32 42}
+!5 = !{i32 21264}


        


More information about the llvm-commits mailing list