Fāng-ruì Sòng via llvm-dev
2021-Jun-06 01:08 UTC
[llvm-dev] -fpic ELF default: reclaim some -fno-semantic-interposition optimization opportunities?
On 2021-06-06, Joerg Sonnenberger wrote:>On Fri, Jun 04, 2021 at 03:26:53PM -0700, Fāng-ruì Sòng via llvm-dev wrote: >> Fixing the last point is actually easy: let -fno-pic use GOT when >> taking the address of an non-definition function. > >I'd far prefer to have an attribute to explicitly say that the address >of a given symbol should always be computed indirectly (e.g. via GOT). >That gives the explicit control necessary for libraries without >penalizing the larger executables like clang. > >JoergTaking the address (in code) of a non-definition function is rare, rarer after optimization. At least when building clang, I cannot find any penalizing. With the following patch, -fno-pic will use GOT for non-i386. I tested a stage-2 clang. The clang executable is **byte identical* if I use such a modified clang to build the origin/main clang. ``` void ext(); // non-definition declaration void *foo() { return (void*)ext; } ``` diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 9b31ecdbd81a..d451ec50f53d 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1057,10 +1057,10 @@ static bool shouldAssumeDSOLocal(const CodeGenModule &CGM, // -fno-pic sets dso_local on a function declaration to allow direct // accesses when taking its address (similar to a data symbol). If the // function is not defined in the executable, a canonical PLT entry will be - // needed at link time. -fno-direct-access-external-data can avoid the - // canonical PLT entry. We don't generalize this condition to -fpie/-fpic as - // it could just cause trouble without providing perceptible benefits. - if (isa<llvm::Function>(GV) && !CGOpts.NoPLT && RM == llvm::Reloc::Static) + // needed at link time. We only do this for legacy i386 where some + // applications may handle R_386_PC32 but not R_386_PLT32. + if (TT.getArch() == llvm::Triple::x86 && isa<llvm::Function>(GV) && + !CGOpts.NoPLT && RM == llvm::Reloc::Static) return true; } diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index a6582879f6f3..e2dd02c4eae5 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -51673,7 +51673,8 @@ void X86TargetLowering::LowerAsmOperandForConstraint(SDValue Op, if (auto *GA = dyn_cast<GlobalAddressSDNode>(Op)) // If we require an extra load to get this address, as in PIC mode, we // can't accept it. - if (isGlobalStubReference( + if (getTargetMachine().getRelocationModel() != Reloc::Static && + isGlobalStubReference( Subtarget.classifyGlobalReference(GA->getGlobal()))) return; break; -- The X86ISelLowering.cpp special case is because in the Linux kernel, arch/x86/include/asm/alternative.h:alternative_call_2 "call %P[new2]" wants a raw symbol instead of a $sym$GOTPCREL(%rip).
Joerg Sonnenberger via llvm-dev
2021-Jun-06 14:08 UTC
[llvm-dev] -fpic ELF default: reclaim some -fno-semantic-interposition optimization opportunities?
On Sat, Jun 05, 2021 at 06:08:57PM -0700, Fāng-ruì Sòng via llvm-dev wrote:> On 2021-06-06, Joerg Sonnenberger wrote: > > On Fri, Jun 04, 2021 at 03:26:53PM -0700, Fāng-ruì Sòng via llvm-dev wrote: > > > Fixing the last point is actually easy: let -fno-pic use GOT when > > > taking the address of an non-definition function. > > > > I'd far prefer to have an attribute to explicitly say that the address > > of a given symbol should always be computed indirectly (e.g. via GOT). > > That gives the explicit control necessary for libraries without > > penalizing the larger executables like clang. > > > > Joerg > > Taking the address (in code) of a non-definition function is rare, > rarer after optimization. At least when building clang, I cannot find > any penalizing.I was not talking about just functions. I can't even think of a case where pointer equality for function pointers matters. But the case I care far more about is being able to avoid copy relocations for global variables and that's the same problem (loading the address of a symbol). Joerg