diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -177,6 +177,8 @@ void SetupMachineFunction(MachineFunction &MF) override; + const MCExpr *lowerConstant(const Constant *CV) override; + void EmitGlobalVariable(const GlobalVariable *GV) override; void EmitFunctionDescriptor() override; @@ -1763,6 +1765,26 @@ report_fatal_error("COMDAT not yet supported by AIX."); } +const MCExpr *PPCAIXAsmPrinter::lowerConstant(const Constant *CV) { + if (const Function *F = dyn_cast(CV)) { + MCSymbolXCOFF *FSym = cast(getSymbol(F)); + if (!FSym->hasContainingCsect()) { + const XCOFF::StorageClass SC = + F->isDeclaration() + ? TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(F) + : XCOFF::C_HIDEXT; + MCSectionXCOFF *Csect = OutStreamer->getContext().getXCOFFSection( + FSym->getName(), XCOFF::XMC_DS, + F->isDeclaration() ? XCOFF::XTY_ER : XCOFF::XTY_SD, SC, + SectionKind::getMetadata()); + FSym->setContainingCsect(Csect); + } + return MCSymbolRefExpr::create( + FSym->getContainingCsect()->getQualNameSymbol(), OutContext); + } + return PPCAsmPrinter::lowerConstant(CV); +} + void PPCAIXAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { ValidateGV(GV); diff --git a/llvm/test/CodeGen/PowerPC/aix-reference-func-addr-const.ll b/llvm/test/CodeGen/PowerPC/aix-reference-func-addr-const.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-reference-func-addr-const.ll @@ -0,0 +1,32 @@ +; RUN: llc -verify-machineinstrs -mcpu=pwr4 -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mcpu=pwr4 -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck --check-prefix=CHECK64 %s + +@foo_ptr = global void (...)* @foo +declare void @foo(...) + +@bar_ptr1 = global void (...)* bitcast (void ()* @bar to void (...)*) +define void @bar() { +entry: + ret void +} + + +;CHECK: .csect .data[RW] +;CHECK-NEXT: .globl foo_ptr +;CHECK-NEXT: .align 2 +;CHECK-NEXT: foo_ptr: +;CHECK-NEXT: .long foo[DS] +;CHECK-NEXT: .globl bar_ptr1 +;CHECK-NEXT: .align 2 +;CHECK-NEXT: bar_ptr1: +;CHECK-NEXT: .long bar[DS] + +;CHECK64: .csect .data[RW] +;CHECK64-NEXT: .globl foo_ptr +;CHECK64-NEXT: .align 3 +;CHECK64-NEXT: foo_ptr: +;CHECK64-NEXT: .llong foo[DS] +;CHECK64-NEXT: .globl bar_ptr1 +;CHECK64-NEXT: .align 3 +;CHECK64-NEXT: bar_ptr1: +;CHECK64-NEXT: .llong bar[DS]