forked from OSchip/llvm-project
Refactor how -fno-semantic-interposition sets dso_local on default visibility external linkage definitions
The idea is that the CC1 default for ELF should set dso_local on default
visibility external linkage definitions in the default -mrelocation-model pic
mode (-fpic/-fPIC) to match COFF/Mach-O and make output IR similar.
The refactoring is made available by 2820a2ca3a
.
Currently only x86 supports local aliases. We move the decision to the driver.
There are three CC1 states:
* -fsemantic-interposition: make some linkages interposable and make default visibility external linkage definitions dso_preemptable.
* (default): selected if the target supports .Lfoo$local: make default visibility external linkage definitions dso_local
* -fhalf-no-semantic-interposition: if neither option is set or the target does not support .Lfoo$local: like -fno-semantic-interposition but local aliases are not used. So references can be interposed if not optimized out.
Add -fhalf-no-semantic-interposition to a few tests using the half-based semantic interposition behavior.
This commit is contained in:
parent
219d00e0d9
commit
d1fd72343c
|
@ -322,7 +322,8 @@ ENUM_LANGOPT(ExternDeclDLLImportVisibility, Visibility, 3, DefaultVisibility,
|
|||
ENUM_LANGOPT(ExternDeclNoDLLStorageClassVisibility, Visibility, 3, HiddenVisibility,
|
||||
"visibility for external declarations without an explicit DLL storage class [-fvisibility-from-dllstorageclass]")
|
||||
BENIGN_LANGOPT(SemanticInterposition , 1, 0, "semantic interposition")
|
||||
BENIGN_LANGOPT(ExplicitNoSemanticInterposition, 1, 0, "explicitly no semantic interposition")
|
||||
BENIGN_LANGOPT(HalfNoSemanticInterposition, 1, 0,
|
||||
"Like -fno-semantic-interposition but don't use local aliases")
|
||||
ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff,
|
||||
"stack protector mode")
|
||||
ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized,
|
||||
|
|
|
@ -3793,7 +3793,7 @@ defm ipa_cp : BooleanFFlag<"ipa-cp">,
|
|||
Group<clang_ignored_gcc_optimization_f_Group>;
|
||||
defm ivopts : BooleanFFlag<"ivopts">, Group<clang_ignored_gcc_optimization_f_Group>;
|
||||
def fsemantic_interposition : Flag<["-"], "fsemantic-interposition">, Group<f_Group>, Flags<[CC1Option]>;
|
||||
def fno_semantic_interposition: Flag<["-"], "fno-semantic-interposition">, Group<f_Group>, Flags<[CC1Option]>;
|
||||
def fno_semantic_interposition: Flag<["-"], "fno-semantic-interposition">, Group<f_Group>;
|
||||
defm non_call_exceptions : BooleanFFlag<"non-call-exceptions">, Group<clang_ignored_f_Group>;
|
||||
defm peel_loops : BooleanFFlag<"peel-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
|
||||
defm permissive : BooleanFFlag<"permissive">, Group<clang_ignored_f_Group>;
|
||||
|
@ -4722,6 +4722,8 @@ def pic_level : Separate<["-"], "pic-level">,
|
|||
HelpText<"Value for __PIC__">;
|
||||
def pic_is_pie : Flag<["-"], "pic-is-pie">,
|
||||
HelpText<"File is for a position independent executable">;
|
||||
def fhalf_no_semantic_interposition : Flag<["-"], "fhalf-no-semantic-interposition">,
|
||||
HelpText<"Like -fno-semantic-interposition but don't use local aliases">;
|
||||
def fno_validate_pch : Flag<["-"], "fno-validate-pch">,
|
||||
HelpText<"Disable validation of precompiled headers">,
|
||||
MarshallingInfoFlag<"PreprocessorOpts->DisablePCHValidation">;
|
||||
|
|
|
@ -534,9 +534,6 @@ void CodeGenModule::Release() {
|
|||
if (Context.getLangOpts().SemanticInterposition)
|
||||
// Require various optimization to respect semantic interposition.
|
||||
getModule().setSemanticInterposition(1);
|
||||
else if (Context.getLangOpts().ExplicitNoSemanticInterposition)
|
||||
// Allow dso_local on applicable targets.
|
||||
getModule().setSemanticInterposition(0);
|
||||
|
||||
if (CodeGenOpts.EmitCodeView) {
|
||||
// Indicate that we want CodeView in the metadata.
|
||||
|
@ -961,15 +958,15 @@ static bool shouldAssumeDSOLocal(const CodeGenModule &CGM,
|
|||
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())
|
||||
// On ELF, if -fno-semantic-interposition is specified and the target
|
||||
// supports local aliases, there will be neither CC1
|
||||
// -fsemantic-interposition nor -fhalf-no-semantic-interposition. Set
|
||||
// dso_local if using a local alias is preferable (can avoid GOT
|
||||
// indirection).
|
||||
if (!GV->canBenefitFromLocalAlias())
|
||||
return false;
|
||||
// The allowed targets need to match AsmPrinter::getSymbolPreferLocal.
|
||||
return TT.isX86();
|
||||
return !(CGM.getLangOpts().SemanticInterposition ||
|
||||
CGM.getLangOpts().HalfNoSemanticInterposition);
|
||||
}
|
||||
|
||||
// A definition cannot be preempted from an executable.
|
||||
|
|
|
@ -4561,12 +4561,31 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
CmdArgs.push_back(A->getValue());
|
||||
}
|
||||
|
||||
// The default is -fno-semantic-interposition. We render it just because we
|
||||
// require explicit -fno-semantic-interposition to infer dso_local.
|
||||
if (Arg *A = Args.getLastArg(options::OPT_fsemantic_interposition,
|
||||
options::OPT_fno_semantic_interposition))
|
||||
if (RelocationModel != llvm::Reloc::Static && !IsPIE)
|
||||
A->render(Args, CmdArgs);
|
||||
// -fsemantic-interposition is forwarded to CC1: set the
|
||||
// "SemanticInterposition" metadata to 1 (make some linkages interposable) and
|
||||
// make default visibility external linkage definitions dso_preemptable.
|
||||
//
|
||||
// -fno-semantic-interposition: if the target supports .Lfoo$local local
|
||||
// aliases (make default visibility external linkage definitions dso_local).
|
||||
// This is the CC1 default for ELF to match COFF/Mach-O.
|
||||
//
|
||||
// Otherwise use Clang's traditional behavior: like
|
||||
// -fno-semantic-interposition but local aliases are not used. So references
|
||||
// can be interposed if not optimized out.
|
||||
if (Triple.isOSBinFormatELF()) {
|
||||
Arg *A = Args.getLastArg(options::OPT_fsemantic_interposition,
|
||||
options::OPT_fno_semantic_interposition);
|
||||
if (RelocationModel != llvm::Reloc::Static && !IsPIE) {
|
||||
// The supported targets need to call AsmPrinter::getSymbolPreferLocal.
|
||||
bool SupportsLocalAlias = Triple.isX86();
|
||||
if (!A)
|
||||
CmdArgs.push_back("-fhalf-no-semantic-interposition");
|
||||
else if (A->getOption().matches(options::OPT_fsemantic_interposition))
|
||||
A->render(Args, CmdArgs);
|
||||
else if (!SupportsLocalAlias)
|
||||
CmdArgs.push_back("-fhalf-no-semantic-interposition");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::string Model;
|
||||
|
|
|
@ -3197,9 +3197,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
|
|||
}
|
||||
|
||||
Opts.SemanticInterposition = Args.hasArg(OPT_fsemantic_interposition);
|
||||
// An explicit -fno-semantic-interposition infers dso_local.
|
||||
Opts.ExplicitNoSemanticInterposition =
|
||||
Args.hasArg(OPT_fno_semantic_interposition);
|
||||
Opts.HalfNoSemanticInterposition =
|
||||
Args.hasArg(OPT_fhalf_no_semantic_interposition);
|
||||
|
||||
// -mrtd option
|
||||
if (Arg *A = Args.getLastArg(OPT_mrtd)) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
|
||||
// REQUIRES: aarch64-registered-target
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=128 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-128
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=512 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-512
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=128 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s -fhalf-no-semantic-interposition | FileCheck %s --check-prefix=CHECK-128
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=512 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s -fhalf-no-semantic-interposition | FileCheck %s --check-prefix=CHECK-512
|
||||
|
||||
#include <arm_sve.h>
|
||||
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
// 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();
|
||||
}
|
|
@ -1,9 +1,38 @@
|
|||
// RUN: %clang_cc1 -emit-llvm -fsemantic-interposition %s -o - | FileCheck --check-prefix=INTERPOSITION %s
|
||||
// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck --check-prefix=NO %s
|
||||
/// With explicit -fno-semantic-interposition, add a module flag to inform the
|
||||
/// backend that dso_local can be inferred.
|
||||
// RUN: %clang_cc1 -emit-llvm -fno-semantic-interposition %s -o - | FileCheck --check-prefix=EXPLICIT_NO %s
|
||||
/// -fno-semantic-interposition is the default and local aliases (via dso_local) are allowed.
|
||||
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -mrelocation-model pic -pic-level 1 %s -o - | FileCheck %s --check-prefixes=CHECK,NOMETADATA
|
||||
|
||||
// INTERPOSITION: !{{[0-9]+}} = !{i32 1, !"SemanticInterposition", i32 1}
|
||||
// NO-NOT: "SemanticInterposition"
|
||||
// EXPLICIT_NO: !{{[0-9]+}} = !{i32 1, !"SemanticInterposition", i32 0}
|
||||
/// -fsemantic-interposition sets a module metadata.
|
||||
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -mrelocation-model pic -pic-level 1 -fsemantic-interposition %s -o - | FileCheck %s --check-prefixes=PREEMPT,METADATA
|
||||
|
||||
/// Traditional half-baked behavior: interprocedural optimizations are allowed
|
||||
/// but local aliases are not used.
|
||||
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -mrelocation-model pic -pic-level 1 -fhalf-no-semantic-interposition %s -o - | FileCheck %s --check-prefixes=PREEMPT,NOMETADATA
|
||||
|
||||
// CHECK: @var = dso_local global i32 0, align 4
|
||||
// CHECK: @ext_var = external global i32, align 4
|
||||
// CHECK: @ifunc = ifunc i32 (), bitcast (i8* ()* @ifunc_resolver to i32 ()*)
|
||||
// CHECK: define dso_local i32 @func()
|
||||
// CHECK: declare i32 @ext()
|
||||
|
||||
// PREEMPT: @var = global i32 0, align 4
|
||||
// PREEMPT: @ext_var = external global i32, align 4
|
||||
// PREEMPT: @ifunc = ifunc i32 (), bitcast (i8* ()* @ifunc_resolver to i32 ()*)
|
||||
// PREEMPT: define i32 @func()
|
||||
// PREEMPT: declare i32 @ext()
|
||||
|
||||
// METADATA: !{{[0-9]+}} = !{i32 1, !"SemanticInterposition", i32 1}
|
||||
// NOMETADATA-NOT: "SemanticInterposition"
|
||||
|
||||
int var;
|
||||
extern int ext_var;
|
||||
|
||||
int ifunc(void) __attribute__((ifunc("ifunc_resolver")));
|
||||
|
||||
int func(void) { return 0; }
|
||||
int ext(void);
|
||||
|
||||
static void *ifunc_resolver() { return func; }
|
||||
|
||||
int foo() {
|
||||
return var + ext_var + ifunc() + func() + ext();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Cross comdat example
|
||||
// Parent VTable is in a comdat section.
|
||||
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
|
||||
|
||||
// The inline function is emitted in each module with the same comdat
|
||||
// CHECK: $_ZTS1A = comdat any
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Check the vtable layout for classes with key functions defined in different
|
||||
// translation units. This TU only manifests the vtable for A.
|
||||
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
|
||||
|
||||
#include "cross-tu-header.h"
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Check the vtable layout for classes with key functions defined in different
|
||||
// translation units. This TU manifests the vtable for B.
|
||||
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
|
||||
|
||||
#include "cross-tu-header.h"
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Diamond inheritance.
|
||||
// A more complicated multiple inheritance example that includes longer chain of inheritance and a common ancestor.
|
||||
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
|
||||
|
||||
// CHECK-DAG: %class.B = type { %class.A }
|
||||
// CHECK-DAG: %class.A = type { i32 (...)** }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Diamond virtual inheritance.
|
||||
// This should cover virtual inheritance, construction vtables, and VTTs.
|
||||
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
|
||||
|
||||
// Class A contains a vtable ptr, then int, then padding
|
||||
// CHECK-DAG: %class.B = type { i32 (...)**, %class.A.base }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Check the layout of the vtable for a child class that inherits a virtual
|
||||
// function but does not override it.
|
||||
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
|
||||
|
||||
class A {
|
||||
public:
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// The VTable is not in a comdat but the inline methods are.
|
||||
// This doesn’t affect the vtable or the stubs we emit.
|
||||
|
||||
// RUN: %clang_cc1 %s -triple=aarch64 -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=x86_64 -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=aarch64 -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=x86_64 -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
|
||||
|
||||
// CHECK: $_ZTI1A.rtti_proxy = comdat any
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Multiple inheritance.
|
||||
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
|
||||
|
||||
// CHECK: %class.C = type { %class.A, %class.B }
|
||||
// CHECK: %class.A = type { i32 (...)** }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Check that no alias is emitted when the vtable is already dso_local. This can
|
||||
// happen if the class is hidden.
|
||||
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s --check-prefix=DEFAULT-VIS
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s --check-prefix=DEFAULT-VIS
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fvisibility hidden | FileCheck %s --check-prefix=HIDDEN-VIS
|
||||
|
||||
// DEFAULT-VIS: @_ZTV1A.local = private unnamed_addr constant
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// We instead emit zero for the pure virtual function component. See PR43094 for
|
||||
// details.
|
||||
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
|
||||
|
||||
// CHECK: @_ZTV1A.local = private unnamed_addr constant { [4 x i32] } { [4 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8* }** @_ZTI1A.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1A.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 0, i32 trunc (i64 sub (i64 ptrtoint (void (%class.A*)* dso_local_equivalent @_ZN1A3barEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1A.local, i32 0, i32 0, i32 2) to i64)) to i32)] }, align 4
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Check the layout of the vtable for a child class that inherits a virtual
|
||||
// function but does override it.
|
||||
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
|
||||
|
||||
// CHECK: @_ZTV1B.local = private unnamed_addr constant { [4 x i32] } { [4 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i8* }** @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1B.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.B*)* dso_local_equivalent @_ZN1B3fooEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1B.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.B*)* dso_local_equivalent @_ZN1B3barEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1B.local, i32 0, i32 0, i32 2) to i64)) to i32)] }, align 4
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// of a soft incremental rollout. This ABI should only be used if the flag for
|
||||
// it is passed on Fuchsia.
|
||||
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck --check-prefix=RELATIVE-ABI %s
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck --check-prefix=RELATIVE-ABI %s
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm -fno-experimental-relative-c++-abi-vtables | FileCheck --check-prefix=DEFAULT-ABI %s
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm | FileCheck --check-prefix=DEFAULT-ABI %s
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Check the layout of the vtable for a normal class.
|
||||
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
|
||||
|
||||
// We should be emitting comdats for each of the virtual function RTTI proxies
|
||||
// CHECK: $_ZTI1A.rtti_proxy = comdat any
|
||||
|
|
|
@ -2,12 +2,27 @@
|
|||
// RUN: %clang -target x86_64 %s -Werror -fPIC -fsemantic-interposition -c -### 2>&1 | FileCheck %s
|
||||
// CHECK: "-fsemantic-interposition"
|
||||
|
||||
/// Require explicit -fno-semantic-interposition to infer dso_local.
|
||||
// RUN: %clang -target x86_64 %s -Werror -fPIC -fsemantic-interposition -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=EXPLICIT_NO %s
|
||||
// EXPLICIT_NO: "-fno-semantic-interposition"
|
||||
/// No-op for -fno-pic/-fpie.
|
||||
// RUN: %clang -target x86_64 %s -Werror -fsemantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NOOP %s
|
||||
// RUN: %clang -target x86_64 %s -Werror -fPIE -fsemantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NOOP %s
|
||||
// NOOP-NOT: "-fsemantic-interposition"
|
||||
// NOOP-NOT: "-fno-semantic-interposition"
|
||||
|
||||
// RUN: %clang -target x86_64 %s -Werror -fsemantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s
|
||||
// RUN: %clang -target x86_64 %s -Werror -fPIC -c -### 2>&1 | FileCheck --check-prefix=NO %s
|
||||
// RUN: %clang -target x86_64 %s -Werror -fPIE -fsemantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s
|
||||
/// If -fno-semantic-interposition is specified and the target supports local
|
||||
/// aliases, neither CC1 option is set.
|
||||
// RUN: %clang -target i386 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s
|
||||
// RUN: %clang -target x86_64 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s
|
||||
// NO-NOT: "-fsemantic-interposition"
|
||||
// NO-NOT: "-fno-semantic-interposition"
|
||||
// NO-NOT: "-fhalf-no-semantic-interposition"
|
||||
|
||||
/// If neither -fsemantic-interposition or -fno-semantic-interposition is specified,
|
||||
/// or -fno-semantic-interposition is specified but the target does not support
|
||||
/// local aliases, use the traditional half-baked behavor: interprocedural
|
||||
/// optimizations are allowed but local aliases are not used. If references are
|
||||
/// not optimized out, semantic interposition at runtime is possible.
|
||||
// RUN: %clang -target aarch64 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=HALF %s
|
||||
// RUN: %clang -target ppc64le %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=HALF %s
|
||||
|
||||
// RUN: %clang -target x86_64 %s -Werror -fPIC -c -### 2>&1 | FileCheck --check-prefix=HALF %s
|
||||
//
|
||||
// HALF: "-fhalf-no-semantic-interposition"
|
||||
|
|
|
@ -855,7 +855,6 @@ public:
|
|||
|
||||
/// Returns whether semantic interposition is to be respected.
|
||||
bool getSemanticInterposition() const;
|
||||
bool noSemanticInterposition() const;
|
||||
|
||||
/// Set whether semantic interposition is to be respected.
|
||||
void setSemanticInterposition(bool);
|
||||
|
|
|
@ -483,10 +483,8 @@ MCSymbol *AsmPrinter::getSymbolPreferLocal(const GlobalValue &GV) const {
|
|||
if (TM.getTargetTriple().isOSBinFormatELF() && GV.canBenefitFromLocalAlias()) {
|
||||
const Module &M = *GV.getParent();
|
||||
if (TM.getRelocationModel() != Reloc::Static &&
|
||||
M.getPIELevel() == PIELevel::Default)
|
||||
if (GV.isDSOLocal() || (TM.getTargetTriple().isX86() &&
|
||||
GV.getParent()->noSemanticInterposition()))
|
||||
return getSymbolWithGlobalValueBase(&GV, "$local");
|
||||
M.getPIELevel() == PIELevel::Default && GV.isDSOLocal())
|
||||
return getSymbolWithGlobalValueBase(&GV, "$local");
|
||||
}
|
||||
return TM.getSymbol(&GV);
|
||||
}
|
||||
|
|
|
@ -601,13 +601,6 @@ void Module::setSemanticInterposition(bool SI) {
|
|||
addModuleFlag(ModFlagBehavior::Error, "SemanticInterposition", SI);
|
||||
}
|
||||
|
||||
bool Module::noSemanticInterposition() const {
|
||||
// Conservatively require an explicit zero value for now.
|
||||
Metadata *MF = getModuleFlag("SemanticInterposition");
|
||||
auto *Val = cast_or_null<ConstantAsMetadata>(MF);
|
||||
return Val && cast<ConstantInt>(Val->getValue())->getZExtValue() == 0;
|
||||
}
|
||||
|
||||
void Module::setOwnedMemoryBuffer(std::unique_ptr<MemoryBuffer> MB) {
|
||||
OwnedMemoryBuffer = std::move(MB);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue