[llvm-branch-commits] [llvm] 2820a2c - Move -fno-semantic-interposition dso_local logic from TargetMachine to Clang CodeGenModule

Fangrui Song via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Dec 29 23:42:49 PST 2020


Author: Fangrui Song
Date: 2020-12-29T23:37:55-08:00
New Revision: 2820a2ca3a0e69c3f301845420e0067ffff2251b

URL: https://github.com/llvm/llvm-project/commit/2820a2ca3a0e69c3f301845420e0067ffff2251b
DIFF: https://github.com/llvm/llvm-project/commit/2820a2ca3a0e69c3f301845420e0067ffff2251b.diff

LOG: Move -fno-semantic-interposition dso_local logic from TargetMachine to Clang CodeGenModule

This simplifies TargetMachine::shouldAssumeDSOLocal and and gives frontend the
decision to use dso_local. For LLVM synthesized functions/globals, they may lose
inferred dso_local but such optimizations are probably not very useful.

Note: the hasComdat() condition in canBenefitFromLocalAlias (D77429) may be dead now.
(llvm/CodeGen/X86/semantic-interposition-comdat.ll)
(Investigate whether we need test coverage when Fuchsia C++ ABI is clearer)

Added: 
    clang/test/CodeGen/semantic-interposition-no.c

Modified: 
    clang/lib/CodeGen/CodeGenModule.cpp
    llvm/lib/Target/TargetMachine.cpp

Removed: 
    llvm/test/CodeGen/X86/semantic-interposition-comdat.ll
    llvm/test/CodeGen/X86/semantic-interposition-infer-dsolocal.ll


################################################################################
diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 93916e85a461..6d14298d9f5f 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -954,8 +954,17 @@ static bool shouldAssumeDSOLocal(const CodeGenModule &CGM,
   const auto &CGOpts = CGM.getCodeGenOpts();
   llvm::Reloc::Model RM = CGOpts.RelocationModel;
   const auto &LOpts = CGM.getLangOpts();
-  if (RM != llvm::Reloc::Static && !LOpts.PIE)
-    return false;
+  if (RM != llvm::Reloc::Static && !LOpts.PIE) {
+    // On ELF, if -fno-semantic-interposition is specified, we can set dso_local
+    // if using a local alias is preferable (can avoid GOT indirection).
+    // Currently only x86 supports local alias.
+    if (!TT.isOSBinFormatELF() ||
+        !CGM.getLangOpts().ExplicitNoSemanticInterposition ||
+        !GV->canBenefitFromLocalAlias())
+      return false;
+    // The allowed targets need to match AsmPrinter::getSymbolPreferLocal.
+    return TT.isX86();
+  }
 
   // A definition cannot be preempted from an executable.
   if (!GV->isDeclarationForLinker())

diff  --git a/clang/test/CodeGen/semantic-interposition-no.c b/clang/test/CodeGen/semantic-interposition-no.c
new file mode 100644
index 000000000000..cc53d1799f9d
--- /dev/null
+++ b/clang/test/CodeGen/semantic-interposition-no.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -mrelocation-model pic -pic-level 1 -fno-semantic-interposition %s -o - | FileCheck %s
+
+/// For ELF -fpic/-fPIC, if -fno-semantic-interposition is specified, mark
+/// defined variables and functions dso_local. ifunc isn't marked.
+
+// CHECK: @var = dso_local global i32 0, align 4
+// CHECK: @ext_var = external global i32, align 4
+int var;
+extern int ext_var;
+
+// CHECK: @ifunc = ifunc i32 (), bitcast (i8* ()* @ifunc_resolver to i32 ()*)
+int ifunc(void) __attribute__((ifunc("ifunc_resolver")));
+
+// CHECK: define dso_local i32 @func()
+// CHECK: declare i32 @ext()
+int func(void) { return 0; }
+int ext(void);
+
+static void *ifunc_resolver() { return func; }
+
+int foo() {
+  return var + ext_var + ifunc() + func() + ext();
+}

diff  --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp
index ad0e90125258..b45b8e354b3a 100644
--- a/llvm/lib/Target/TargetMachine.cpp
+++ b/llvm/lib/Target/TargetMachine.cpp
@@ -163,14 +163,6 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
     // If the symbol is defined, it cannot be preempted.
     if (!GV->isDeclarationForLinker())
       return true;
-  } else if (TT.isOSBinFormatELF()) {
-    // If dso_local allows AsmPrinter::getSymbolPreferLocal to use a local
-    // alias, set the flag. We cannot set dso_local for other global values,
-    // because otherwise direct accesses to a probably interposable symbol (even
-    // if the codegen assumes not) will be rejected by the linker.
-    if (!GV->canBenefitFromLocalAlias())
-      return false;
-    return TT.isX86() && M.noSemanticInterposition();
   }
 
   // ELF & wasm support preemption of other symbols.

diff  --git a/llvm/test/CodeGen/X86/semantic-interposition-comdat.ll b/llvm/test/CodeGen/X86/semantic-interposition-comdat.ll
deleted file mode 100644
index d11be2d6bd0c..000000000000
--- a/llvm/test/CodeGen/X86/semantic-interposition-comdat.ll
+++ /dev/null
@@ -1,28 +0,0 @@
-; RUN: llc -mtriple=x86_64 -relocation-model=pic < %s | FileCheck %s
-
-$comdat_func = comdat any
-
-; CHECK-LABEL: func2:
-; CHECK-NOT: .Lfunc2$local
-
-declare void @func()
-
-define hidden void @func2() {
-entry:
-  call void @func()
-  ret void
-}
-
-; CHECK: comdat_func:
-; CHECK-NOT: .Lcomdat_func$local
-
-define hidden void @comdat_func() comdat {
-entry:
-  call void @func()
-  ret void
-}
-
-!llvm.module.flags = !{!0, !1}
-
-!0 = !{i32 1, !"SemanticInterposition", i32 0}
-!1 = !{i32 7, !"PIC Level", i32 2}

diff  --git a/llvm/test/CodeGen/X86/semantic-interposition-infer-dsolocal.ll b/llvm/test/CodeGen/X86/semantic-interposition-infer-dsolocal.ll
deleted file mode 100644
index a0391d036468..000000000000
--- a/llvm/test/CodeGen/X86/semantic-interposition-infer-dsolocal.ll
+++ /dev/null
@@ -1,46 +0,0 @@
-; RUN: llc -mtriple=x86_64 -relocation-model=pic < %s | FileCheck %s
-
-;; With a module flag SemanticInterposition=0, infer dso_local flags even if PIC.
-;; Local aliases will be generated for applicable variables and functions.
-
- at var = global i32 0, align 4
-
- at ifunc = ifunc i32 (), bitcast (i32 ()* ()* @ifunc_resolver to i32 ()*)
-
-define i32 @ifunc_impl() {
-entry:
-  ret i32 0
-}
-
-define i32 ()* @ifunc_resolver() {
-entry:
-  ret i32 ()* @ifunc_impl
-}
-
-declare i32 @external()
-
-define i32 @func() {
-  ret i32 0
-}
-
-;; Don't set dso_local on declarations or ifuncs.
-define i32 @foo() {
-; CHECK: movl .Lvar$local(%rip), %ebp
-; CHECK: callq external at PLT
-; CHECK: callq ifunc at PLT
-; CHECK: callq .Lfunc$local{{$}}
-entry:
-  %0 = load i32, i32* @var, align 4
-  %call = tail call i32 @external()
-  %add = add nsw i32 %call, %0
-  %call1 = tail call i32 @ifunc()
-  %add2 = add nsw i32 %add, %call1
-  %call2 = tail call i32 @func()
-  %add3 = add nsw i32 %add, %call2
-  ret i32 %add3
-}
-
-!llvm.module.flags = !{!0, !1}
-
-!0 = !{i32 1, !"SemanticInterposition", i32 0}
-!1 = !{i32 7, !"PIC Level", i32 2}


        


More information about the llvm-branch-commits mailing list