[llvm] [AIX] Handle toc-data offset overflowing 16-bits (PR #80092)
Zaara Syeda via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 30 18:58:52 PST 2024
https://github.com/syzaara created https://github.com/llvm/llvm-project/pull/80092
When the toc-data offset overflows the 16-bits, we can truncate the value to the 16-bit value as the linker will handle overflow through fixup code.
>From becb7cf5d662e3a885801e5236d977b240a6626f Mon Sep 17 00:00:00 2001
From: Zaara Syeda <syzaara at cpap8104.rtp.raleigh.ibm.com>
Date: Tue, 30 Jan 2024 21:56:46 -0500
Subject: [PATCH] [AIX] Handle toc-data offset overflowing 16-bits
When the toc-data offset overflows the 16-bits, we
can truncate the value to the 16-bit value as the linker
will handle overflow through fixup code.
---
llvm/lib/MC/XCOFFObjectWriter.cpp | 23 ++++++--
.../CodeGen/PowerPC/aix-overflow-toc-data.py | 59 +++++++++++++++++++
2 files changed, 78 insertions(+), 4 deletions(-)
create mode 100644 llvm/test/CodeGen/PowerPC/aix-overflow-toc-data.py
diff --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp
index 343e2fc877bc3..1a8ae755307f9 100644
--- a/llvm/lib/MC/XCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/XCOFFObjectWriter.cpp
@@ -718,11 +718,26 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
} else {
// The FixedValue should be the TOC entry offset from the TOC-base plus
// any constant offset value.
- const int64_t TOCEntryOffset = SectionMap[SymASec]->Address -
- TOCCsects.front().Address +
- Target.getConstant();
+ int64_t TOCEntryOffset = SectionMap[SymASec]->Address -
+ TOCCsects.front().Address + Target.getConstant();
+ // For small code model, if the TOCEntryOffset overflows the 16-bit value,
+ // we truncate it back down to 16 bits. The linker will be able to insert
+ // fix-up code when needed.
+ // For non toc-data symbols, we already did the truncation in
+ // PPCAsmPrinter.cpp through setting Target.getConstant() in the
+ // expression above by calling getTOCEntryLoadingExprForXCOFF for the
+ // various TOC PseudoOps.
+ // For toc-data symbols, we were not able to calculate the offset from
+ // the TOC in PPCAsmPrinter.cpp since the TOC has not been finalized at
+ // that point, so we are adjusting it here though
+ // llvm::SignExtend64<16>(TOCEntryOffset);
+ // TODO: Since the time that the handling for offsets over 16-bits was
+ // added in PPCAsmPrinter.cpp using getTOCEntryLoadingExprForXCOFF, the
+ // system assembler and linker have been updated to be able to handle the
+ // overflowing offsets, so we no longer need to keep
+ // getTOCEntryLoadingExprForXCOFF.
if (Type == XCOFF::RelocationType::R_TOC && !isInt<16>(TOCEntryOffset))
- report_fatal_error("TOCEntryOffset overflows in small code model mode");
+ TOCEntryOffset = llvm::SignExtend64<16>(TOCEntryOffset);
FixedValue = TOCEntryOffset;
}
diff --git a/llvm/test/CodeGen/PowerPC/aix-overflow-toc-data.py b/llvm/test/CodeGen/PowerPC/aix-overflow-toc-data.py
new file mode 100644
index 0000000000000..d271eb4fedeec
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-overflow-toc-data.py
@@ -0,0 +1,59 @@
+# UNSUPPORTED: expensive_checks, debug
+
+# RUN: %python %s > %t.ll
+# RUN: llc -mtriple powerpc-ibm-aix-xcoff -code-model=small -mcpu=pwr4 -mattr=-altivec -O0 < %t.ll | \
+# RUN: FileCheck --check-prefix=ASM32 %s
+
+# RUN: llc -mtriple powerpc64-ibm-aix-xcoff -code-model=small -mcpu=pwr4 -mattr=-altivec -O0 < %t.ll | \
+# RUN: FileCheck --check-prefix=ASM64 %s
+
+# RUN: llc -mtriple powerpc-ibm-aix-xcoff -code-model=small -mcpu=pwr4 -mattr=-altivec -O0 \
+# RUN: -filetype=obj -o %t.o < %t.ll
+# RUN: llvm-objdump --no-print-imm-hex -D -r --symbol-description %t.o | FileCheck --check-prefix=DIS32 %s
+
+# RUN: llc -mtriple powerpc64-ibm-aix-xcoff -code-model=small -mcpu=pwr4 -mattr=-altivec -O0 \
+# RUN: -filetype=obj -o %t.o < %t.ll
+# RUN: llvm-objdump --no-print-imm-hex -D -r --symbol-description %t.o | FileCheck --check-prefix=DIS64 %s
+
+numentries = 8195
+for x in range(0, numentries):
+ print("@a%d = global i32 0, align 4 #0" % (x))
+
+print("define void @foo() {")
+print("entry:")
+for x in range(0, numentries):
+ print("store i32 1, i32* @a%d, align 4" % (x))
+print("ret void")
+print("}")
+
+print("attributes #0 = { \"toc-data\" }")
+
+# 32-bit assembly check
+# ASM32: la 4, a0[TD](2)
+# ASM32: la 4, a1[TD](2)
+
+# ASM32: la 4, a8191[TD](2)
+# ASM32: la 4, a8192[TD](2)
+# ASM32: la 4, a8193[TD](2)
+
+# 64-bit assembly check
+# ASM64: la 4, a0[TD](2)
+# ASM64: la 4, a1[TD](2)
+
+# ASM64: la 4, a8191[TD](2)
+# ASM64: la 4, a8192[TD](2)
+# ASM64: la 4, a8193[TD](2)
+
+# DIS32: fffc: 38 82 7f fc addi 4, 2, 32764
+# DIS32: 0000fffe: R_TOC (idx: 16391) a8191[TD]
+# DIS32: 10004: 38 82 80 00 addi 4, 2, -32768
+# DIS32: 00010006: R_TOC (idx: 16393) a8192[TD]
+# DIS32: 1000c: 38 82 80 04 addi 4, 2, -32764
+# DIS32: 0001000e: R_TOC (idx: 16395) a8193[TD]
+
+# DIS64: fffc: 38 82 7f fc addi 4, 2, 32764
+# DIS64: 0000fffe: R_TOC (idx: 16391) a8191[TD]
+# DIS64: 10004: 38 82 80 00 addi 4, 2, -32768
+# DIS64: 00010006: R_TOC (idx: 16393) a8192[TD]
+# DIS64: 1000c: 38 82 80 04 addi 4, 2, -32764
+# DIS64: 0001000e: R_TOC (idx: 16395) a8193[TD]
More information about the llvm-commits
mailing list