Skip to content

Commit fd09f12

Browse files
author
serge-sans-paille
committed
Implement -fsemantic-interposition
First attempt at implementing -fsemantic-interposition. Rely on GlobalValue::isInterposable that already captures most of the expected behavior. Rely on a ModuleFlag to state whether we should respect SemanticInterposition or not. The default remains no. So this should be a no-op if -fsemantic-interposition isn't used, and if it is, isInterposable being already used in most optimisation, they should honor it properly. Note that it only impacts architecture compiled with -fPIC and no pie. Differential Revision: https://reviews.llvm.org/D72829
1 parent 24f0b6b commit fd09f12

File tree

15 files changed

+114
-6
lines changed

15 files changed

+114
-6
lines changed

clang/docs/ClangCommandLineReference.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,12 @@ Strip (or keep only, if negative) a given number of path components when emittin
904904

905905
Turn on runtime checks for various forms of undefined or suspicious behavior. See user manual for available checks
906906

907+
.. option:: -fno-semantic-interposition, -fsemantic-interposition
908+
909+
Enable semantic interposition. Semantic interposition allows for the
910+
interposition of a symbol by another at runtime, thus preventing a range of
911+
inter-procedural optimisation.
912+
907913
.. option:: -moutline, -mno-outline
908914

909915
Enable function outlining (AArch64 only)

clang/include/clang/Basic/LangOptions.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility,
284284
"default visibility for types [-ftype-visibility]")
285285
LANGOPT(SetVisibilityForExternDecls, 1, 0,
286286
"apply global symbol visibility to external declarations without an explicit visibility")
287+
BENIGN_LANGOPT(SemanticInterposition , 1, 0, "semantic interposition")
287288
ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff,
288289
"stack protector mode")
289290
ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized,

clang/include/clang/Driver/Options.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3283,7 +3283,8 @@ defm inline_small_functions : BooleanFFlag<"inline-small-functions">,
32833283
defm ipa_cp : BooleanFFlag<"ipa-cp">,
32843284
Group<clang_ignored_gcc_optimization_f_Group>;
32853285
defm ivopts : BooleanFFlag<"ivopts">, Group<clang_ignored_gcc_optimization_f_Group>;
3286-
def : Flag<["-"], "fno-semantic-interposition">, Group<clang_ignored_f_Group>;
3286+
def fsemantic_interposition : Flag<["-"], "fsemantic-interposition">, Group<f_Group>, Flags<[CC1Option]>;
3287+
def fno_semantic_interposition: Flag<["-"], "fno-semantic-interposition">, Group<f_Group>;
32873288
defm non_call_exceptions : BooleanFFlag<"non-call-exceptions">, Group<clang_ignored_f_Group>;
32883289
defm peel_loops : BooleanFFlag<"peel-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
32893290
defm permissive : BooleanFFlag<"permissive">, Group<clang_ignored_f_Group>;

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,11 @@ void CodeGenModule::Release() {
483483
getModule().addModuleFlag(llvm::Module::Max, "Dwarf Version",
484484
CodeGenOpts.DwarfVersion);
485485
}
486+
487+
if (Context.getLangOpts().SemanticInterposition)
488+
// Require various optimization to respect semantic interposition.
489+
getModule().setSemanticInterposition(1);
490+
486491
if (CodeGenOpts.EmitCodeView) {
487492
// Indicate that we want CodeView in the metadata.
488493
getModule().addModuleFlag(llvm::Module::Warning, "CodeView", 1);
@@ -872,7 +877,7 @@ static bool shouldAssumeDSOLocal(const CodeGenModule &CGM,
872877
if (isa<llvm::Function>(GV) && !CGOpts.NoPLT && RM == llvm::Reloc::Static)
873878
return true;
874879

875-
// Otherwise don't assue it is local.
880+
// Otherwise don't assume it is local.
876881
return false;
877882
}
878883

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5037,6 +5037,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
50375037
options::OPT_fno_emulated_tls);
50385038
Args.AddLastArg(CmdArgs, options::OPT_fkeep_static_consts);
50395039

5040+
if (Args.hasFlag(options::OPT_fsemantic_interposition,
5041+
options::OPT_fno_semantic_interposition, false))
5042+
CmdArgs.push_back("-fsemantic-interposition");
5043+
50405044
// AltiVec-like language extensions aren't relevant for assembling.
50415045
if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm)
50425046
Args.AddLastArg(CmdArgs, options::OPT_fzvector);

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3036,6 +3036,10 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
30363036
Opts.setDefaultCallingConv(DefaultCC);
30373037
}
30383038

3039+
// -fsemantic-interposition
3040+
Opts.SemanticInterposition =
3041+
Args.hasArg(OPT_fsemantic_interposition) && Opts.PICLevel && !Opts.PIE;
3042+
30393043
// -mrtd option
30403044
if (Arg *A = Args.getLastArg(OPT_mrtd)) {
30413045
if (Opts.getDefaultCallingConv() != LangOptions::DCC_None)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Semantic Interposition is active if
2+
// -fsemantic-interposition is set,
3+
// - pic-level > 0
4+
// - pic-is-pie is not set
5+
6+
// RUN: %clang_cc1 -emit-llvm -fsemantic-interposition -pic-level 0 %s -o - | FileCheck %s -check-prefix=CHECK-NO-INTERPOSITION
7+
// RUN: %clang_cc1 -emit-llvm -fsemantic-interposition -pic-level 1 %s -o - | FileCheck %s -check-prefix=CHECK-INTERPOSITION
8+
// RUN: %clang_cc1 -emit-llvm -fsemantic-interposition -pic-level 2 %s -o - | FileCheck %s -check-prefix=CHECK-INTERPOSITION
9+
// RUN: %clang_cc1 -emit-llvm -fsemantic-interposition -pic-level 0 %s -o - | FileCheck %s -check-prefix=CHECK-NO-INTERPOSITION
10+
// RUN: %clang_cc1 -emit-llvm -fsemantic-interposition -pic-level 1 -pic-is-pie %s -o - | FileCheck %s -check-prefix=CHECK-NO-INTERPOSITION
11+
// RUN: %clang_cc1 -emit-llvm -fsemantic-interposition -pic-level 2 -pic-is-pie %s -o - | FileCheck %s -check-prefix=CHECK-NO-INTERPOSITION
12+
13+
// CHECK-NO-INTERPOSITION-NOT: "SemanticInterposition"
14+
// CHECK-INTERPOSITION: !{{[0-9]+}} = !{i32 1, !"SemanticInterposition", i32 1}

clang/test/Driver/clang_f_opts.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@
252252
// RUN: -fivopts -fno-ivopts \
253253
// RUN: -fnon-call-exceptions -fno-non-call-exceptions \
254254
// RUN: -fno-semantic-interposition \
255+
// RUN: -fsemantic-interposition \
255256
// RUN: -fpermissive -fno-permissive \
256257
// RUN: -fdefer-pop -fno-defer-pop \
257258
// RUN: -fprefetch-loop-arrays -fno-prefetch-loop-arrays \

llvm/include/llvm/IR/GlobalValue.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -423,10 +423,10 @@ class GlobalValue : public Constant {
423423
}
424424

425425
/// Return true if this global's definition can be substituted with an
426-
/// *arbitrary* definition at link time. We cannot do any IPO or inlinining
427-
/// across interposable call edges, since the callee can be replaced with
428-
/// something arbitrary at link time.
429-
bool isInterposable() const { return isInterposableLinkage(getLinkage()); }
426+
/// *arbitrary* definition at link time or load time. We cannot do any IPO or
427+
/// inlining across interposable call edges, since the callee can be
428+
/// replaced with something arbitrary.
429+
bool isInterposable() const;
430430

431431
bool hasExternalLinkage() const { return isExternalLinkage(getLinkage()); }
432432
bool hasAvailableExternallyLinkage() const {

llvm/include/llvm/IR/Module.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,12 @@ class Module {
848848
Metadata *getProfileSummary(bool IsCS);
849849
/// @}
850850

851+
/// Returns whether semantic interposition is to be respected.
852+
bool getSemanticInterposition() const;
853+
854+
/// Set whether semantic interposition is to be respected.
855+
void setSemanticInterposition(bool);
856+
851857
/// Returns true if PLT should be avoided for RTLib calls.
852858
bool getRtLibUseGOT() const;
853859

0 commit comments

Comments
 (0)