https://github.com/Zhenhang1213 created 
https://github.com/llvm/llvm-project/pull/190885

Fixes https://github.com/llvm/llvm-project/issues/183916

>From 59e3e17964a88d16ac79222f0ba161fa77e46572 Mon Sep 17 00:00:00 2001
From: Austin <[email protected]>
Date: Wed, 8 Apr 2026 10:00:16 +0800
Subject: [PATCH] [arm] using indirection got not pc-relative

---
 clang/test/Driver/weak-symbol-pic.c | 17 +++++++++++++++++
 llvm/lib/Target/TargetMachine.cpp   |  9 +++++++++
 2 files changed, 26 insertions(+)
 create mode 100644 clang/test/Driver/weak-symbol-pic.c

diff --git a/clang/test/Driver/weak-symbol-pic.c 
b/clang/test/Driver/weak-symbol-pic.c
new file mode 100644
index 0000000000000..44b8a55f0f0de
--- /dev/null
+++ b/clang/test/Driver/weak-symbol-pic.c
@@ -0,0 +1,17 @@
+// RUN: %clang -fpic -S -target arm-linux-gnueabihf -o - %s | FileCheck %s
+// RUN: %clang -fpic -S -target armeb-linux-gnueabihf -o - %s | FileCheck %s
+
+// Test that weak symbols use GOT relocations in PIC mode on ARM.
+// This matches GCC behavior where weak symbols require GOT because they
+// can be preempted at runtime.
+
+// CHECK: xxx(GOT_PREL)
+
+void __attribute__((__weak__)) xxx(void);
+
+void call_func(void (*f)(void));
+
+int main() {
+  call_func(xxx);
+  return 0;
+}
\ No newline at end of file
diff --git a/llvm/lib/Target/TargetMachine.cpp 
b/llvm/lib/Target/TargetMachine.cpp
index 9243cdad43e1e..71602b2a262cd 100644
--- a/llvm/lib/Target/TargetMachine.cpp
+++ b/llvm/lib/Target/TargetMachine.cpp
@@ -212,6 +212,14 @@ bool TargetMachine::shouldAssumeDSOLocal(const GlobalValue 
*GV) const {
   if (!GV)
     return false;
 
+  // Weak symbols can be preempted at runtime, so don't assume they're DSO
+  // local. This is important for PIC code where we need GOT relocations for
+  // weak symbols. Only apply this fix for ARM targets to match GCC behavior.
+  if ((GV->hasWeakLinkage() || GV->hasExternalWeakLinkage()) &&
+      (TT.getArch() == Triple::arm || TT.getArch() == Triple::armeb ||
+       TT.getArch() == Triple::thumb || TT.getArch() == Triple::thumbeb))
+    return false;
+
   // If the IR producer requested that this GV be treated as dso local, obey.
   if (GV->isDSOLocal())
     return true;
@@ -251,6 +259,7 @@ bool TargetMachine::shouldAssumeDSOLocal(const GlobalValue 
*GV) const {
 
   assert(TT.isOSBinFormatELF() || TT.isOSBinFormatWasm() ||
          TT.isOSBinFormatXCOFF());
+
   return false;
 }
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to