diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1948,7 +1948,11 @@ case GlobalValue::CommonLinkage: return XCOFF::C_EXT; case GlobalValue::ExternalWeakLinkage: + case GlobalValue::LinkOnceODRLinkage: return XCOFF::C_WEAKEXT; + case GlobalValue::AppendingLinkage: + report_fatal_error( + "There is no mapping that implements AppendingLinkage for XCOFF."); default: report_fatal_error( "Unhandled linkage when mapping linkage to StorageClass."); 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 @@ -1579,9 +1579,22 @@ return PPCAsmPrinter::lowerConstant(CV); } +static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV) { + return StringSwitch(GV->getName()) + .Cases("llvm.global_ctors", "llvm.global_dtors", true) + .Default(false); +} + void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { ValidateGV(GV); + // TODO: Update the handling of global arrays for static init when we support + // the ".ref" directive. + // Otherwise, we can skip these arrays, because the AIX linker collects + // static init functions simply based on their name. + if (isSpecialLLVMGlobalArrayForStaticInit(GV)) + return; + // Create the symbol, set its storage class. MCSymbolXCOFF *GVSym = cast(getSymbol(GV)); GVSym->setStorageClass( diff --git a/llvm/test/CodeGen/PowerPC/aix-AppendingLinkage.ll b/llvm/test/CodeGen/PowerPC/aix-AppendingLinkage.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-AppendingLinkage.ll @@ -0,0 +1,21 @@ +; RUN: llc -verify-machineinstrs -mcpu=pwr4 -mtriple powerpc-ibm-aix-xcoff < \ +; RUN: %s | FileCheck %s + +; RUN: llc -verify-machineinstrs -mcpu=pwr4 -mtriple powerpc64-ibm-aix-xcoff < \ +; RUN: %s | FileCheck %s + +@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* null }] +@llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @bar, i8* null }] + +define dso_local void @foo() { +entry: + ret void +} + +define dso_local void @bar() { +entry: + ret void +} + +; CHECK-NOT: llvm.global_ctors +; CHECK-NOT: llvm.global_dtors diff --git a/llvm/test/CodeGen/PowerPC/aix-LinkOnceODRLinkage.ll b/llvm/test/CodeGen/PowerPC/aix-LinkOnceODRLinkage.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-LinkOnceODRLinkage.ll @@ -0,0 +1,13 @@ +; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \ +; RUN: FileCheck %s + +; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \ +; RUN: FileCheck %s + +define linkonce_odr void @_Z3fooIiEvT_() { +entry: + ret void +} + +; CHECK: .weak _Z3fooIiEvT_ +; CHECK: .weak ._Z3fooIiEvT_