diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 15ff398836803..b4ac0a70e7fde 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2300,6 +2300,32 @@ bool AsmPrinter::doFinalization(Module &M) { // through user plugins. emitStackMaps(); + // Print aliases in topological order, that is, for each alias a = b, + // b must be printed before a. + // This is because on some targets (e.g. PowerPC) linker expects aliases in + // such an order to generate correct TOC information. + SmallVector AliasStack; + SmallPtrSet AliasVisited; + for (const auto &Alias : M.aliases()) { + if (Alias.hasAvailableExternallyLinkage()) + continue; + for (const GlobalAlias *Cur = &Alias; Cur; + Cur = dyn_cast(Cur->getAliasee())) { + if (!AliasVisited.insert(Cur).second) + break; + AliasStack.push_back(Cur); + } + for (const GlobalAlias *AncestorAlias : llvm::reverse(AliasStack)) + emitGlobalAlias(M, *AncestorAlias); + AliasStack.clear(); + } + + // IFuncs must come before deubginfo in case the backend decides to emit them + // as actual functions, since on MachO targets, we cannot create regular + // sections after DWARF. + for (const auto &IFunc : M.ifuncs()) + emitGlobalIFunc(M, IFunc); + // Finalize debug and EH information. for (const HandlerInfo &HI : Handlers) { NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName, @@ -2339,28 +2365,6 @@ bool AsmPrinter::doFinalization(Module &M) { } } - // Print aliases in topological order, that is, for each alias a = b, - // b must be printed before a. - // This is because on some targets (e.g. PowerPC) linker expects aliases in - // such an order to generate correct TOC information. - SmallVector AliasStack; - SmallPtrSet AliasVisited; - for (const auto &Alias : M.aliases()) { - if (Alias.hasAvailableExternallyLinkage()) - continue; - for (const GlobalAlias *Cur = &Alias; Cur; - Cur = dyn_cast(Cur->getAliasee())) { - if (!AliasVisited.insert(Cur).second) - break; - AliasStack.push_back(Cur); - } - for (const GlobalAlias *AncestorAlias : llvm::reverse(AliasStack)) - emitGlobalAlias(M, *AncestorAlias); - AliasStack.clear(); - } - for (const auto &IFunc : M.ifuncs()) - emitGlobalIFunc(M, IFunc); - GCModuleInfo *MI = getAnalysisIfAvailable(); assert(MI && "AsmPrinter didn't require GCModuleInfo?"); for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; ) diff --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp index e0080b145d4f9..ce736178afc8b 100644 --- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp @@ -147,7 +147,7 @@ bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const CallBase &CB, if (const GlobalIFunc *IF = dyn_cast(CalleeV); IF && MF.getTarget().getTargetTriple().isOSBinFormatMachO()) { // ld64 requires that .symbol_resolvers to be called via a stub, so these - // must always be a diret call. + // must always be a direct call. Info.Callee = MachineOperand::CreateGA(IF, 0); } else if (const Function *F = dyn_cast(CalleeV)) Info.Callee = MachineOperand::CreateGA(F, 0); diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index f4128332008fb..26b3a14e22b2a 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -1965,65 +1965,71 @@ void AArch64AsmPrinter::emitManualSymbolResolver(Module &M, OutStreamer->emitLabel(StubHelper); emitVisibility(StubHelper, GI.getVisibility()); - // stp fp, lr, [sp, #-16]! - // mov fp, sp - // stp x1, x0, [sp, #-16]! - // stp x3, x2, [sp, #-16]! - // stp x5, x4, [sp, #-16]! - // stp x7, x6, [sp, #-16]! - // stp d1, d0, [sp, #-16]! - // stp d3, d2, [sp, #-16]! - // stp d5, d4, [sp, #-16]! - // stp d7, d6, [sp, #-16]! + // stp fp, lr, [sp, #-16] + // sub fp, sp, 16 + // stp x1, x0, [sp, #-32] + // stp x3, x2, [sp, #-48] + // stp x5, x4, [sp, #-64] + // stp x7, x6, [sp, #-80] + // stp d1, d0, [sp, #-96] + // stp d3, d2, [sp, #-112] + // stp d5, d4, [sp, #-128] + // stp d7, d6, [sp, #-144] + // sub sp, sp, 144 // bl _resolver // adrp x16, lazy_pointer@GOTPAGE // ldr x16, [x16, lazy_pointer@GOTPAGEOFF] // str x0, [x16] // mov x16, x0 - // ldp d7, d6, [sp], #16 - // ldp d5, d4, [sp], #16 - // ldp d3, d2, [sp], #16 - // ldp d1, d0, [sp], #16 - // ldp x7, x6, [sp], #16 - // ldp x5, x4, [sp], #16 - // ldp x3, x2, [sp], #16 - // ldp x1, x0, [sp], #16 - // ldp fp, lr, [sp], #16 + // add sp, sp, 144 + // ldp d7, d6, [sp, #-144] + // ldp d5, d4, [sp, #-128] + // ldp d3, d2, [sp, #-112] + // ldp d1, d0, [sp, #-96] + // ldp x7, x6, [sp, #-80] + // ldp x5, x4, [sp, #-64] + // ldp x3, x2, [sp, #-48] + // ldp x1, x0, [sp, #-32] + // ldp fp, lr, [sp, #-16] // br x16 - OutStreamer->emitInstruction(MCInstBuilder(AArch64::STPXpre) - .addReg(AArch64::SP) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::STPXi) .addReg(AArch64::FP) .addReg(AArch64::LR) .addReg(AArch64::SP) .addImm(-2), *STI); - OutStreamer->emitInstruction(MCInstBuilder(AArch64::ADDXri) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::SUBXri) .addReg(AArch64::FP) .addReg(AArch64::SP) - .addImm(0) + .addImm(16) .addImm(0), *STI); - for (int I = 0; I != 4; ++I) - OutStreamer->emitInstruction(MCInstBuilder(AArch64::STPXpre) - .addReg(AArch64::SP) - .addReg(AArch64::X1 + 2 * I) - .addReg(AArch64::X0 + 2 * I) + for (int I = 0; I != 8; I += 2) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::STPXi) + .addReg(AArch64::X1 + I) + .addReg(AArch64::X0 + I) .addReg(AArch64::SP) - .addImm(-2), + .addImm(-4 - I), *STI); - for (int I = 0; I != 4; ++I) - OutStreamer->emitInstruction(MCInstBuilder(AArch64::STPDpre) + for (int I = 0; I != 8; I += 2) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::STPDi) + .addReg(AArch64::D1 + I) + .addReg(AArch64::D0 + I) .addReg(AArch64::SP) - .addReg(AArch64::D1 + 2 * I) - .addReg(AArch64::D0 + 2 * I) - .addReg(AArch64::SP) - .addImm(-2), + .addImm(-12 - I), *STI); + OutStreamer->emitInstruction(MCInstBuilder(AArch64::SUBXri) + .addReg(AArch64::SP) + .addReg(AArch64::SP) + .addImm(144) + .addImm(0), + *STI); + OutStreamer->emitInstruction( MCInstBuilder(AArch64::BL) .addOperand(MCOperand::createExpr(lowerConstant(GI.getResolver()))), @@ -2070,30 +2076,34 @@ void AArch64AsmPrinter::emitManualSymbolResolver(Module &M, .addImm(0), *STI); - for (int I = 3; I != -1; --I) - OutStreamer->emitInstruction(MCInstBuilder(AArch64::LDPDpost) - .addReg(AArch64::SP) - .addReg(AArch64::D1 + 2 * I) - .addReg(AArch64::D0 + 2 * I) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::ADDXri) + .addReg(AArch64::SP) + .addReg(AArch64::SP) + .addImm(144) + .addImm(0), + *STI); + + for (int I = 6; I != -2; I -= 2) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::LDPDi) + .addReg(AArch64::D1 + I) + .addReg(AArch64::D0 + I) .addReg(AArch64::SP) - .addImm(2), + .addImm(-12 - I), *STI); - for (int I = 3; I != -1; --I) - OutStreamer->emitInstruction(MCInstBuilder(AArch64::LDPXpost) - .addReg(AArch64::SP) - .addReg(AArch64::X1 + 2 * I) - .addReg(AArch64::X0 + 2 * I) + for (int I = 6; I != -2; I -= 2) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::LDPXi) + .addReg(AArch64::X1 + I) + .addReg(AArch64::X0 + I) .addReg(AArch64::SP) - .addImm(2), + .addImm(-4 - I), *STI); - OutStreamer->emitInstruction(MCInstBuilder(AArch64::LDPXpost) - .addReg(AArch64::SP) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::LDPXi) .addReg(AArch64::FP) .addReg(AArch64::LR) .addReg(AArch64::SP) - .addImm(2), + .addImm(-2), *STI); OutStreamer->emitInstruction(MCInstBuilder(TM.getTargetTriple().isArm64e() diff --git a/llvm/test/CodeGen/AArch64/addrsig-macho.ll b/llvm/test/CodeGen/AArch64/addrsig-macho.ll index 980b0e7bc4466..62bc764e0251b 100644 --- a/llvm/test/CodeGen/AArch64/addrsig-macho.ll +++ b/llvm/test/CodeGen/AArch64/addrsig-macho.ll @@ -3,6 +3,19 @@ ; RUN: llvm-objdump --macho --section-headers %t | FileCheck %s --check-prefix=SECTIONS ; RUN: llvm-objdump --macho --reloc %t | FileCheck %s --check-prefix=RELOCS +; CHECK: .section __DATA,__data +; CHECK: _i1.lazy_pointer: +; CHECK: .section __TEXT,__text,regular,pure_instructions +; CHECK: _i1: +; CHECK: _i1.stub_helper: +; CHECK: .section __DATA,__data +; CHECK: _i2.lazy_pointer: +; CHECK: .section __TEXT,__text,regular,pure_instructions +; CHECK: _i2: +; CHECK: _i2.stub_helper: + +; CHECK: .section __DWARF + ; CHECK: .addrsig{{$}} ; CHECK-NEXT: .addrsig_sym _func03_takeaddr ; CHECK-NEXT: .addrsig_sym _f1 @@ -118,8 +131,8 @@ declare void @f3() unnamed_addr @a1 = alias i32, i32* @g1 @a2 = internal local_unnamed_addr alias i32, i32* @g2 -@i1 = external ifunc void(), void()* ()* @f1 -@i2 = external local_unnamed_addr ifunc void(), void()* ()* @f2 +@i1 = ifunc void(), void()* ()* @f1 +@i2 = internal local_unnamed_addr ifunc void(), void()* ()* @f2 declare void @llvm.dbg.value(metadata, metadata, metadata) diff --git a/llvm/test/CodeGen/AArch64/ifunc-asm.ll b/llvm/test/CodeGen/AArch64/ifunc-asm.ll index fbc0f74cee46b..ede669aa52703 100644 --- a/llvm/test/CodeGen/AArch64/ifunc-asm.ll +++ b/llvm/test/CodeGen/AArch64/ifunc-asm.ll @@ -3,79 +3,82 @@ ; RUN: llc -mtriple=arm64-apple-darwin %s -filetype=asm -o - -arm64-darwin-ifunc-symbol_resolver=if_supported | FileCheck %s --check-prefixes=MACHO,MACHO-DEFAULT ; RUN: llc -mtriple=arm64-apple-darwin %s -filetype=asm -o - -arm64-darwin-ifunc-symbol_resolver=never | FileCheck %s --check-prefixes=MACHO,MACHO-MANUAL ; RUN: llc -mtriple=arm64-apple-darwin %s -filetype=asm -o - | FileCheck %s --check-prefixes=MACHO,MACHO-MANUAL +; RUN: llc -mtriple=arm64-apple-darwin %s -filetype=asm -o - -global-isel | FileCheck %s --check-prefixes=MACHO,MACHO-MANUAL -define internal ptr @foo_resolver() { +define internal ptr @the_resolver() { entry: ret ptr null } -; ELF: .type foo_resolver,@function -; ELF-NEXT: foo_resolver: +; ELF: .type the_resolver,@function +; ELF-NEXT: the_resolver: ; MACHO: .p2align 2 -; MACHO-NEXT: _foo_resolver +; MACHO-NEXT: _the_resolver -@foo_ifunc = ifunc i32 (i32), ptr @foo_resolver -; ELF: .globl foo_ifunc -; ELF-NEXT: .type foo_ifunc,@gnu_indirect_function -; ELF-NEXT: .set foo_ifunc, foo_resolver +@global_ifunc = ifunc i32 (i32), ptr @the_resolver +; ELF: .globl global_ifunc +; ELF-NEXT: .type global_ifunc,@gnu_indirect_function +; ELF-NEXT: .set global_ifunc, the_resolver -; MACHO-LINKER: .globl _foo_ifunc +; MACHO-LINKER: .globl _global_ifunc ; MACHO-LINKER-NEXT: .p2align 2 -; MACHO-LINKER-NEXT: _foo_ifunc: -; MACHO-LINKER-NEXT: .symbol_resolver _foo_ifunc -; MACHO-LINKER-NEXT: b _foo_resolver +; MACHO-LINKER-NEXT: _global_ifunc: +; MACHO-LINKER-NEXT: .symbol_resolver _global_ifunc +; MACHO-LINKER-NEXT: b _the_resolver -; MACHO-DEFAULT: .globl _foo_ifunc +; MACHO-DEFAULT: .globl _global_ifunc ; MACHO-DEFAULT-NEXT: .p2align 2 -; MACHO-DEFAULT-NEXT: _foo_ifunc: -; MACHO-DEFAULT-NEXT: .symbol_resolver _foo_ifunc -; MACHO-DEFAULT-NEXT: b _foo_resolver +; MACHO-DEFAULT-NEXT: _global_ifunc: +; MACHO-DEFAULT-NEXT: .symbol_resolver _global_ifunc +; MACHO-DEFAULT-NEXT: b _the_resolver ; MACHO-MANUAL: .section __DATA,__data -; MACHO-MANUAL-NEXT: .globl _foo_ifunc.lazy_pointer -; MACHO-MANUAL-NEXT: _foo_ifunc.lazy_pointer: -; MACHO-MANUAL-NEXT: .quad _foo_ifunc.stub_helper +; MACHO-MANUAL-NEXT: .globl _global_ifunc.lazy_pointer +; MACHO-MANUAL-NEXT: _global_ifunc.lazy_pointer: +; MACHO-MANUAL-NEXT: .quad _global_ifunc.stub_helper ; MACHO-MANUAL: .section __TEXT,__text,regular,pure_instructions -; MACHO-MANUAL-NEXT: .globl _foo_ifunc +; MACHO-MANUAL-NEXT: .globl _global_ifunc ; MACHO-MANUAL-NEXT: .p2align 2 -; MACHO-MANUAL-NEXT: _foo_ifunc: -; MACHO-MANUAL-NEXT: adrp x16, _foo_ifunc.lazy_pointer@GOTPAGE -; MACHO-MANUAL-NEXT: ldr x16, [x16, _foo_ifunc.lazy_pointer@GOTPAGEOFF] +; MACHO-MANUAL-NEXT: _global_ifunc: +; MACHO-MANUAL-NEXT: adrp x16, _global_ifunc.lazy_pointer@GOTPAGE +; MACHO-MANUAL-NEXT: ldr x16, [x16, _global_ifunc.lazy_pointer@GOTPAGEOFF] ; MACHO-MANUAL-NEXT: ldr x16, [x16] ; MACHO-MANUAL-NEXT: br x16 -; MACHO-MANUAL-NEXT: .globl _foo_ifunc.stub_helper +; MACHO-MANUAL-NEXT: .globl _global_ifunc.stub_helper ; MACHO-MANUAL-NEXT: .p2align 2 -; MACHO-MANUAL-NEXT: _foo_ifunc.stub_helper: -; MACHO-MANUAL-NEXT: stp x29, x30, [sp, #-16]! -; MACHO-MANUAL-NEXT: mov x29, sp -; MACHO-MANUAL-NEXT: stp x1, x0, [sp, #-16]! -; MACHO-MANUAL-NEXT: stp x3, x2, [sp, #-16]! -; MACHO-MANUAL-NEXT: stp x5, x4, [sp, #-16]! -; MACHO-MANUAL-NEXT: stp x7, x6, [sp, #-16]! -; MACHO-MANUAL-NEXT: stp d1, d0, [sp, #-16]! -; MACHO-MANUAL-NEXT: stp d3, d2, [sp, #-16]! -; MACHO-MANUAL-NEXT: stp d5, d4, [sp, #-16]! -; MACHO-MANUAL-NEXT: stp d7, d6, [sp, #-16]! -; MACHO-MANUAL-NEXT: bl _foo_resolver -; MACHO-MANUAL-NEXT: adrp x16, _foo_ifunc.lazy_pointer@GOTPAGE -; MACHO-MANUAL-NEXT: ldr x16, [x16, _foo_ifunc.lazy_pointer@GOTPAGEOFF] +; MACHO-MANUAL-NEXT: _global_ifunc.stub_helper: +; MACHO-MANUAL-NEXT: stp x29, x30, [sp, #-16] +; MACHO-MANUAL-NEXT: sub x29, sp, #16 +; MACHO-MANUAL-NEXT: stp x1, x0, [sp, #-32] +; MACHO-MANUAL-NEXT: stp x3, x2, [sp, #-48] +; MACHO-MANUAL-NEXT: stp x5, x4, [sp, #-64] +; MACHO-MANUAL-NEXT: stp x7, x6, [sp, #-80] +; MACHO-MANUAL-NEXT: stp d1, d0, [sp, #-96] +; MACHO-MANUAL-NEXT: stp d3, d2, [sp, #-112] +; MACHO-MANUAL-NEXT: stp d5, d4, [sp, #-128] +; MACHO-MANUAL-NEXT: stp d7, d6, [sp, #-144] +; MACHO-MANUAL-NEXT: sub sp, sp, #144 +; MACHO-MANUAL-NEXT: bl _the_resolver +; MACHO-MANUAL-NEXT: adrp x16, _global_ifunc.lazy_pointer@GOTPAGE +; MACHO-MANUAL-NEXT: ldr x16, [x16, _global_ifunc.lazy_pointer@GOTPAGEOFF] ; MACHO-MANUAL-NEXT: str x0, [x16] ; MACHO-MANUAL-NEXT: add x16, x0, #0 -; MACHO-MANUAL-NEXT: ldp d7, d6, [sp], #16 -; MACHO-MANUAL-NEXT: ldp d5, d4, [sp], #16 -; MACHO-MANUAL-NEXT: ldp d3, d2, [sp], #16 -; MACHO-MANUAL-NEXT: ldp d1, d0, [sp], #16 -; MACHO-MANUAL-NEXT: ldp x7, x6, [sp], #16 -; MACHO-MANUAL-NEXT: ldp x5, x4, [sp], #16 -; MACHO-MANUAL-NEXT: ldp x3, x2, [sp], #16 -; MACHO-MANUAL-NEXT: ldp x1, x0, [sp], #16 -; MACHO-MANUAL-NEXT: ldp x29, x30, [sp], #16 +; MACHO-MANUAL-NEXT: add sp, sp, #144 +; MACHO-MANUAL-NEXT: ldp d7, d6, [sp, #-144] +; MACHO-MANUAL-NEXT: ldp d5, d4, [sp, #-128] +; MACHO-MANUAL-NEXT: ldp d3, d2, [sp, #-112] +; MACHO-MANUAL-NEXT: ldp d1, d0, [sp, #-96] +; MACHO-MANUAL-NEXT: ldp x7, x6, [sp, #-80] +; MACHO-MANUAL-NEXT: ldp x5, x4, [sp, #-64] +; MACHO-MANUAL-NEXT: ldp x3, x2, [sp, #-48] +; MACHO-MANUAL-NEXT: ldp x1, x0, [sp, #-32] +; MACHO-MANUAL-NEXT: ldp x29, x30, [sp, #-16] ; MACHO-MANUAL-NEXT: br x16 -@weak_ifunc = weak ifunc i32 (i32), ptr @foo_resolver +@weak_ifunc = weak ifunc i32 (i32), ptr @the_resolver ; ELF: .type weak_ifunc,@gnu_indirect_function ; MACHO-LINKER: .symbol_resolver _weak_ifunc ; MACHO-MANUAL: _weak_ifunc.stub_helper: diff --git a/llvm/test/Verifier/ifunc-macho.ll b/llvm/test/Verifier/ifunc-macho.ll deleted file mode 100644 index 2e2166645983a..0000000000000 --- a/llvm/test/Verifier/ifunc-macho.ll +++ /dev/null @@ -1,42 +0,0 @@ -; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s - -target triple = "arm64-apple-ios" - -define ptr @resolver() { - ret ptr null -} - -@g = external global i32 -@inval_objtype = ifunc void (), ptr @g -; CHECK: IFunc must have a Function resolver - -declare ptr @resolver_decl() -@inval_resolver_decl = ifunc void (), ptr @resolver_decl -; CHECK: IFunc resolver must be a definition -; CHECK-NEXT: @inval_resolver_decl - -define available_externally ptr @resolver_linker_decl() { - ret ptr null -} -@inval_resolver_decl2 = ifunc void (), ptr @resolver_linker_decl -; CHECK: IFunc resolver must be a definition -; CHECK-NEXT: @inval_resolver_decl2 - -@ifunc_nonpointer_return_type = ifunc i32 (), ptr @resolver_returns_nonpointer -; CHECK: IFunc resolver must return a pointer -; CHECK-NEXT: ptr @ifunc_nonpointer_return_type - -define i32 @resolver_returns_nonpointer() { - ret i32 0 -} - -@valid_external = ifunc void (), ptr @resolver -; CHECK-NOT: valid_external - -@inval_linkonce = linkonce ifunc void (), ptr @resolver - -@inval_weak = weak ifunc void (), ptr @resolver - -@inval_weak_extern = extern_weak ifunc void (), ptr @resolver - -@inval_private = private ifunc void (), ptr @resolver