Index: lib/MC/MCSectionXCOFF.cpp =================================================================== --- lib/MC/MCSectionXCOFF.cpp +++ lib/MC/MCSectionXCOFF.cpp @@ -72,6 +72,11 @@ } if (isCsect() && getMappingClass() == XCOFF::XMC_TD) { + // Common csect type (uninitialized storage) does not have to print csect + // directive for section switching unless it is local. + if (getKind().isCommon() && !getKind().isBSSLocal()) + return; + assert((getKind().isBSSExtern() || getKind().isBSSLocal() || getKind().isReadOnlyWithRel()) && "Unexepected section kind for toc-data"); @@ -126,5 +131,7 @@ return false; assert(isCsect() && "Handling for isVirtualSection not implemented for this section!"); - return XCOFF::XTY_CM == CsectProp->Type; + // XTY_CM sections are virtual except for toc-data symbols. + return (XCOFF::XTY_CM == CsectProp->Type) && + (getMappingClass() != XCOFF::XMC_TD); } Index: lib/MC/XCOFFObjectWriter.cpp =================================================================== --- lib/MC/XCOFFObjectWriter.cpp +++ lib/MC/XCOFFObjectWriter.cpp @@ -467,9 +467,15 @@ return TOCCsects; case XCOFF::XMC_TC: case XCOFF::XMC_TE: - case XCOFF::XMC_TD: assert(XCOFF::XTY_SD == MCSec->getCSectType() && - "Only an initialized csect can contain TC entry."); + "A TOC symbol must be an initialized csect."); + assert(!TOCCsects.empty() && + "We should at least have a TOC-base in this CsectGroup."); + return TOCCsects; + case XCOFF::XMC_TD: + assert((XCOFF::XTY_SD == MCSec->getCSectType() || + XCOFF::XTY_CM == MCSec->getCSectType()) && + "Symbol type incompatible with toc-data."); assert(!TOCCsects.empty() && "We should at least have a TOC-base in this CsectGroup."); return TOCCsects; Index: lib/Target/PowerPC/PPCAsmPrinter.cpp =================================================================== --- lib/Target/PowerPC/PPCAsmPrinter.cpp +++ lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -2554,12 +2554,18 @@ GVSym->setStorageClass( TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV)); - if (GVKind.isBSSLocal() || GVKind.isThreadBSSLocal()) - OutStreamer->emitXCOFFLocalCommonSymbol( - OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()), Size, - GVSym, Alignment); - else + if (GVKind.isBSSLocal() && Csect->getMappingClass() == XCOFF::XMC_TD) { + OutStreamer->emitZeros(Size); + } else if (GVKind.isBSSLocal() || GVKind.isThreadBSSLocal()) { + assert(Csect->getMappingClass() != XCOFF::XMC_TD && + "BSS local toc-data already handled and TLS variables " + "incompatible with XMC_TD"); + OutStreamer->emitXCOFFLocalCommonSymbol( + OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()), Size, + GVSym, Alignment); + } else { OutStreamer->emitCommonSymbol(GVSym, Size, Alignment); + } return; } @@ -2702,8 +2708,17 @@ TS->emitTCEntry(*I.first.first, I.first.second); } - for (const auto *GV : TOCDataGlobalVars) - emitGlobalVariableHelper(GV); + // Traverse the list of global variables twice, emitting all of the + // non-common global variables before the common ones, as emitting a + // .comm directive changes the scope from .toc to the common symbol. + for (const auto *GV : TOCDataGlobalVars) { + if (!GV->hasCommonLinkage()) + emitGlobalVariableHelper(GV); + } + for (const auto *GV : TOCDataGlobalVars) { + if (GV->hasCommonLinkage()) + emitGlobalVariableHelper(GV); + } } bool PPCAIXAsmPrinter::doInitialization(Module &M) { Index: lib/Target/PowerPC/PPCISelDAGToDAG.cpp =================================================================== --- lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -549,12 +549,9 @@ "A GlobalVariable with size larger than a TOC entry is not currently " "supported by the toc data transformation."); - if (GV->hasLocalLinkage() || GV->hasPrivateLinkage()) - report_fatal_error("A GlobalVariable with private or local linkage is not " - "currently supported by the toc data transformation."); - - assert(!GV->hasCommonLinkage() && - "Tentative definitions cannot have the mapping class XMC_TD."); + if (GV->hasPrivateLinkage()) + report_fatal_error("A GlobalVariable with private linkage is not " + "currently supported by the toc data transformation."); return true; } Index: test/CodeGen/PowerPC/basic-toc-data-local-linkage.ll =================================================================== --- test/CodeGen/PowerPC/basic-toc-data-local-linkage.ll +++ test/CodeGen/PowerPC/basic-toc-data-local-linkage.ll @@ -1,6 +1,6 @@ -; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs \ +; RUN: llc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs \ ; RUN: < %s 2>&1 | FileCheck %s -; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs \ +; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs \ ; RUN: < %s 2>&1 | FileCheck %s @ilocal = internal global i32 0, align 4 #0 @@ -11,6 +11,8 @@ ret i32 %0 } -; CHECK: LLVM ERROR: A GlobalVariable with private or local linkage is not currently supported by the toc data transformation. - attributes #0 = { "toc-data" } + +; CHECK: .toc +; CHECK-NEXT: .csect ilocal[TD],2 +; CHECK-NEXT: .space 4