Author: Tony Guillot
Date: 2026-07-12T01:35:54+02:00
New Revision: 10955eac1c053d58bbcda3d86912deee43ffc798

URL: 
https://github.com/llvm/llvm-project/commit/10955eac1c053d58bbcda3d86912deee43ffc798
DIFF: 
https://github.com/llvm/llvm-project/commit/10955eac1c053d58bbcda3d86912deee43ffc798.diff

LOG: Revert "[ARM] Use .reloc for weak symbols in PIC mode instead of GOT 
indirect…"

This reverts commit 290279b6b69138f4162cace4865713efa12ec262.

Added: 
    

Modified: 
    llvm/lib/Target/ARM/ARMAsmPrinter.cpp
    llvm/lib/Target/ARM/ARMFastISel.cpp
    llvm/lib/Target/ARM/ARMISelLowering.cpp
    llvm/lib/Target/ARM/ARMSubtarget.cpp
    llvm/lib/Target/ARM/ARMTargetMachine.h
    llvm/test/CodeGen/ARM/elf-preemption.ll
    llvm/test/CodeGen/ARM/weak-hidden-pic.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp 
b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
index b7448dd5c9783..c25a2cfeff8d6 100644
--- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -1016,36 +1016,6 @@ void ARMAsmPrinter::emitMachineConstantPoolValue(
     unsigned char TF =
         TM.getTargetTriple().isOSBinFormatMachO() ? ARMII::MO_NONLAZY : 0;
     MCSym = GetARMGVSymbol(GV, TF);
-
-    // For weak symbols in ELF PIC mode, the assembler would eagerly resolve a
-    // PC-relative expression like sym-(LPC+8) when the symbol and reference 
are
-    // in the same section, preventing the linker from overriding a weak
-    // definition with a non-weak definition from another section. Use a
-    // .reloc directive rather than a fixup to force the generation of a
-    // relocation (R_ARM_REL32) so the linker can perform the override.
-    if (GV->isWeakForLinker() && TM.getTargetTriple().isOSBinFormatELF() &&
-        TM.isPositionIndependent() && ACPV->getPCAdjustment() != 0) {
-      MCSymbol *CPILabel = OutContext.createTempSymbol();
-      OutStreamer->emitLabel(CPILabel);
-      // Emit local-only expression: CPILabel - (LPC+PCAdj)
-      const MCExpr *LocalExpr = MCSymbolRefExpr::create(CPILabel, OutContext);
-      MCSymbol *PCLabel =
-          getPICLabel(DL.getInternalSymbolPrefix(), getFunctionNumber(),
-                      ACPV->getLabelId(), OutContext);
-      const MCExpr *PCRelExpr = MCSymbolRefExpr::create(PCLabel, OutContext);
-      PCRelExpr = MCBinaryExpr::createAdd(
-          PCRelExpr,
-          MCConstantExpr::create(ACPV->getPCAdjustment(), OutContext),
-          OutContext);
-      LocalExpr = MCBinaryExpr::createSub(LocalExpr, PCRelExpr, OutContext);
-      OutStreamer->emitValue(LocalExpr, Size);
-      // Emit .reloc to force linker resolution of the weak symbol.
-      const MCExpr *CPIExpr = MCSymbolRefExpr::create(CPILabel, OutContext);
-      const MCExpr *SymExpr = MCSymbolRefExpr::create(MCSym, OutContext);
-      OutStreamer->emitRelocDirective(*CPIExpr, "R_ARM_REL32", SymExpr,
-                                      SMLoc());
-      return;
-    }
   } else if (ACPV->isMachineBasicBlock()) {
     const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB();
     MCSym = MBB->getSymbol();

diff  --git a/llvm/lib/Target/ARM/ARMFastISel.cpp 
b/llvm/lib/Target/ARM/ARMFastISel.cpp
index 2c5d286e11c4f..1cf0d98f690aa 100644
--- a/llvm/lib/Target/ARM/ARMFastISel.cpp
+++ b/llvm/lib/Target/ARM/ARMFastISel.cpp
@@ -3033,7 +3033,8 @@ bool ARMFastISel::tryToFoldLoadIntoMI(MachineInstr *MI, 
unsigned OpNo,
 }
 
 Register ARMFastISel::ARMLowerPICELF(const GlobalValue *GV, MVT VT) {
-  bool UseGOT_PREL = !GV->isDSOLocal();
+  // Weak symbols need GOT indirection even when hidden/DSO-local.
+  bool UseGOT_PREL = !GV->isDSOLocal() || GV->isWeakForLinker();
   LLVMContext *Context = &MF->getFunction().getContext();
   unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
   unsigned PCAdj = Subtarget->isThumb() ? 4 : 8;

diff  --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp 
b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 28d4c0ff22703..35c46c3f0a75a 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -3651,10 +3651,15 @@ SDValue 
ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
       return V;
 
   if (isPositionIndependent()) {
-    SDValue G = DAG.getTargetGlobalAddress(
-        GV, dl, PtrVT, 0, GV->isDSOLocal() ? 0 : ARMII::MO_GOT);
+    // Weak symbols need GOT indirection even when hidden/DSO-local.
+    // The assembler eagerly resolves PC-relative expressions when the
+    // symbol and reference are in the same section, which prevents the
+    // linker from overriding a weak definition with a non-weak one.
+    bool UseGOT = !GV->isDSOLocal() || GV->isWeakForLinker();
+    SDValue G = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
+                                           UseGOT ? ARMII::MO_GOT : 0);
     SDValue Result = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVT, G);
-    if (!GV->isDSOLocal())
+    if (UseGOT)
       Result =
           DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Result,
                       MachinePointerInfo::getGOT(DAG.getMachineFunction()));

diff  --git a/llvm/lib/Target/ARM/ARMSubtarget.cpp 
b/llvm/lib/Target/ARM/ARMSubtarget.cpp
index 4893d8d3a9ef1..0f324a6a31757 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.cpp
+++ b/llvm/lib/Target/ARM/ARMSubtarget.cpp
@@ -397,7 +397,8 @@ bool ARMSubtarget::isGVIndirectSymbol(const GlobalValue 
*GV) const {
 }
 
 bool ARMSubtarget::isGVInGOT(const GlobalValue *GV) const {
-  return isTargetELF() && TM.isPositionIndependent() && !GV->isDSOLocal();
+  return isTargetELF() && TM.isPositionIndependent() &&
+         (!GV->isDSOLocal() || GV->isWeakForLinker());
 }
 
 unsigned ARMSubtarget::getMispredictionPenalty() const {

diff  --git a/llvm/lib/Target/ARM/ARMTargetMachine.h 
b/llvm/lib/Target/ARM/ARMTargetMachine.h
index 215b541620acb..109d6fd5e6671 100644
--- a/llvm/lib/Target/ARM/ARMTargetMachine.h
+++ b/llvm/lib/Target/ARM/ARMTargetMachine.h
@@ -111,6 +111,15 @@ class ARMBaseTargetMachine : public 
CodeGenTargetMachineImpl {
         (GV->isDeclarationForLinker() || GV->hasCommonLinkage()))
       return true;
 
+    // In ELF PIC mode, weak symbols referenced via the constant pool use a
+    // PC-relative expression (e.g. .long xxx-(.LPC+8)) that the assembler
+    // eagerly resolves when both the symbol and label are in the same section.
+    // This prevents the linker from overriding a weak definition with a
+    // non-weak one. Use GOT indirection for weak symbols to avoid this.
+    if (getTargetTriple().isOSBinFormatELF() && isPositionIndependent() &&
+        GV->isWeakForLinker())
+      return true;
+
     return false;
   }
 

diff  --git a/llvm/test/CodeGen/ARM/elf-preemption.ll 
b/llvm/test/CodeGen/ARM/elf-preemption.ll
index 6d5a78dd95aa4..88b35683b97c0 100644
--- a/llvm/test/CodeGen/ARM/elf-preemption.ll
+++ b/llvm/test/CodeGen/ARM/elf-preemption.ll
@@ -59,14 +59,13 @@ define ptr @get_weak_dsolocal_var() nounwind {
 ; PIC:       @ %bb.0:
 ; PIC-NEXT:    ldr r0, .LCPI2_0
 ; PIC-NEXT:  .LPC2_0:
-; PIC-NEXT:    add r0, pc, r0
+; PIC-NEXT:    ldr r0, [pc, r0]
 ; PIC-NEXT:    bx lr
 ; PIC-NEXT:    .p2align 2
 ; PIC-NEXT:  @ %bb.1:
 ; PIC-NEXT:  .LCPI2_0:
 ; PIC-NEXT:  .Ltmp1:
-; PIC-NEXT:    .long .Ltmp1-(.LPC2_0+8)
-; PIC-NEXT:    .reloc .Ltmp1, R_ARM_REL32, weak_dsolocal_var
+; PIC-NEXT:    .long weak_dsolocal_var(GOT_PREL)-(.LPC2_0+8-.Ltmp1)
   ret ptr @weak_dsolocal_var
 }
 
@@ -164,14 +163,13 @@ define weak dso_local ptr @weak_dsolocal_func() nounwind {
 ; PIC:       @ %bb.0:
 ; PIC-NEXT:    ldr r0, .LCPI7_0
 ; PIC-NEXT:  .LPC7_0:
-; PIC-NEXT:    add r0, pc, r0
+; PIC-NEXT:    ldr r0, [pc, r0]
 ; PIC-NEXT:    bx lr
 ; PIC-NEXT:    .p2align 2
 ; PIC-NEXT:  @ %bb.1:
 ; PIC-NEXT:  .LCPI7_0:
 ; PIC-NEXT:  .Ltmp3:
-; PIC-NEXT:    .long .Ltmp3-(.LPC7_0+8)
-; PIC-NEXT:    .reloc .Ltmp3, R_ARM_REL32, weak_dsolocal_func
+; PIC-NEXT:    .long weak_dsolocal_func(GOT_PREL)-(.LPC7_0+8-.Ltmp3)
   ret ptr @weak_dsolocal_func
 }
 

diff  --git a/llvm/test/CodeGen/ARM/weak-hidden-pic.ll 
b/llvm/test/CodeGen/ARM/weak-hidden-pic.ll
index 26a779f2dc9f9..4d6eca77af855 100644
--- a/llvm/test/CodeGen/ARM/weak-hidden-pic.ll
+++ b/llvm/test/CodeGen/ARM/weak-hidden-pic.ll
@@ -2,20 +2,18 @@
 ; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi -relocation-model=pic | 
FileCheck %s
 ; RUN: llc < %s -O0 -fast-isel-abort=2 -mtriple=armv7-linux-gnueabi 
-relocation-model=pic | FileCheck %s
 
-; Weak dso_local hidden functions must be overridable at link time
-; (a non-weak definition in another object should override the weak one).
-; Instead of using GOT indirection, we use a PC-relative constant pool
-; entry with a .reloc directive to force the assembler to emit a proper
-; relocation (R_ARM_REL32), preventing eager resolution when the symbol
-; and reference are in the same section.
+; Hidden weak function with dso_local must still use GOT indirection
+; in PIC mode on ARM. The assembler eagerly resolves PC-relative
+; expressions like .long xxx-(.LPC+8) when both are in the same section,
+; which prevents the linker from overriding the weak definition with
+; a non-weak one from another object file.
 
 define weak dso_local hidden void @weak_hidden_func() {
   ret void
 }
 
 ; CHECK-LABEL: weak_hidden_func_addr:
-; CHECK:       .long .Ltmp{{[0-9]+}}-(.LPC{{[0-9]+}}_0+{{[48]}})
-; CHECK:       .reloc .Ltmp{{[0-9]+}}, R_ARM_REL32, weak_hidden_func
+; CHECK:       .long weak_hidden_func(GOT_PREL)
 define i8* @weak_hidden_func_addr() {
   ret i8* bitcast (void()* @weak_hidden_func to i8*)
 }


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

Reply via email to