[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.

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(

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