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
