[llvm] r373009 - [AIX]Emit function descriptor csect in assembly
Xiangling Liao via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 26 12:38:32 PDT 2019
Author: xiangling_liao
Date: Thu Sep 26 12:38:32 2019
New Revision: 373009
URL: http://llvm.org/viewvc/llvm-project?rev=373009&view=rev
Log:
[AIX]Emit function descriptor csect in assembly
This patch emits the function descriptor csect for functions with definitions
under both 32-bit/64-bit mode on AIX.
Differential Revision: https://reviews.llvm.org/D66724
Added:
llvm/trunk/test/CodeGen/PowerPC/test_func_desc.ll
Modified:
llvm/trunk/include/llvm/CodeGen/AsmPrinter.h
llvm/trunk/include/llvm/MC/MCAsmInfo.h
llvm/trunk/include/llvm/MC/MCAsmInfoXCOFF.h
llvm/trunk/include/llvm/MC/MCDirectives.h
llvm/trunk/include/llvm/MC/MCSymbolXCOFF.h
llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/trunk/lib/MC/MCAsmInfoXCOFF.cpp
llvm/trunk/lib/MC/MCAsmStreamer.cpp
llvm/trunk/lib/MC/MCELFStreamer.cpp
llvm/trunk/lib/MC/MCMachOStreamer.cpp
llvm/trunk/lib/MC/MCSectionXCOFF.cpp
llvm/trunk/lib/MC/XCOFFObjectWriter.cpp
llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
llvm/trunk/test/CodeGen/PowerPC/aix-xcoff-common.ll
Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AsmPrinter.h?rev=373009&r1=373008&r2=373009&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h (original)
+++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h Thu Sep 26 12:38:32 2019
@@ -111,6 +111,10 @@ public:
/// of each call to runOnMachineFunction().
MCSymbol *CurrentFnSym = nullptr;
+ /// The symbol for the current function descriptor on AIX. This is created
+ /// at the beginning of each call to SetupMachineFunction().
+ MCSymbol *CurrentFnDescSym = nullptr;
+
/// The symbol used to represent the start of the current function for the
/// purpose of calculating its size (e.g. using the .size directive). By
/// default, this is equal to CurrentFnSym.
@@ -304,7 +308,7 @@ public:
/// This should be called when a new MachineFunction is being processed from
/// runOnMachineFunction.
- void SetupMachineFunction(MachineFunction &MF);
+ virtual void SetupMachineFunction(MachineFunction &MF);
/// This method emits the body and trailer for a function.
void EmitFunctionBody();
@@ -414,6 +418,10 @@ public:
virtual void EmitFunctionEntryLabel();
+ virtual void EmitFunctionDescriptor() {
+ llvm_unreachable("Function descriptor is target-specific.");
+ }
+
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
/// Targets can override this to change how global constants that are part of
Modified: llvm/trunk/include/llvm/MC/MCAsmInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAsmInfo.h?rev=373009&r1=373008&r2=373009&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAsmInfo.h (original)
+++ llvm/trunk/include/llvm/MC/MCAsmInfo.h Thu Sep 26 12:38:32 2019
@@ -317,6 +317,10 @@ protected:
/// Defaults to false.
bool HasLinkOnceDirective = false;
+ /// True if we have a .lglobl directive, which is used to emit the information
+ /// of a static symbol into the symbol table. Defaults to false.
+ bool HasDotLGloblDirective = false;
+
/// This attribute, if not MCSA_Invalid, is used to declare a symbol as having
/// hidden visibility. Defaults to MCSA_Hidden.
MCSymbolAttr HiddenVisibilityAttr = MCSA_Hidden;
@@ -392,6 +396,9 @@ protected:
// %hi(), and similar unary operators.
bool HasMipsExpressions = false;
+ // If true, emit function descriptor symbol on AIX.
+ bool NeedsFunctionDescriptors = false;
+
public:
explicit MCAsmInfo();
virtual ~MCAsmInfo();
@@ -565,6 +572,8 @@ public:
bool hasLinkOnceDirective() const { return HasLinkOnceDirective; }
+ bool hasDotLGloblDirective() const { return HasDotLGloblDirective; }
+
MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr; }
MCSymbolAttr getHiddenDeclarationVisibilityAttr() const {
@@ -647,6 +656,7 @@ public:
bool canRelaxRelocations() const { return RelaxELFRelocations; }
void setRelaxELFRelocations(bool V) { RelaxELFRelocations = V; }
bool hasMipsExpressions() const { return HasMipsExpressions; }
+ bool needsFunctionDescriptors() const { return NeedsFunctionDescriptors; }
};
} // end namespace llvm
Modified: llvm/trunk/include/llvm/MC/MCAsmInfoXCOFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAsmInfoXCOFF.h?rev=373009&r1=373008&r2=373009&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAsmInfoXCOFF.h (original)
+++ llvm/trunk/include/llvm/MC/MCAsmInfoXCOFF.h Thu Sep 26 12:38:32 2019
@@ -18,6 +18,11 @@ class MCAsmInfoXCOFF : public MCAsmInfo
protected:
MCAsmInfoXCOFF();
+
+public:
+ // Return true only when the identifier Name does not need quotes to be
+ // syntactically correct for XCOFF.
+ bool isValidUnquotedName(StringRef Name) const override;
};
} // end namespace llvm
Modified: llvm/trunk/include/llvm/MC/MCDirectives.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDirectives.h?rev=373009&r1=373008&r2=373009&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCDirectives.h (original)
+++ llvm/trunk/include/llvm/MC/MCDirectives.h Thu Sep 26 12:38:32 2019
@@ -28,6 +28,7 @@ enum MCSymbolAttr {
MCSA_ELF_TypeNoType, ///< .type _foo, STT_NOTYPE # aka @notype
MCSA_ELF_TypeGnuUniqueObject, /// .type _foo, @gnu_unique_object
MCSA_Global, ///< .globl
+ MCSA_LGlobal, ///< .lglobl (XCOFF)
MCSA_Hidden, ///< .hidden (ELF)
MCSA_IndirectSymbol, ///< .indirect_symbol (MachO)
MCSA_Internal, ///< .internal (ELF)
Modified: llvm/trunk/include/llvm/MC/MCSymbolXCOFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSymbolXCOFF.h?rev=373009&r1=373008&r2=373009&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCSymbolXCOFF.h (original)
+++ llvm/trunk/include/llvm/MC/MCSymbolXCOFF.h Thu Sep 26 12:38:32 2019
@@ -35,14 +35,14 @@ public:
return StorageClass.getValue();
}
- void setContainingCsect(const MCSectionXCOFF *C) {
+ void setContainingCsect(MCSectionXCOFF *C) {
assert((!ContainingCsect || ContainingCsect == C) &&
"Trying to set a containing csect that doesn't match the one that"
"this symbol is already mapped to.");
ContainingCsect = C;
}
- const MCSectionXCOFF *getContainingCsect() const {
+ MCSectionXCOFF *getContainingCsect() const {
assert(ContainingCsect &&
"Trying to get containing csect but none was set.");
return ContainingCsect;
@@ -50,7 +50,7 @@ public:
private:
Optional<XCOFF::StorageClass> StorageClass;
- const MCSectionXCOFF *ContainingCsect = nullptr;
+ MCSectionXCOFF *ContainingCsect = nullptr;
};
} // end namespace llvm
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=373009&r1=373008&r2=373009&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Thu Sep 26 12:38:32 2019
@@ -91,10 +91,12 @@
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCSectionXCOFF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolELF.h"
+#include "llvm/MC/MCSymbolXCOFF.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/SectionKind.h"
@@ -426,7 +428,10 @@ void AsmPrinter::EmitLinkage(const Globa
OutStreamer->EmitSymbolAttribute(GVSym, MCSA_Global);
return;
case GlobalValue::PrivateLinkage:
+ return;
case GlobalValue::InternalLinkage:
+ if (MAI->hasDotLGloblDirective())
+ OutStreamer->EmitSymbolAttribute(GVSym, MCSA_LGlobal);
return;
case GlobalValue::AppendingLinkage:
case GlobalValue::AvailableExternallyLinkage:
@@ -662,6 +667,10 @@ void AsmPrinter::EmitFunctionHeader() {
OutStreamer->SwitchSection(getObjFileLowering().SectionForGlobal(&F, TM));
EmitVisibility(CurrentFnSym, F.getVisibility());
+ if (MAI->needsFunctionDescriptors() &&
+ F.getLinkage() != GlobalValue::InternalLinkage)
+ EmitLinkage(&F, CurrentFnDescSym);
+
EmitLinkage(&F, CurrentFnSym);
if (MAI->hasFunctionAlignment())
EmitAlignment(MF->getAlignment(), &F);
@@ -697,8 +706,13 @@ void AsmPrinter::EmitFunctionHeader() {
}
}
- // Emit the CurrentFnSym. This is a virtual function to allow targets to
- // do their wild and crazy things as required.
+ // Emit the function descriptor. This is a virtual function to allow targets
+ // to emit their specific function descriptor.
+ if (MAI->needsFunctionDescriptors())
+ EmitFunctionDescriptor();
+
+ // Emit the CurrentFnSym. This is a virtual function to allow targets to do
+ // their wild and crazy things as required.
EmitFunctionEntryLabel();
// If the function had address-taken blocks that got deleted, then we have
@@ -1644,8 +1658,27 @@ MCSymbol *AsmPrinter::getCurExceptionSym
void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
this->MF = &MF;
+
// Get the function symbol.
- CurrentFnSym = getSymbol(&MF.getFunction());
+ if (MAI->needsFunctionDescriptors()) {
+ assert(TM.getTargetTriple().isOSAIX() && "Function descriptor is only"
+ " supported on AIX.");
+ assert(CurrentFnDescSym && "The function descriptor symbol needs to be"
+ " initalized first.");
+
+ // Get the function entry point symbol.
+ CurrentFnSym =
+ OutContext.getOrCreateSymbol("." + CurrentFnDescSym->getName());
+
+ const Function &F = MF.getFunction();
+ MCSectionXCOFF *FnEntryPointSec =
+ cast<MCSectionXCOFF>(getObjFileLowering().SectionForGlobal(&F, TM));
+ // Set the containing csect.
+ cast<MCSymbolXCOFF>(CurrentFnSym)->setContainingCsect(FnEntryPointSec);
+ } else {
+ CurrentFnSym = getSymbol(&MF.getFunction());
+ }
+
CurrentFnSymForSize = CurrentFnSym;
CurrentFnBegin = nullptr;
CurExceptionSym = nullptr;
Modified: llvm/trunk/lib/MC/MCAsmInfoXCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmInfoXCOFF.cpp?rev=373009&r1=373008&r2=373009&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmInfoXCOFF.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmInfoXCOFF.cpp Thu Sep 26 12:38:32 2019
@@ -20,5 +20,16 @@ MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
UseDotAlignForAlignment = true;
AsciiDirective = nullptr; // not supported
AscizDirective = nullptr; // not supported
+ NeedsFunctionDescriptors = true;
+ HasDotLGloblDirective = true;
Data64bitsDirective = "\t.llong\t";
+ SupportsQuotedNames = false;
+}
+
+bool MCAsmInfoXCOFF::isValidUnquotedName(StringRef Name) const {
+ // FIXME: Remove this function when we stop using "TOC[TC0]" as a symbol name.
+ if (Name.equals("TOC[TC0]"))
+ return true;
+
+ return MCAsmInfo::isValidUnquotedName(Name);
}
Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=373009&r1=373008&r2=373009&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Thu Sep 26 12:38:32 2019
@@ -650,6 +650,7 @@ bool MCAsmStreamer::EmitSymbolAttribute(
case MCSA_Global: // .globl/.global
OS << MAI->getGlobalDirective();
break;
+ case MCSA_LGlobal: OS << "\t.lglobl\t"; break;
case MCSA_Hidden: OS << "\t.hidden\t"; break;
case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
case MCSA_Internal: OS << "\t.internal\t"; break;
Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFStreamer.cpp?rev=373009&r1=373008&r2=373009&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCELFStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCELFStreamer.cpp Thu Sep 26 12:38:32 2019
@@ -277,6 +277,9 @@ bool MCELFStreamer::EmitSymbolAttribute(
case MCSA_AltEntry:
llvm_unreachable("ELF doesn't support the .alt_entry attribute");
+
+ case MCSA_LGlobal:
+ llvm_unreachable("ELF doesn't support the .lglobl attribute");
}
return true;
Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=373009&r1=373008&r2=373009&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Thu Sep 26 12:38:32 2019
@@ -330,6 +330,7 @@ bool MCMachOStreamer::EmitSymbolAttribut
case MCSA_Protected:
case MCSA_Weak:
case MCSA_Local:
+ case MCSA_LGlobal:
return false;
case MCSA_Global:
Modified: llvm/trunk/lib/MC/MCSectionXCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSectionXCOFF.cpp?rev=373009&r1=373008&r2=373009&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCSectionXCOFF.cpp (original)
+++ llvm/trunk/lib/MC/MCSectionXCOFF.cpp Thu Sep 26 12:38:32 2019
@@ -15,26 +15,46 @@ using namespace llvm;
MCSectionXCOFF::~MCSectionXCOFF() = default;
+static StringRef getMappingClassString(XCOFF::StorageMappingClass SMC) {
+ switch (SMC) {
+ case XCOFF::XMC_DS:
+ return "DS";
+ case XCOFF::XMC_RW:
+ return "RW";
+ case XCOFF::XMC_PR:
+ return "PR";
+ default:
+ report_fatal_error("Unhandled storage-mapping class.");
+ }
+}
+
void MCSectionXCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
raw_ostream &OS,
const MCExpr *Subsection) const {
if (getKind().isText()) {
if (getMappingClass() != XCOFF::XMC_PR)
- llvm_unreachable("Unsupported storage-mapping class for .text csect");
+ report_fatal_error("Unhandled storage-mapping class for .text csect");
OS << "\t.csect " << getSectionName() << "["
- << "PR"
+ << getMappingClassString(getMappingClass())
<< "]" << '\n';
return;
}
if (getKind().isData()) {
- assert(getMappingClass() == XCOFF::XMC_RW &&
- "Unhandled storage-mapping class for data section.");
-
- OS << "\t.csect " << getSectionName() << "["
- << "RW"
- << "]" << '\n';
+ switch (getMappingClass()) {
+ case XCOFF::XMC_RW:
+ case XCOFF::XMC_DS:
+ OS << "\t.csect " << getSectionName() << "["
+ << getMappingClassString(getMappingClass()) << "]" << '\n';
+ break;
+ case XCOFF::XMC_TC0:
+ OS << "\t.toc\n";
+ break;
+ default:
+ report_fatal_error(
+ "Unhandled storage-mapping class for .data csect.");
+ }
return;
}
Modified: llvm/trunk/lib/MC/XCOFFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/XCOFFObjectWriter.cpp?rev=373009&r1=373008&r2=373009&view=diff
==============================================================================
--- llvm/trunk/lib/MC/XCOFFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/XCOFFObjectWriter.cpp Thu Sep 26 12:38:32 2019
@@ -235,6 +235,9 @@ void XCOFFObjectWriter::executePostLayou
break;
}
report_fatal_error("Unhandled mapping of read-write csect to section.");
+ case XCOFF::XMC_TC0:
+ // TODO FIXME Handle emiting the TOC base.
+ break;
case XCOFF::XMC_BS:
assert(XCOFF::XTY_CM == MCSec->getCSectType() &&
"Mapping invalid csect. CSECT with bss storage class must be "
Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp?rev=373009&r1=373008&r2=373009&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Thu Sep 26 12:38:32 2019
@@ -167,7 +167,13 @@ public:
StringRef getPassName() const override { return "AIX PPC Assembly Printer"; }
+ void SetupMachineFunction(MachineFunction &MF) override;
+
void EmitGlobalVariable(const GlobalVariable *GV) override;
+
+ void EmitFunctionDescriptor() override;
+
+ void EmitEndOfAsmFile(Module &) override;
};
} // end anonymous namespace
@@ -1669,6 +1675,18 @@ bool PPCDarwinAsmPrinter::doFinalization
return AsmPrinter::doFinalization(M);
}
+void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) {
+ // Get the function descriptor symbol.
+ CurrentFnDescSym = getSymbol(&MF.getFunction());
+ // Set the containing csect.
+ MCSectionXCOFF *FnDescSec = OutStreamer->getContext().getXCOFFSection(
+ CurrentFnDescSym->getName(), XCOFF::XMC_DS, XCOFF::XTY_SD,
+ XCOFF::C_HIDEXT, SectionKind::getData());
+ cast<MCSymbolXCOFF>(CurrentFnDescSym)->setContainingCsect(FnDescSec);
+
+ return AsmPrinter::SetupMachineFunction(MF);
+}
+
void PPCAIXAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
// Early error checking limiting what is supported.
if (GV->isThreadLocal())
@@ -1718,6 +1736,45 @@ void PPCAIXAsmPrinter::EmitGlobalVariabl
EmitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer());
}
+void PPCAIXAsmPrinter::EmitFunctionDescriptor() {
+ const DataLayout &DL = getDataLayout();
+ const unsigned PointerSize = DL.getPointerSizeInBits() == 64 ? 8 : 4;
+
+ MCSectionSubPair Current = OutStreamer->getCurrentSection();
+ // Emit function descriptor.
+ OutStreamer->SwitchSection(
+ cast<MCSymbolXCOFF>(CurrentFnDescSym)->getContainingCsect());
+ OutStreamer->EmitLabel(CurrentFnDescSym);
+ // Emit function entry point address.
+ OutStreamer->EmitValue(MCSymbolRefExpr::create(CurrentFnSym, OutContext),
+ PointerSize);
+ // Emit TOC base address.
+ MCSymbol *TOCBaseSym = OutContext.getOrCreateSymbol(StringRef("TOC[TC0]"));
+ OutStreamer->EmitValue(MCSymbolRefExpr::create(TOCBaseSym, OutContext),
+ PointerSize);
+ // Emit a null environment pointer.
+ OutStreamer->EmitIntValue(0, PointerSize);
+
+ OutStreamer->SwitchSection(Current.first, Current.second);
+}
+
+void PPCAIXAsmPrinter::EmitEndOfAsmFile(Module &M) {
+ // If there are no functions in this module, we will never need to reference
+ // the TOC base.
+ if (M.empty())
+ return;
+
+ // Emit TOC base.
+ MCSymbol *TOCBaseSym = OutContext.getOrCreateSymbol(StringRef("TOC[TC0]"));
+ MCSectionXCOFF *TOCBaseSection = OutStreamer->getContext().getXCOFFSection(
+ StringRef("TOC"), XCOFF::XMC_TC0, XCOFF::XTY_SD, XCOFF::C_HIDEXT,
+ SectionKind::getData());
+ cast<MCSymbolXCOFF>(TOCBaseSym)->setContainingCsect(TOCBaseSection);
+ // Switch to section to emit TOC base.
+ OutStreamer->SwitchSection(TOCBaseSection);
+}
+
+
/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
/// for a MachineFunction to the given output stream, in a format that the
/// Darwin assembler can deal with.
Modified: llvm/trunk/test/CodeGen/PowerPC/aix-xcoff-common.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/aix-xcoff-common.ll?rev=373009&r1=373008&r2=373009&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/aix-xcoff-common.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/aix-xcoff-common.ll Thu Sep 26 12:38:32 2019
@@ -21,6 +21,8 @@
@array = common local_unnamed_addr global [33 x i8] zeroinitializer, align 1
+; CHECK-NOT: .toc
+
; CHECK: .csect .text[PR]
; CHECK-NEXT: .file
; CHECK-NEXT: .comm a,4,2
Added: llvm/trunk/test/CodeGen/PowerPC/test_func_desc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/test_func_desc.ll?rev=373009&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/test_func_desc.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/test_func_desc.ll Thu Sep 26 12:38:32 2019
@@ -0,0 +1,74 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefixes=CHECK,32BIT %s
+
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \
+; RUN: FileCheck --check-prefixes=CHECK,64BIT %s
+
+
+define i32 @foo() {
+entry:
+ ret i32 3
+}
+
+define i32 @main() {
+entry:
+ %0 = call i32 @foo()
+ %1 = call i32 bitcast (i32 (...)* @extern_foo to i32 ()*)()
+ %2 = call i32 @static_foo()
+ %3 = add nsw i32 %0, %1
+ %4 = add nsw i32 %3, %2
+ ret i32 %4
+}
+
+declare i32 @extern_foo(...)
+
+define internal i32 @static_foo() {
+entry:
+ ret i32 3
+}
+
+; CHECK: .globl foo
+; CHECK: .globl .foo
+; CHECK: .csect foo[DS]
+; CHECK-NEXT: foo:
+; 32BIT: .long .foo
+; 32BIT-NEXT: .long TOC[TC0]
+; 32BIT-NEXT: .long 0
+; 64BIT: .llong .foo
+; 64BIT-NEXT: .llong TOC[TC0]
+; 64BIT-NEXT: .llong 0
+; CHECK-NEXT: .csect .text[PR]
+; CHECK-LABEL: .foo:
+
+; CHECK: .globl main
+; CHECK: .globl .main
+; CHECK: .csect main[DS]
+; CHECK-NEXT: main:
+; 32BIT: .long .main
+; 32BIT-NEXT: .long TOC[TC0]
+; 32BIT-NEXT: .long 0
+; 64BIT: .llong .main
+; 64BIT-NEXT: .llong TOC[TC0]
+; 64BIT-NEXT: .llong 0
+; CHECK-NEXT: .csect .text[PR]
+; CHECK-LABEL: .main:
+; CHECK: bl .foo
+; CHECK: bl .extern_foo
+; CHECK: bl .static_foo
+
+; CHECK: .lglobl .static_foo
+; CHECK: .csect static_foo[DS]
+; CHECK-NEXT: static_foo:
+; 32BIT: .long .static_foo
+; 32BIT-NEXT: .long TOC[TC0]
+; 32BIT-NEXT: .long 0
+; 64BIT: .llong .static_foo
+; 64BIT-NEXT: .llong TOC[TC0]
+; 64BIT-NEXT: .llong 0
+; CHECK-NEXT: .csect .text[PR]
+; CHECK-LABEL: .static_foo:
+
+; CHECK-NOT: .csect extern_foo
+
+; CHECK: .toc
+; CHECK-NOT: .tc
More information about the llvm-commits
mailing list