summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp19
-rw-r--r--llvm/test/CodeGen/AArch64/prefixdata.ll29
-rw-r--r--llvm/test/CodeGen/X86/prefixdata.ll27
3 files changed, 65 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 7099065a638..f02062b7377 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -646,8 +646,23 @@ void AsmPrinter::EmitFunctionHeader() {
}
// 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
index 00000000000..f62734c16e5
--- /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
index 9bb54a2a397..b62f48ddce2 100644
--- 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
OpenPOWER on IntegriCloud