[llvm] [AIX] [XCOFF] Add support for common and local common symbols in the TOC (PR #79530)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 25 16:38:43 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mc
Author: Zaara Syeda (syzaara)
<details>
<summary>Changes</summary>
This patch adds support for common and local symbols in the TOC for AIX. Note that we need to update isVirtualSection so as a common symbol in TOC will have the symbol type XTY_CM and will be initialized when placed in the TOC so sections with this type are no longer virtual.
---
Full diff: https://github.com/llvm/llvm-project/pull/79530.diff
5 Files Affected:
- (modified) llvm/lib/MC/MCSectionXCOFF.cpp (+8-1)
- (modified) llvm/lib/MC/XCOFFObjectWriter.cpp (+8-2)
- (modified) llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp (+19-4)
- (modified) llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (+2-5)
- (modified) llvm/test/CodeGen/PowerPC/basic-toc-data-local-linkage.ll (+6-4)
``````````diff
diff --git a/llvm/lib/MC/MCSectionXCOFF.cpp b/llvm/lib/MC/MCSectionXCOFF.cpp
index 02b1b972f339bf0..95d32e3580e3f55 100644
--- a/llvm/lib/MC/MCSectionXCOFF.cpp
+++ b/llvm/lib/MC/MCSectionXCOFF.cpp
@@ -82,6 +82,11 @@ void MCSectionXCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
}
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()) &&
"Unexepected section kind for toc-data");
printCsectDirective(OS);
@@ -135,5 +140,7 @@ bool MCSectionXCOFF::isVirtualSection() const {
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);
}
diff --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp
index 343e2fc877bc3b1..11f8a72edeadafc 100644
--- a/llvm/lib/MC/XCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/XCOFFObjectWriter.cpp
@@ -533,9 +533,15 @@ CsectGroup &XCOFFObjectWriter::getCsectGroup(const MCSectionXCOFF *MCSec) {
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;
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 4f15ba497d84c45..1f4476d3907cdd3 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -2572,12 +2572,18 @@ void PPCAIXAsmPrinter::emitGlobalVariableHelper(const GlobalVariable *GV) {
GVSym->setStorageClass(
TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV));
- if (GVKind.isBSSLocal() || GVKind.isThreadBSSLocal())
+ 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
+ } else {
OutStreamer->emitCommonSymbol(GVSym, Size, Alignment);
+ }
return;
}
@@ -2738,8 +2744,17 @@ void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
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) {
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index b57d185bb638b8c..b86c9abeecf35f8 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -551,13 +551,10 @@ static bool hasTocDataAttr(SDValue Val, unsigned PointerSize) {
"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 "
+ if (GV->hasPrivateLinkage())
+ report_fatal_error("A GlobalVariable with private linkage is not "
"currently supported by the toc data transformation.");
- assert(!GV->hasCommonLinkage() &&
- "Tentative definitions cannot have the mapping class XMC_TD.");
-
return true;
}
diff --git a/llvm/test/CodeGen/PowerPC/basic-toc-data-local-linkage.ll b/llvm/test/CodeGen/PowerPC/basic-toc-data-local-linkage.ll
index 0e131672b421e4b..4352852533ffb31 100644
--- a/llvm/test/CodeGen/PowerPC/basic-toc-data-local-linkage.ll
+++ b/llvm/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 @@ define dso_local i32 @read_i32_local_linkage() {
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/79530
More information about the llvm-commits
mailing list