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. - -@var = global i32 0, align 4 - -@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@PLT -; CHECK: callq ifunc@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} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits