[llvm-dev] -fpic ELF default: reclaim some -fno-semantic-interposition optimization opportunities?
Fāng-ruì Sòng via llvm-dev
llvm-dev at lists.llvm.org
Sat Jun 5 18:08:57 PDT 2021
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.
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).
More information about the llvm-dev
mailing list