diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -10,6 +10,7 @@ #define LLVM_MC_MCCONTEXT_H #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallString.h" @@ -100,6 +101,10 @@ /// Bindings of names to symbols. SymbolTable Symbols; + /// llvm extern intrinsic xcoff symbols used for emiting these symbol's + /// linkage. + DenseSet XCOFFIntrinsicSymbols; + /// A mapping from a local label number and an instance count to a symbol. /// For example, in the assembly /// 1: @@ -414,6 +419,11 @@ /// Get the symbol for \p Name, or null. MCSymbol *lookupSymbol(const Twine &Name) const; + /// Get XCOFF Intrinsic entern symbols DenseSet. + DenseSet &getXCOFFIntrinsicExternSymbol() { + return XCOFFIntrinsicSymbols; + } + /// Set value for a symbol. void setSymbolValue(MCStreamer &Streamer, StringRef Sym, uint64_t Val); 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 @@ -20,6 +20,7 @@ #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" @@ -1528,6 +1529,12 @@ emitVisibility(Name, V, false); } + // Emit linkage for llvm intrinsic function entry point symbol. + if (TM.getTargetTriple().isOSBinFormatXCOFF()) { + for (auto Sym : OutContext.getXCOFFIntrinsicExternSymbol()) { + OutStreamer->emitSymbolAttribute(Sym, MCSA_Extern); + } + } // Emit the remarks section contents. // FIXME: Figure out when is the safest time to emit this section. It should // not come after debug info. diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -26,6 +26,7 @@ #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/None.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" @@ -5270,7 +5271,10 @@ return getAIXFuncEntryPointSymbolSDNode(F->getName(), F->isDeclaration(), SC); } - + auto &Context = DAG.getMachineFunction().getMMI().getContext(); + MCSymbolXCOFF *Sym = cast( + Context.getOrCreateSymbol(Twine(".") + Twine(SymName))); + Context.getXCOFFIntrinsicExternSymbol().insert(Sym); return getAIXFuncEntryPointSymbolSDNode(SymName, true, XCOFF::C_EXT); } diff --git a/llvm/test/CodeGen/PowerPC/aix-llvm-intrinsic.ll b/llvm/test/CodeGen/PowerPC/aix-llvm-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-llvm-intrinsic.ll @@ -0,0 +1,194 @@ +; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \ +; RUN: -mattr=-altivec < %s | FileCheck --check-prefixes=COMMON,BIT32 %s + +; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff -mcpu=pwr4 \ +; RUN: -mattr=-altivec < %s | FileCheck --check-prefixes=COMMON,BIT64 %s + +; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \ +; RUN: -mattr=-altivec -filetype=obj -o %t.o < %s +; RUN: llvm-readobj --symbols %t.o | FileCheck --check-prefix=CHECKSYM %s + +; RUN: not --crash llc -verify-machineinstrs -mcpu=pwr4 -mtriple powerpc64-ibm-aix-xcoff \ +; RUN: -mattr=-altivec -filetype=obj -o %t.o 2>&1 < %s | FileCheck --check-prefix=XCOFF64 %s +; XCOFF64: LLVM ERROR: 64-bit XCOFF object files are not supported yet. + +%struct.S = type { i32, i32 } + +@s = external global %struct.S, align 4 + +define void @bar() { +entry: + %0 = load i32, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 1), align 4 + %1 = trunc i32 %0 to i8 + %2 = load i32, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 1), align 4 + call void @llvm.memset.p0i8.i32(i8* align 4 bitcast (%struct.S* @s to i8*), i8 %1, i32 %2, i1 false) + ret void +} + +declare void @llvm.memset.p0i8.i32(i8* nocapture writeonly, i8, i32, i1 immarg) + +; COMMON: .globl bar[DS] # -- Begin function bar +; COMMON-NEXT: .globl .bar +; COMMON-NEXT: .align 4 +; COMMON-NEXT: .csect bar[DS] +; BIT32-NEXT: .long .bar # @bar +; BIT64-NEXT: .llong .bar # @bar +; BIT32-NEXT: .long TOC[TC0] +; BIT64-NEXT: .llong TOC[TC0] +; BIT32-NEXT: .long 0 +; BIT64-NEXT: .llong 0 +; COMMON-NEXT: .csect .text[PR] +; COMMON-NEXT: .bar: +; COMMON-NEXT: # %bb.0: # %entry +; COMMON-NEXT: mflr 0 +; COMMON: bl .memset + +; COMMON: .extern s[UA] +; COMMON-NEXT: .extern .memset +; COMMON-NEXT: .toc +; COMMON-NEXT: LC0: +; COMMON-NEXT: .tc s[TC],s[UA] + +; CHECKSYM: Symbols [ +; CHECKSYM-NEXT: Symbol { +; CHECKSYM-NEXT: Index: [[#Index:]] +; CHECKSYM-NEXT: Name: .memset +; CHECKSYM-NEXT: Value (RelocatableAddress): 0x0 +; CHECKSYM-NEXT: Section: N_UNDEF +; CHECKSYM-NEXT: Type: 0x0 +; CHECKSYM-NEXT: StorageClass: C_EXT (0x2) +; CHECKSYM-NEXT: NumberOfAuxEntries: 1 +; CHECKSYM-NEXT: CSECT Auxiliary Entry { +; CHECKSYM-NEXT: Index: [[#Index+1]] +; CHECKSYM-NEXT: SectionLen: 0 +; CHECKSYM-NEXT: ParameterHashIndex: 0x0 +; CHECKSYM-NEXT: TypeChkSectNum: 0x0 +; CHECKSYM-NEXT: SymbolAlignmentLog2: 0 +; CHECKSYM-NEXT: SymbolType: XTY_ER (0x0) +; CHECKSYM-NEXT: StorageMappingClass: XMC_PR (0x0) +; CHECKSYM-NEXT: StabInfoIndex: 0x0 +; CHECKSYM-NEXT: StabSectNum: 0x0 +; CHECKSYM-NEXT: } +; CHECKSYM-NEXT: } +; CHECKSYM-NEXT: Symbol { +; CHECKSYM-NEXT: Index: [[#Index+2]] +; CHECKSYM-NEXT: Name: s +; CHECKSYM-NEXT: Value (RelocatableAddress): 0x0 +; CHECKSYM-NEXT: Section: N_UNDEF +; CHECKSYM-NEXT: Type: 0x0 +; CHECKSYM-NEXT: StorageClass: C_EXT (0x2) +; CHECKSYM-NEXT: NumberOfAuxEntries: 1 +; CHECKSYM-NEXT: CSECT Auxiliary Entry { +; CHECKSYM-NEXT: Index: [[#Index+3]] +; CHECKSYM-NEXT: SectionLen: 0 +; CHECKSYM-NEXT: ParameterHashIndex: 0x0 +; CHECKSYM-NEXT: TypeChkSectNum: 0x0 +; CHECKSYM-NEXT: SymbolAlignmentLog2: 0 +; CHECKSYM-NEXT: SymbolType: XTY_ER (0x0) +; CHECKSYM-NEXT: StorageMappingClass: XMC_UA (0x4) +; CHECKSYM-NEXT: StabInfoIndex: 0x0 +; CHECKSYM-NEXT: StabSectNum: 0x0 +; CHECKSYM-NEXT: } +; CHECKSYM-NEXT: } +; CHECKSYM-NEXT: Symbol { +; CHECKSYM-NEXT: Index: [[#Index+4]] +; CHECKSYM-NEXT: Name: .text +; CHECKSYM-NEXT: Value (RelocatableAddress): 0x0 +; CHECKSYM-NEXT: Section: .text +; CHECKSYM-NEXT: Type: 0x0 +; CHECKSYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; CHECKSYM-NEXT: NumberOfAuxEntries: 1 +; CHECKSYM-NEXT: CSECT Auxiliary Entry { +; CHECKSYM-NEXT: Index: [[#Index+5]] +; CHECKSYM-NEXT: SectionLen: 48 +; CHECKSYM-NEXT: ParameterHashIndex: 0x0 +; CHECKSYM-NEXT: TypeChkSectNum: 0x0 +; CHECKSYM-NEXT: SymbolAlignmentLog2: 4 +; CHECKSYM-NEXT: SymbolType: XTY_SD (0x1) +; CHECKSYM-NEXT: StorageMappingClass: XMC_PR (0x0) +; CHECKSYM-NEXT: StabInfoIndex: 0x0 +; CHECKSYM-NEXT: StabSectNum: 0x0 +; CHECKSYM-NEXT: } +; CHECKSYM-NEXT: } +; CHECKSYM-NEXT: Symbol { +; CHECKSYM-NEXT: Index: [[#Index+6]] +; CHECKSYM-NEXT: Name: .bar +; CHECKSYM-NEXT: Value (RelocatableAddress): 0x0 +; CHECKSYM-NEXT: Section: .text +; CHECKSYM-NEXT: Type: 0x0 +; CHECKSYM-NEXT: StorageClass: C_EXT (0x2) +; CHECKSYM-NEXT: NumberOfAuxEntries: 1 +; CHECKSYM-NEXT: CSECT Auxiliary Entry { +; CHECKSYM-NEXT: Index: [[#Index+7]] +; CHECKSYM-NEXT: ContainingCsectSymbolIndex: [[#Index+4]] +; CHECKSYM-NEXT: ParameterHashIndex: 0x0 +; CHECKSYM-NEXT: TypeChkSectNum: 0x0 +; CHECKSYM-NEXT: SymbolAlignmentLog2: 0 +; CHECKSYM-NEXT: SymbolType: XTY_LD (0x2) +; CHECKSYM-NEXT: StorageMappingClass: XMC_PR (0x0) +; CHECKSYM-NEXT: StabInfoIndex: 0x0 +; CHECKSYM-NEXT: StabSectNum: 0x0 +; CHECKSYM-NEXT: } +; CHECKSYM-NEXT: } +; CHECKSYM-NEXT: Symbol { +; CHECKSYM-NEXT: Index: [[#Index+8]] +; CHECKSYM-NEXT: Name: bar +; CHECKSYM-NEXT: Value (RelocatableAddress): 0x30 +; CHECKSYM-NEXT: Section: .data +; CHECKSYM-NEXT: Type: 0x0 +; CHECKSYM-NEXT: StorageClass: C_EXT (0x2) +; CHECKSYM-NEXT: NumberOfAuxEntries: 1 +; CHECKSYM-NEXT: CSECT Auxiliary Entry { +; CHECKSYM-NEXT: Index: [[#Index+9]] +; CHECKSYM-NEXT: SectionLen: 12 +; CHECKSYM-NEXT: ParameterHashIndex: 0x0 +; CHECKSYM-NEXT: TypeChkSectNum: 0x0 +; CHECKSYM-NEXT: SymbolAlignmentLog2: 2 +; CHECKSYM-NEXT: SymbolType: XTY_SD (0x1) +; CHECKSYM-NEXT: StorageMappingClass: XMC_DS (0xA) +; CHECKSYM-NEXT: StabInfoIndex: 0x0 +; CHECKSYM-NEXT: StabSectNum: 0x0 +; CHECKSYM-NEXT: } +; CHECKSYM-NEXT: } +; CHECKSYM-NEXT: Symbol { +; CHECKSYM-NEXT: Index: [[#Index+10]] +; CHECKSYM-NEXT: Name: TOC +; CHECKSYM-NEXT: Value (RelocatableAddress): 0x3C +; CHECKSYM-NEXT: Section: .data +; CHECKSYM-NEXT: Type: 0x0 +; CHECKSYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; CHECKSYM-NEXT: NumberOfAuxEntries: 1 +; CHECKSYM-NEXT: CSECT Auxiliary Entry { +; CHECKSYM-NEXT: Index: [[#Index+11]] +; CHECKSYM-NEXT: SectionLen: 0 +; CHECKSYM-NEXT: ParameterHashIndex: 0x0 +; CHECKSYM-NEXT: TypeChkSectNum: 0x0 +; CHECKSYM-NEXT: SymbolAlignmentLog2: 2 +; CHECKSYM-NEXT: SymbolType: XTY_SD (0x1) +; CHECKSYM-NEXT: StorageMappingClass: XMC_TC0 (0xF) +; CHECKSYM-NEXT: StabInfoIndex: 0x0 +; CHECKSYM-NEXT: StabSectNum: 0x0 +; CHECKSYM-NEXT: } +; CHECKSYM-NEXT: } +; CHECKSYM-NEXT: Symbol { +; CHECKSYM-NEXT: Index: [[#Index+12]] +; CHECKSYM-NEXT: Name: s +; CHECKSYM-NEXT: Value (RelocatableAddress): 0x3C +; CHECKSYM-NEXT: Section: .data +; CHECKSYM-NEXT: Type: 0x0 +; CHECKSYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; CHECKSYM-NEXT: NumberOfAuxEntries: 1 +; CHECKSYM-NEXT: CSECT Auxiliary Entry { +; CHECKSYM-NEXT: Index: [[#Index+13]] +; CHECKSYM-NEXT: SectionLen: 4 +; CHECKSYM-NEXT: ParameterHashIndex: 0x0 +; CHECKSYM-NEXT: TypeChkSectNum: 0x0 +; CHECKSYM-NEXT: SymbolAlignmentLog2: 2 +; CHECKSYM-NEXT: SymbolType: XTY_SD (0x1) +; CHECKSYM-NEXT: StorageMappingClass: XMC_TC (0x3) +; CHECKSYM-NEXT: StabInfoIndex: 0x0 +; CHECKSYM-NEXT: StabSectNum: 0x0 +; CHECKSYM-NEXT: } +; CHECKSYM-NEXT: } +; CHECKSYM-NEXT: ] +