[llvm] a03a6e9 - [AIX] [XCOFF] Add support for common and local common symbols in the TOC (#79530)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 31 13:34:25 PST 2024
Author: Zaara Syeda
Date: 2024-01-31T16:34:21-05:00
New Revision: a03a6e99647318a86ea398c42e241da43e3c550e
URL: https://github.com/llvm/llvm-project/commit/a03a6e99647318a86ea398c42e241da43e3c550e
DIFF: https://github.com/llvm/llvm-project/commit/a03a6e99647318a86ea398c42e241da43e3c550e.diff
LOG: [AIX] [XCOFF] Add support for common and local common symbols in the TOC (#79530)
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.
---------
Co-authored-by: Zaara Syeda <syzaara at ca.ibm.com>
Added:
llvm/test/CodeGen/PowerPC/basic-toc-data-private-linkage.ll
llvm/test/CodeGen/PowerPC/toc-data-common.ll
Modified:
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
llvm/lib/MC/MCSectionXCOFF.cpp
llvm/lib/MC/XCOFFObjectWriter.cpp
llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
llvm/test/CodeGen/PowerPC/basic-toc-data-local-linkage.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index a69b71451736f..b0cdd6321a5f9 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2424,8 +2424,10 @@ MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
if (GVar->hasAttribute("toc-data")) {
SmallString<128> Name;
getNameWithPrefix(Name, GO, TM);
+ XCOFF::SymbolType symType =
+ GO->hasCommonLinkage() ? XCOFF::XTY_CM : XCOFF::XTY_SD;
return getContext().getXCOFFSection(
- Name, Kind, XCOFF::CsectProperties(XCOFF::XMC_TD, XCOFF::XTY_SD),
+ Name, Kind, XCOFF::CsectProperties(XCOFF::XMC_TD, symType),
/* MultiSymbolsAllowed*/ true);
}
diff --git a/llvm/lib/MC/MCSectionXCOFF.cpp b/llvm/lib/MC/MCSectionXCOFF.cpp
index 02b1b972f339b..95d32e3580e3f 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 343e2fc877bc3..11f8a72edeada 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 528267cb01329..ce600654df72a 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -2571,12 +2571,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;
}
@@ -2737,8 +2743,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 24e067f2ebfba..9fad96340737c 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 0e131672b421e..4352852533ffb 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
diff --git a/llvm/test/CodeGen/PowerPC/basic-toc-data-private-linkage.ll b/llvm/test/CodeGen/PowerPC/basic-toc-data-private-linkage.ll
new file mode 100644
index 0000000000000..a3831d8f0f3c8
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/basic-toc-data-private-linkage.ll
@@ -0,0 +1,15 @@
+; RUN: not --crash 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: < %s 2>&1 | FileCheck %s
+
+ at iprivate = private global i32 55 #0
+
+define nonnull ptr @get() local_unnamed_addr {
+entry:
+ ret ptr @iprivate
+}
+
+attributes #0 = { "toc-data" }
+
+; CHECK: LLVM ERROR: A GlobalVariable with private linkage is not currently supported by the toc data transformation.
diff --git a/llvm/test/CodeGen/PowerPC/toc-data-common.ll b/llvm/test/CodeGen/PowerPC/toc-data-common.ll
new file mode 100644
index 0000000000000..7747f2eecc935
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/toc-data-common.ll
@@ -0,0 +1,148 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs < %s | FileCheck %s -DINSTR=lwz --check-prefix=CHECK
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs < %s | FileCheck %s -DINSTR=ld --check-prefix=CHECK
+
+; RUN: llc -filetype=obj -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs < %s -o %t32.o
+; RUN: llvm-objdump -t --symbol-description %t32.o | FileCheck %s --check-prefix=OBJ32
+
+; RUN: llc -filetype=obj -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs < %s -o %t64.o
+; RUN: llvm-objdump -t --symbol-description %t64.o | FileCheck %s --check-prefix=OBJ64
+
+ at a1 = common global i32 0, align 4 #0
+ at a2 = global i32 0, align 4 #0
+ at a3 = common global i32 0, align 4
+ at a4 = global i32 0, align 4
+
+define void @set(i32 noundef %_a) {
+; CHECK-LABEL: set:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: la 4, a2[TD](2)
+; CHECK-NEXT: la 5, a1[TD](2)
+; CHECK-NEXT: stw 3, 0(4)
+; CHECK-NEXT: [[INSTR]] 4, L..C0(2) # @a4
+; CHECK-NEXT: stw 3, 0(5)
+; CHECK-NEXT: [[INSTR]] 5, L..C1(2) # @a3
+; CHECK-NEXT: stw 3, 0(4)
+; CHECK-NEXT: stw 3, 0(5)
+; CHECK-NEXT: blr
+entry:
+store i32 %_a, ptr @a2, align 4
+store i32 %_a, ptr @a1, align 4
+store i32 %_a, ptr @a4, align 4
+store i32 %_a, ptr @a3, align 4
+ret void
+}
+
+define i32 @get1() {
+; CHECK-LABEL: get1:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: la 3, a2[TD](2)
+; CHECK-NEXT: lwz 3, 0(3)
+; CHECK-NEXT: blr
+entry:
+%0 = load i32, ptr @a2, align 4
+ret i32 %0
+}
+
+define i32 @get2() {
+; CHECK-LABEL: get2:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: la 3, a1[TD](2)
+; CHECK-NEXT: lwz 3, 0(3)
+; CHECK-NEXT: blr
+entry:
+%0 = load i32, ptr @a1, align 4
+ret i32 %0
+}
+
+define i32 @get3() {
+; CHECK-LABEL: get3:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: [[INSTR]] 3, L..C0(2) # @a4
+; CHECK-NEXT: lwz 3, 0(3)
+; CHECK-NEXT: blr
+entry:
+%0 = load i32, ptr @a4, align 4
+ret i32 %0
+}
+
+define i32 @get4() {
+; CHECK-LABEL: get4:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: [[INSTR]] 3, L..C1(2) # @a3
+; CHECK-NEXT: lwz 3, 0(3)
+; CHECK-NEXT: blr
+entry:
+%0 = load i32, ptr @a3, align 4
+ret i32 %0
+}
+
+define nonnull ptr @escape1() {
+; CHECK-LABEL: escape1:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: la 3, a2[TD](2)
+; CHECK-NEXT: blr
+entry:
+ret ptr @a2
+}
+
+define nonnull ptr @escape2() {
+; CHECK-LABEL: escape2:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: la 3, a1[TD](2)
+; CHECK-NEXT: blr
+entry:
+ret ptr @a1
+}
+
+define nonnull ptr @escape3() {
+; CHECK-LABEL: escape3:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: [[INSTR]] 3, L..C0(2) # @a4
+; CHECK-NEXT: blr
+entry:
+ret ptr @a4
+}
+
+define nonnull ptr @escape4() {
+; CHECK-LABEL: escape4:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: [[INSTR]] 3, L..C1(2) # @a3
+; CHECK-NEXT: blr
+entry:
+ret ptr @a3
+}
+
+attributes #0 = { "toc-data" }
+
+; CHECK: .comm a3[RW],4,2 # @a3
+; CHECK-NEXT: .csect a4[RW],2
+; CHECK-NEXT: .globl a4[RW] # @a4
+; CHECK-NEXT: .align 2
+; CHECK-NEXT: .vbyte 4, 0 # 0x0
+; CHECK-NEXT: .toc
+; CHECK-LABEL: L..C0:
+; CHECK-NEXT: .tc a4[TC],a4[RW]
+; CHECK-LABEL: L..C1:
+; CHECK-NEXT: .tc a3[TC],a3[RW]
+; CHECK-NEXT: .csect a2[TD],2
+; CHECK-NEXT: .globl a2[TD] # @a2
+; CHECK-NEXT: .align 2
+; CHECK-NEXT: .vbyte 4, 0 # 0x0
+; CHECK-NEXT: .comm a1[TD],4,2 # @a1
+
+; OBJ32: {{([[:xdigit:]]{8})}} g O .data 00000004 (idx: {{[0-9]+}}) a4[RW]
+; OBJ32-LABEL: {{([[:xdigit:]]{8})}} l .data 00000000 (idx: {{[0-9]+}}) TOC[TC0]
+; OBJ32-NEXT: {{([[:xdigit:]]{8})}} l O .data 00000004 (idx: {{[0-9]+}}) a4[TC]
+; OBJ32-NEXT: {{([[:xdigit:]]{8})}} l O .data 00000004 (idx: {{[0-9]+}}) a3[TC]
+; OBJ32-NEXT: {{([[:xdigit:]]{8})}} g O .data 00000004 (idx: {{[0-9]+}}) a2[TD]
+; OBJ32-NEXT: {{([[:xdigit:]]{8})}} g O *COM* 00000004 (idx: {{[0-9]+}}) a1[TD]
+; OBJ32-NEXT: {{([[:xdigit:]]{8})}} g O *COM* 00000004 (idx: {{[0-9]+}}) a3[RW]
+
+; OBJ64: {{([[:xdigit:]]{16})}} g O .data 0000000000000004 (idx: {{[0-9]+}}) a4[RW]
+; OBJ64-LABEL: {{([[:xdigit:]]{16})}} l .data 0000000000000000 (idx: {{[0-9]+}}) TOC[TC0]
+; OBJ64-NEXT: {{([[:xdigit:]]{16})}} l O .data 0000000000000008 (idx: {{[0-9]+}}) a4[TC]
+; OBJ64-NEXT: {{([[:xdigit:]]{16})}} l O .data 0000000000000008 (idx: {{[0-9]+}}) a3[TC]
+; OBJ64-NEXT: {{([[:xdigit:]]{16})}} g O .data 0000000000000004 (idx: {{[0-9]+}}) a2[TD]
+; OBJ64-NEXT: {{([[:xdigit:]]{16})}} g O *COM* 0000000000000004 (idx: {{[0-9]+}}) a1[TD]
+; OBJ64-NEXT: {{([[:xdigit:]]{16})}} g O *COM* 0000000000000004 (idx: {{[0-9]+}}) a3[RW]
More information about the llvm-commits
mailing list