diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -646,8 +646,23 @@ } // Emit the prefix data. - if (F->hasPrefixData()) - EmitGlobalConstant(F->getParent()->getDataLayout(), F->getPrefixData()); + if (F->hasPrefixData()) { + if (MAI->hasSubsectionsViaSymbols()) { + // Preserving prefix data on platforms which use subsections-via-symbols + // is a bit tricky. Here we introduce a symbol for the prefix data + // and use the .alt_entry attribute to mark the function's real entry point + // as an alternative entry point to the prefix-data symbol. + MCSymbol *PrefixSym = OutContext.createLinkerPrivateTempSymbol(); + OutStreamer->EmitLabel(PrefixSym); + + EmitGlobalConstant(F->getParent()->getDataLayout(), F->getPrefixData()); + + // Emit an .alt_entry directive for the actual function symbol. + OutStreamer->EmitSymbolAttribute(CurrentFnSym, MCSA_AltEntry); + } else { + EmitGlobalConstant(F->getParent()->getDataLayout(), F->getPrefixData()); + } + } // Emit the CurrentFnSym. This is a virtual function to allow targets to // do their wild and crazy things as required. diff --git a/llvm/test/CodeGen/AArch64/prefixdata.ll b/llvm/test/CodeGen/AArch64/prefixdata.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/prefixdata.ll @@ -0,0 +1,29 @@ +; RUN: llc < %s -mtriple=aarch64-apple-darwin | FileCheck --check-prefix=MACHO %s +; RUN: llc < %s -mtriple=aarch64-pc-linux | FileCheck --check-prefix=ELF %s + +@i = linkonce_odr global i32 1 + +; MACHO: ltmp0: +; MACHO-NEXT: .long 1 +; MACHO-NEXT: .alt_entry _f +; MACHO-NEXT: _f: +; ELF: .type f,@function +; ELF-NEXT: .word 1 +; ELF-NEXT: // 0x1 +; ELF-NEXT: f: +define void @f() prefix i32 1 { + ret void +} + +; MACHO: ltmp1: +; MACHO-NEXT: .quad _i +; MACHO-NEXT: .alt_entry _g +; MACHO-NEXT: _g: +; ELF: .type g,@function +; ELF-NEXT: .xword i +; ELF-NEXT: g: +define void @g() prefix i32* @i { + ret void +} + +; MACHO: .subsections_via_symbols diff --git a/llvm/test/CodeGen/X86/prefixdata.ll b/llvm/test/CodeGen/X86/prefixdata.ll --- a/llvm/test/CodeGen/X86/prefixdata.ll +++ b/llvm/test/CodeGen/X86/prefixdata.ll @@ -1,18 +1,29 @@ -; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck --check-prefix=MACHO %s +; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck --check-prefix=ELF %s @i = linkonce_odr global i32 1 -; CHECK: .type f,@function -; CHECK-NEXT: .long 1 -; CHECK-NEXT: # 0x1 -; CHECK-NEXT: f: +; MACHO: ltmp0: +; MACHO-NEXT: .long 1 +; MACHO-NEXT: .alt_entry _f +; MACHO-NEXT: _f: +; ELF: .type f,@function +; ELF-NEXT: .long 1 +; ELF-NEXT: # 0x1 +; ELF-NEXT: f: define void @f() prefix i32 1 { ret void } -; CHECK: .type g,@function -; CHECK-NEXT: .quad i -; CHECK-NEXT: g: +; MACHO: ltmp1: +; MACHO-NEXT: .quad _i +; MACHO-NEXT: .alt_entry _g +; MACHO-NEXT: _g: +; ELF: .type g,@function +; ELF-NEXT: .quad i +; ELF-NEXT: g: define void @g() prefix i32* @i { ret void } + +; MACHO: .subsections_via_symbols