summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Driver/Options.td4
-rw-r--r--include/clang/Frontend/CodeGenOptions.def1
-rw-r--r--lib/CodeGen/CGCall.cpp3
-rw-r--r--lib/Driver/ToolChains/Arch/X86.cpp18
-rw-r--r--lib/Driver/ToolChains/Clang.cpp3
-rw-r--r--lib/Frontend/CompilerInvocation.cpp2
-rw-r--r--test/CodeGen/attr-speculative-load-hardening.c10
-rw-r--r--test/Driver/x86-target-features.c9
8 files changed, 45 insertions, 5 deletions
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index e4539ab080..32038dc733 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -2009,6 +2009,10 @@ def mno_stackrealign : Flag<["-"], "mno-stackrealign">, Group<m_Group>;
def mretpoline : Flag<["-"], "mretpoline">, Group<m_Group>, Flags<[CoreOption,DriverOption]>;
def mno_retpoline : Flag<["-"], "mno-retpoline">, Group<m_Group>, Flags<[CoreOption,DriverOption]>;
+def mspeculative_load_hardening : Flag<["-"], "mspeculative-load-hardening">,
+ Group<m_Group>, Flags<[CoreOption,CC1Option]>;
+def mno_speculative_load_hardening : Flag<["-"], "mno-speculative-load-hardening">,
+ Group<m_Group>, Flags<[CoreOption]>;
def mrelax : Flag<["-"], "mrelax">, Group<m_riscv_Features_Group>,
HelpText<"Enable linker relaxation">;
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index 4968e7b2bf..f94979c3e6 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -211,6 +211,7 @@ CODEGENOPT(SanitizeCoverageStackDepth, 1, 0) ///< Enable max stack depth tracing
CODEGENOPT(SanitizeStats , 1, 0) ///< Collect statistics for sanitizers.
CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled.
CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float.
+CODEGENOPT(SpeculativeLoadHardening, 1, 0) ///< Enable speculative load hardening.
CODEGENOPT(FineGrainedBitfieldAccesses, 1, 0) ///< Enable fine-grained bitfield accesses.
CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition.
CODEGENOPT(StrictVTablePointers, 1, 0) ///< Optimize based on the strict vtable pointers
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index c2b4c95ae9..8857ffdde4 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -1784,6 +1784,9 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
FuncAttrs.addAttribute("stackrealign");
if (CodeGenOpts.Backchain)
FuncAttrs.addAttribute("backchain");
+
+ if (CodeGenOpts.SpeculativeLoadHardening)
+ FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
}
if (getLangOpts().assumeFunctionsAreConvergent()) {
diff --git a/lib/Driver/ToolChains/Arch/X86.cpp b/lib/Driver/ToolChains/Arch/X86.cpp
index ff2023c2cb..bc707857d8 100644
--- a/lib/Driver/ToolChains/Arch/X86.cpp
+++ b/lib/Driver/ToolChains/Arch/X86.cpp
@@ -146,15 +146,23 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
// Translate the high level `-mretpoline` flag to the specific target feature
// flags. We also detect if the user asked for retpoline external thunks but
- // failed to ask for retpolines themselves. This is a bit hacky but keeps
- // existing usages working. We should consider deprecated this and instead
- // warning if the user requests external retpoline thunks and *doesn't*
- // request some form of retpolines.
- if (Args.hasArgNoClaim(options::OPT_mretpoline, options::OPT_mno_retpoline)) {
+ // failed to ask for retpolines themselves (through any of the different
+ // flags). This is a bit hacky but keeps existing usages working. We should
+ // consider deprecating this and instead warn if the user requests external
+ // retpoline thunks and *doesn't* request some form of retpolines.
+ if (Args.hasArgNoClaim(options::OPT_mretpoline, options::OPT_mno_retpoline,
+ options::OPT_mspeculative_load_hardening,
+ options::OPT_mno_speculative_load_hardening)) {
if (Args.hasFlag(options::OPT_mretpoline, options::OPT_mno_retpoline,
false)) {
Features.push_back("+retpoline-indirect-calls");
Features.push_back("+retpoline-indirect-branches");
+ } else if (Args.hasFlag(options::OPT_mspeculative_load_hardening,
+ options::OPT_mno_speculative_load_hardening,
+ false)) {
+ // On x86, speculative load hardening relies on at least using retpolines
+ // for indirect calls.
+ Features.push_back("+retpoline-indirect-calls");
}
} else if (Args.hasFlag(options::OPT_mretpoline_external_thunk,
options::OPT_mno_retpoline_external_thunk, false)) {
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index ff083c79f1..79129a7a7c 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -4132,6 +4132,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_pthread);
+ Args.AddLastArg(CmdArgs, options::OPT_mspeculative_load_hardening,
+ options::OPT_mno_speculative_load_hardening);
+
RenderSSPOptions(getToolChain(), Args, CmdArgs, KernelOrKext);
// Translate -mstackrealign
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 4ac7929328..5210314493 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1147,6 +1147,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.KeepStaticConsts = Args.hasArg(OPT_fkeep_static_consts);
+ Opts.SpeculativeLoadHardening = Args.hasArg(OPT_mspeculative_load_hardening);
+
return Success;
}
diff --git a/test/CodeGen/attr-speculative-load-hardening.c b/test/CodeGen/attr-speculative-load-hardening.c
new file mode 100644
index 0000000000..ccbded44bb
--- /dev/null
+++ b/test/CodeGen/attr-speculative-load-hardening.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -mspeculative-load-hardening -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s -check-prefix=SLH
+//
+// Check that we set the attribute on each function.
+
+int test1() {
+ return 42;
+}
+// SLH: @{{.*}}test1{{.*}}[[SLH:#[0-9]+]]
+
+// SLH: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
diff --git a/test/Driver/x86-target-features.c b/test/Driver/x86-target-features.c
index 527a9a2cff..ee2e6afd61 100644
--- a/test/Driver/x86-target-features.c
+++ b/test/Driver/x86-target-features.c
@@ -140,6 +140,15 @@
// RETPOLINE-EXTERNAL-THUNK: "-target-feature" "+retpoline-external-thunk"
// NO-RETPOLINE-EXTERNAL-THUNK: "-target-feature" "-retpoline-external-thunk"
+// RUN: %clang -target i386-linux-gnu -mspeculative-load-hardening %s -### -o %t.o 2>&1 | FileCheck -check-prefix=SLH %s
+// RUN: %clang -target i386-linux-gnu -mretpoline -mspeculative-load-hardening %s -### -o %t.o 2>&1 | FileCheck -check-prefix=RETPOLINE %s
+// RUN: %clang -target i386-linux-gnu -mno-speculative-load-hardening %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-SLH %s
+// SLH-NOT: retpoline
+// SLH: "-target-feature" "+retpoline-indirect-calls"
+// SLH-NOT: retpoline
+// SLH: "-mspeculative-load-hardening"
+// NO-SLH-NOT: retpoline
+
// RUN: %clang -target i386-linux-gnu -mwaitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=WAITPKG %s
// RUN: %clang -target i386-linux-gnu -mno-waitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-WAITPKG %s
// WAITPKG: "-target-feature" "+waitpkg"