[compiler-rt] [PowerPC][JITLink] Support R_PPC64_GOT_TLSGD_PCREL34 (PR #68660)

Kai Luo via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 12 22:24:33 PDT 2023


https://github.com/bzEq updated https://github.com/llvm/llvm-project/pull/68660

>From 91743f4062a89647f63c62fd006eec6319d8d203 Mon Sep 17 00:00:00 2001
From: Kai Luo <lkail at cn.ibm.com>
Date: Tue, 10 Oct 2023 12:56:08 +0800
Subject: [PATCH 1/8] Support R_PPC64_GOT_TLSGD_PCREL34

---
 .../llvm/ExecutionEngine/JITLink/ppc64.h       |  1 +
 llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp | 16 ++++++++++++----
 llvm/lib/ExecutionEngine/JITLink/ppc64.cpp     |  2 ++
 .../JITLink/ppc64/ELF_ppc64_relocations.s      | 18 ++++++++++++++++++
 4 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h b/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h
index ff932f6022bdc88..89a26b089a67b48 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 {
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
index a095059496dc15e..c04ebaf517deffa 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) {
@@ -372,6 +377,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..4a587435cbde8be 100644
--- a/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s
+++ b/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s
@@ -9,6 +9,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 +21,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 +257,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:

>From 5546eab719b9ff2d1f3d1c7c2cf05fbfa1f12a26 Mon Sep 17 00:00:00 2001
From: Kai Luo <lkail at cn.ibm.com>
Date: Wed, 11 Oct 2023 10:55:04 +0800
Subject: [PATCH 2/8] R_PPC64_TPREL34 unsupported

---
 llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
index c04ebaf517deffa..a54731ff7853537 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
@@ -239,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();

>From 99a765fdae7ffd3762caa6397d8be4d32aee8f46 Mon Sep 17 00:00:00 2001
From: Kai Luo <lkail at cn.ibm.com>
Date: Wed, 11 Oct 2023 12:54:39 +0800
Subject: [PATCH 3/8] No __tls_get_addr under windows

---
 llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s b/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s
index 4a587435cbde8be..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

>From c2f565ac7e3ce2617b8d319e1eb994aa86ea667e Mon Sep 17 00:00:00 2001
From: Kai Luo <lkail at cn.ibm.com>
Date: Fri, 13 Oct 2023 03:05:00 +0000
Subject: [PATCH 4/8] Add test case for host running on pwr10

---
 .../Linux/ppc64/trivial-tls-pwr10.cpp         | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.cpp

diff --git a/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.cpp b/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.cpp
new file mode 100644
index 000000000000000..de57a8c22f3a6c4
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.cpp
@@ -0,0 +1,35 @@
+// RUN: %clangxx -fPIC -c -o %t %s
+// RUN: %llvm_jitlink %t
+
+#include <fstream>
+#include <iostream>
+#include <string>
+
+thread_local int x = 0;
+thread_local int y = 1;
+thread_local int z = -1;
+
+static int __attribute__((target("arch=pwr10"))) TestPOWER10() {
+  return x + y + z;
+}
+
+static 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();
+}

>From 6847686dfd5a569ee4777d4a81be9d0f27ef4d9c Mon Sep 17 00:00:00 2001
From: Kai Luo <lkail at cn.ibm.com>
Date: Fri, 13 Oct 2023 04:54:54 +0000
Subject: [PATCH 5/8] Seperate modules

---
 .../trivial-tls-main.cpp}                                | 9 ++-------
 .../TestCases/Linux/ppc64/Inputs/trivial-tls-pwr10.cpp   | 5 +++++
 .../orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test     | 9 +++++++++
 3 files changed, 16 insertions(+), 7 deletions(-)
 rename compiler-rt/test/orc/TestCases/Linux/ppc64/{trivial-tls-pwr10.cpp => Inputs/trivial-tls-main.cpp} (74%)
 create mode 100644 compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-pwr10.cpp
 create mode 100644 compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test

diff --git a/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.cpp b/compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-main.cpp
similarity index 74%
rename from compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.cpp
rename to compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-main.cpp
index de57a8c22f3a6c4..d6757fdd4154c7e 100644
--- a/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.cpp
+++ b/compiler-rt/test/orc/TestCases/Linux/ppc64/Inputs/trivial-tls-main.cpp
@@ -1,6 +1,3 @@
-// RUN: %clangxx -fPIC -c -o %t %s
-// RUN: %llvm_jitlink %t
-
 #include <fstream>
 #include <iostream>
 #include <string>
@@ -9,11 +6,9 @@ thread_local int x = 0;
 thread_local int y = 1;
 thread_local int z = -1;
 
-static int __attribute__((target("arch=pwr10"))) TestPOWER10() {
-  return x + y + z;
-}
+extern int TestPOWER10();
 
-static int Test() { return x + y + z; }
+int Test() { return x + y + z; }
 
 static bool CPUModelIsPOWER10() {
   std::string line;
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..be7fa7832f728e4
--- /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 object fil from normal object file due to
+// currrent implementation only supports single PLT stub for the same symbol.
+// For example, `__tls_get_addr` in one object file has only one PLT stub,
+// however we need another one for `__tls_get_addr at notoc` which is not
+// implemented.

>From 60ba484b1642017a8415cff06017996a49aad901 Mon Sep 17 00:00:00 2001
From: Kai Luo <lkail at cn.ibm.com>
Date: Fri, 13 Oct 2023 04:58:55 +0000
Subject: [PATCH 6/8] Adjust comment

---
 .../orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test     | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

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
index be7fa7832f728e4..9afb47cb683c57a 100644
--- a/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test
+++ b/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test
@@ -2,8 +2,9 @@
 // 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 object fil from normal object file due to
+// FIXME: We seperate pwr10 object file from normal object file due to
 // currrent implementation only supports single PLT stub for the same symbol.
-// For example, `__tls_get_addr` in one object file has only one PLT stub,
-// however we need another one for `__tls_get_addr at notoc` which is not
-// implemented.
+// For example, `bl __tls_get_addr` in one object file has only one PLT stub,
+// however we need additional one for `bl __tls_get_addr at notoc` relocation
+// whose target symbol is also `__tls_get_addr`.
+

>From dcafa2842c987eacd223b8f48d96c79e37928e1a Mon Sep 17 00:00:00 2001
From: Kai Luo <lkail at cn.ibm.com>
Date: Fri, 13 Oct 2023 05:09:35 +0000
Subject: [PATCH 7/8] Adjust comment

---
 .../test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test  | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

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
index 9afb47cb683c57a..93561b1645c3322 100644
--- a/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test
+++ b/compiler-rt/test/orc/TestCases/Linux/ppc64/trivial-tls-pwr10.test
@@ -2,9 +2,8 @@
 // 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 object file from normal object file due to
-// currrent implementation only supports single PLT stub for the same symbol.
+// 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 additional one for `bl __tls_get_addr at notoc` relocation
+// however we need another different PLT stub for `bl __tls_get_addr at notoc`
 // whose target symbol is also `__tls_get_addr`.
-

>From ffaeaa5a32a33dbf48c6e250e7fff75b56ec0002 Mon Sep 17 00:00:00 2001
From: Kai Luo <lkail at cn.ibm.com>
Date: Fri, 13 Oct 2023 05:24:18 +0000
Subject: [PATCH 8/8] Add FIXME

---
 llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h b/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h
index 89a26b089a67b48..b72391445598614 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h
@@ -203,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 different PLT stubs for the same symbol.
+  // For example, we need two different 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();



More information about the llvm-commits mailing list