[llvm] [ARM] Use .reloc for dso_local weak symbols in PIC mode instead of GOT indirection (PR #209660)
Peter Smith via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 16 12:46:12 PDT 2026
smithp35 wrote:
Apologies for taking so long to reply.
Where I'm up to at the moment.
The original code, prior to any of these changes https://github.com/llvm/llvm-project/pull/209660/changes/3cb23f5a41328703f0cb9180503d63b29325eb48 had a isGVinGOT of
```
bool ARMSubtarget::isGVInGOT(const GlobalValue *GV) const {
return isTargetELF() && TM.isPositionIndependent() && !GV->isDSOLocal();
}
```
`ARMFastIsel::ARMLowerPICELF` just used `!GV->isDSOLocal()`
`ARMTargetLowering::LowerGlobalAddressELF` just used `GV->isDSOLocal()` to decide whether to use the GOT or not.
With this original code there was no test failure in the sanitizer run-time when building a shared object. I think a dso_local weak global value would not have gone through the GOT, but instead it would have been resolved entirely at assembly time, so the linker would not have seen the R_ARM_REL32 relocation to the preemptable symbol.
What I want to work out is why `isGVinGOT` has to be changed, and why do `ARMFastIsel::ARMLowerPICELF` and `ARMTargetLowering::LowerGlobalAddressELF` have to use it. It looks like it should be possible in `ARMAsmPrinter::emitMachineConstantPoolValue` to only use the R_ARM_REL32 sequence on non-default visibility weak symbols, perhaps by adding `&& !GV->hasDefaultVisibility()` instead of `!isGVinGOT()`
I still don't know why it is legal for dso_local to be used on a default visibility weak symbol. I'd like to work out how that is possible from C/C++. Yes I know we can hand-write the IR, but I'm not sure if that would be legal for C/C++. That may be a separate issue though.
https://github.com/llvm/llvm-project/pull/209660
More information about the llvm-commits
mailing list