[compiler-rt] 18dc8dc - [PowerPC][JITLink] Support R_PPC64_GOT_TLSGD_PCREL34 (#68660)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 13 19:57:09 PDT 2023
Author: Kai Luo
Date: 2023-10-14T10:57:03+08:00
New Revision: 18dc8dcd768fd99f29d21d3fa1603d299c686da1
URL: https://github.com/llvm/llvm-project/commit/18dc8dcd768fd99f29d21d3fa1603d299c686da1
DIFF: https://github.com/llvm/llvm-project/commit/18dc8dcd768fd99f29d21d3fa1603d299c686da1.diff
LOG: [PowerPC][JITLink] Support R_PPC64_GOT_TLSGD_PCREL34 (#68660)
`R_PPC64_GOT_TLSGD_PCREL34` is generated for pwr10+.
Added:
compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-main.cpp
compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-pwr10.cpp
compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test
Modified:
llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h
llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
llvm/lib/ExecutionEngine/JITLink/ppc64.cpp
llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s
Removed:
################################################################################
diff --git a/compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-main.cpp b/compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-main.cpp
new file mode 100644
index 000000000000000..d6757fdd4154c7e
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-main.cpp
@@ -0,0 +1,30 @@
+#include <fstream>
+#include <iostream>
+#include <string>
+
+thread_local int x = 0;
+thread_local int y = 1;
+thread_local int z = -1;
+
+extern int TestPOWER10();
+
+int Test() { return x + y + z; }
+
+static bool CPUModelIsPOWER10() {
+ std::string line;
+ std::ifstream cpuinfo("/proc/cpuinfo", std::ios::in);
+ if (!cpuinfo.is_open())
+ return false;
+ while (std::getline(cpuinfo, line)) {
+ if (line.find("cpu") != std::string::npos &&
+ line.find("POWER10") != std::string::npos)
+ return true;
+ }
+ return false;
+}
+
+int main() {
+ if (CPUModelIsPOWER10())
+ return TestPOWER10();
+ return Test();
+}
diff --git a/compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-pwr10.cpp b/compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-pwr10.cpp
new file mode 100644
index 000000000000000..a6fb3088af62998
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-pwr10.cpp
@@ -0,0 +1,5 @@
+extern thread_local int x;
+extern thread_local int y;
+extern thread_local int z;
+
+int __attribute__((target("arch=pwr10"))) TestPOWER10() { return x + y + z; }
diff --git a/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test b/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test
new file mode 100644
index 000000000000000..93561b1645c3322
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: %clangxx -fPIC -c -o %t/main.o %S/Inputs/trivial-tls-main.cpp
+// RUN: %clangxx -fPIC -c -o %t/pwr10.o %S/Inputs/trivial-tls-pwr10.cpp
+// RUN: %llvm_jitlink %t/main.o %t/pwr10.o
+// FIXME: We seperate pwr10 code from main object file due to currrent
+// implementation only supports one PLT stub for the same symbol.
+// For example, `bl __tls_get_addr` in one object file has only one PLT stub,
+// however we need another
diff erent PLT stub for `bl __tls_get_addr at notoc`
+// whose target symbol is also `__tls_get_addr`.
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h b/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h
index ff932f6022bdc88..b72391445598614 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h
@@ -61,6 +61,7 @@ enum EdgeKind_ppc64 : Edge::Kind {
RequestCallNoTOC,
RequestTLSDescInGOTAndTransformToTOCDelta16HA,
RequestTLSDescInGOTAndTransformToTOCDelta16LO,
+ RequestTLSDescInGOTAndTransformToDelta34,
};
enum PLTCallStubKind {
@@ -202,6 +203,10 @@ class PLTTableManager : public TableManager<PLTTableManager<Endianness>> {
static StringRef getSectionName() { return "$__STUBS"; }
+ // FIXME: One external symbol can only have one PLT stub in a object file.
+ // This is a limitation when we need
diff erent PLT stubs for the same symbol.
+ // For example, we need two
diff erent PLT stubs for `bl __tls_get_addr` and
+ // `bl __tls_get_addr at notoc`.
bool visitEdge(LinkGraph &G, Block *B, Edge &E) {
bool isExternal = E.getTarget().isExternal();
Edge::Kind K = E.getKind();
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
index bf1d22ac9a43057..25b1dd9d3d12539 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
@@ -43,17 +43,22 @@ class TLSInfoTableManager_ELF_ppc64
bool visitEdge(LinkGraph &G, Block *B, Edge &E) {
Edge::Kind K = E.getKind();
- if (K == ppc64::RequestTLSDescInGOTAndTransformToTOCDelta16HA) {
+ switch (K) {
+ case ppc64::RequestTLSDescInGOTAndTransformToTOCDelta16HA:
E.setKind(ppc64::TOCDelta16HA);
E.setTarget(this->getEntryForTarget(G, E.getTarget()));
return true;
- }
- if (K == ppc64::RequestTLSDescInGOTAndTransformToTOCDelta16LO) {
+ case ppc64::RequestTLSDescInGOTAndTransformToTOCDelta16LO:
E.setKind(ppc64::TOCDelta16LO);
E.setTarget(this->getEntryForTarget(G, E.getTarget()));
return true;
+ case ppc64::RequestTLSDescInGOTAndTransformToDelta34:
+ E.setKind(ppc64::Delta34);
+ E.setTarget(this->getEntryForTarget(G, E.getTarget()));
+ return true;
+ default:
+ return false;
}
- return false;
}
Symbol &createEntry(LinkGraph &G, Symbol &Target) {
@@ -234,10 +239,15 @@ class ELFLinkGraphBuilder_ppc64
if (ELFReloc == ELF::R_PPC64_TLSLD)
return make_error<StringError>("Local-dynamic TLS model is not supported",
inconvertibleErrorCode());
+
if (ELFReloc == ELF::R_PPC64_PCREL_OPT)
// TODO: Support PCREL optimization, now ignore it.
return Error::success();
+ if (ELFReloc == ELF::R_PPC64_TPREL34)
+ return make_error<StringError>("Local-exec TLS model is not supported",
+ inconvertibleErrorCode());
+
auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
if (!ObjSymbol)
return ObjSymbol.takeError();
@@ -372,6 +382,9 @@ class ELFLinkGraphBuilder_ppc64
case ELF::R_PPC64_GOT_TLSGD16_LO:
Kind = ppc64::RequestTLSDescInGOTAndTransformToTOCDelta16LO;
break;
+ case ELF::R_PPC64_GOT_TLSGD_PCREL34:
+ Kind = ppc64::RequestTLSDescInGOTAndTransformToDelta34;
+ break;
}
Edge GE(Kind, Offset, *GraphSymbol, Addend);
diff --git a/llvm/lib/ExecutionEngine/JITLink/ppc64.cpp b/llvm/lib/ExecutionEngine/JITLink/ppc64.cpp
index ac4a62a503919e2..27484aaf205901f 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ppc64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ppc64.cpp
@@ -134,6 +134,8 @@ const char *getEdgeKindName(Edge::Kind K) {
return "RequestTLSDescInGOTAndTransformToTOCDelta16HA";
case RequestTLSDescInGOTAndTransformToTOCDelta16LO:
return "RequestTLSDescInGOTAndTransformToTOCDelta16LO";
+ case RequestTLSDescInGOTAndTransformToDelta34:
+ return "RequestTLSDescInGOTAndTransformToDelta34";
default:
return getGenericEdgeKindName(static_cast<Edge::Kind>(K));
}
diff --git a/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s b/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s
index bcee29d1d34f60c..8f28a8662cbd67c 100644
--- a/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s
+++ b/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s
@@ -1,3 +1,4 @@
+# REQUIRES: system-linux
# RUN: rm -rf %t && mkdir -p %t
# RUN: llvm-mc --triple=powerpc64le-unknown-linux-gnu --filetype=obj -o \
# RUN: %t/elf_reloc.o --defsym LE=1 %s
@@ -9,6 +10,7 @@
# RUN: --abs external_addr16_data=0x6000 \
# RUN: --abs external_addr32_data=0x36668840 \
# RUN: --abs pcrel_external_var=0x36668860 \
+# RUN: --abs pcrel_external_tls=0x36668880 \
# RUN: --check %s %t/elf_reloc.o
# RUN: llvm-mc --triple=powerpc64-unknown-linux-gnu --filetype=obj -o \
# RUN: %t/elf_reloc.o %s
@@ -20,6 +22,7 @@
# RUN: --abs external_addr16_data=0x6000 \
# RUN: --abs external_addr32_data=0x36668840 \
# RUN: --abs pcrel_external_var=0x36668860 \
+# RUN: --abs pcrel_external_tls=0x36668880 \
# RUN: --check %s %t/elf_reloc.o
# jitlink-check: section_addr(elf_reloc.o, $__GOT) + 0x8000 = __TOC__
@@ -255,6 +258,22 @@ reloc_got_pcrel34:
blr
.size reloc_got_pcrel34,.-reloc_got_pcrel34
+ .global reloc_tlsgd_pcrel34
+ .p2align 4
+ .type reloc_tlsgd_pcrel34, at function
+reloc_tlsgd_pcrel34:
+ mflr 0
+ std 0, 16(1)
+ stdu 1, -32(1)
+ paddi 3, 0, pcrel_external_tls at got@tlsgd at pcrel, 1
+ bl __tls_get_addr at notoc(a at tlsgd)
+ lwa 3, 0(3)
+ addi 1, 1, 32
+ ld 0, 16(1)
+ mtlr 0
+ blr
+ .size reloc_tlsgd_pcrel34,.-reloc_tlsgd_pcrel34
+
.type .L.str, at object
.section .rodata.str1.1,"aMS", at progbits,1
.L.str:
More information about the llvm-commits
mailing list