Author: Florian Mayer Date: 2025-06-27T13:46:54-07:00 New Revision: 8d2034cf68b51041a40069b0d868dfcdbf719685
URL: https://github.com/llvm/llvm-project/commit/8d2034cf68b51041a40069b0d868dfcdbf719685 DIFF: https://github.com/llvm/llvm-project/commit/8d2034cf68b51041a40069b0d868dfcdbf719685.diff LOG: [clang] Add flag fallow-runtime-check-skip-hot-cutoff (#145999) Co-authored-by: Kazu Hirata <k...@google.com> Added: clang/test/CodeGen/fallow-runtime-check-skip-hot-cutoff.c clang/test/Driver/fallow-runtime-check-skip-hot-cutoff.c Modified: clang/include/clang/Basic/CodeGenOptions.h clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index 77a0c559f7689..1b99d56fc68e1 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -399,6 +399,8 @@ class CodeGenOptions : public CodeGenOptionsBase { /// with extra debug info. SanitizerSet SanitizeAnnotateDebugInfo; + std::optional<double> AllowRuntimeCheckSkipHotCutoff; + /// List of backend command-line options for -fembed-bitcode. std::vector<uint8_t> CmdArgs; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 0822df2640d23..9911d752966e3 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2668,6 +2668,15 @@ def fsanitize_skip_hot_cutoff_EQ } // end -f[no-]sanitize* flags +def fallow_runtime_check_skip_hot_cutoff_EQ + : Joined<["-"], "fallow-runtime-check-skip-hot-cutoff=">, + Group<f_clang_Group>, + Visibility<[ClangOption, CC1Option]>, + HelpText<"Exclude __builtin_allow_runtime_check for the top hottest " + "code responsible for the given fraction of PGO counters " + "(0.0 [default] = skip none; 1.0 = skip all). " + "Argument format: <value>">; + def funsafe_math_optimizations : Flag<["-"], "funsafe-math-optimizations">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>, HelpText<"Allow unsafe floating-point math optimizations which may decrease precision">, diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 97bc063ad34e5..1c92ea45c7458 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -805,17 +805,21 @@ static void addSanitizers(const Triple &TargetTriple, // SanitizeSkipHotCutoffs: doubles with range [0, 1] // Opts.cutoffs: unsigned ints with range [0, 1000000] auto ScaledCutoffs = CodeGenOpts.SanitizeSkipHotCutoffs.getAllScaled(1000000); - + uint64_t AllowRuntimeCheckSkipHotCutoff = + CodeGenOpts.AllowRuntimeCheckSkipHotCutoff.value_or(0.0) * 1000000; // TODO: remove IsRequested() - if (LowerAllowCheckPass::IsRequested() || ScaledCutoffs.has_value()) { + if (LowerAllowCheckPass::IsRequested() || ScaledCutoffs.has_value() || + CodeGenOpts.AllowRuntimeCheckSkipHotCutoff.has_value()) { // We want to call it after inline, which is about OptimizerEarlyEPCallback. PB.registerOptimizerEarlyEPCallback( - [ScaledCutoffs](ModulePassManager &MPM, OptimizationLevel Level, - ThinOrFullLTOPhase Phase) { + [ScaledCutoffs, AllowRuntimeCheckSkipHotCutoff]( + ModulePassManager &MPM, OptimizationLevel Level, + ThinOrFullLTOPhase Phase) { LowerAllowCheckPass::Options Opts; // TODO: after removing IsRequested(), make this unconditional if (ScaledCutoffs.has_value()) Opts.cutoffs = ScaledCutoffs.value(); + Opts.runtime_check = AllowRuntimeCheckSkipHotCutoff; MPM.addPass( createModuleToFunctionPassAdaptor(LowerAllowCheckPass(Opts))); }); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 8a18865b899d2..ceb592d1548f5 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6028,7 +6028,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more // complicated ways. auto SanitizeArgs = TC.getSanitizerArgs(Args); - + Args.AddLastArg(CmdArgs, + options::OPT_fallow_runtime_check_skip_hot_cutoff_EQ); bool IsAsyncUnwindTablesDefault = TC.getDefaultUnwindTableLevel(Args) == ToolChain::UnwindTableLevel::Asynchronous; bool IsSyncUnwindTablesDefault = diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 9e269ab244d4c..f366e90945dac 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1820,6 +1820,11 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts, for (std::string Sanitizer : Values) GenerateArg(Consumer, OPT_fsanitize_skip_hot_cutoff_EQ, Sanitizer); + if (Opts.AllowRuntimeCheckSkipHotCutoff) { + GenerateArg(Consumer, OPT_fallow_runtime_check_skip_hot_cutoff_EQ, + std::to_string(*Opts.AllowRuntimeCheckSkipHotCutoff)); + } + for (StringRef Sanitizer : serializeSanitizerKinds(Opts.SanitizeAnnotateDebugInfo)) GenerateArg(Consumer, OPT_fsanitize_annotate_debug_info_EQ, Sanitizer); @@ -2322,6 +2327,18 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Args.getAllArgValues(OPT_fsanitize_annotate_debug_info_EQ), Diags, Opts.SanitizeAnnotateDebugInfo); + if (StringRef V = + Args.getLastArgValue(OPT_fallow_runtime_check_skip_hot_cutoff_EQ); + !V.empty()) { + double A; + if (V.getAsDouble(A) || A < 0.0 || A > 1.0) { + Diags.Report(diag::err_drv_invalid_value) + << "-fallow-runtime-check-skip-hot-cutoff=" << V; + } else { + Opts.AllowRuntimeCheckSkipHotCutoff = A; + } + } + Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true); if (!LangOpts->CUDAIsDevice) diff --git a/clang/test/CodeGen/fallow-runtime-check-skip-hot-cutoff.c b/clang/test/CodeGen/fallow-runtime-check-skip-hot-cutoff.c new file mode 100644 index 0000000000000..0f1cdf9512395 --- /dev/null +++ b/clang/test/CodeGen/fallow-runtime-check-skip-hot-cutoff.c @@ -0,0 +1,15 @@ +// RUN: %clang -fallow-runtime-check-skip-hot-cutoff=1.0 -S -emit-llvm %s -o - -O2 | FileCheck --check-prefix=ONE %s +// RUN: %clang -fallow-runtime-check-skip-hot-cutoff=0.0 -S -emit-llvm %s -o - -O2 | FileCheck --check-prefix=ZERO %s +// RUN: not %clang -fallow-runtime-check-skip-hot-cutoff=6.0 -S -emit-llvm %s -o - -O2 2>&1 | FileCheck --check-prefix=SIX %s +// RUN: not %clang -fallow-runtime-check-skip-hot-cutoff=-1.0 -S -emit-llvm %s -o - -O2 2>&1 | FileCheck --check-prefix=MINUSONE %s +// RUN: not %clang -fallow-runtime-check-skip-hot-cutoff=string -S -emit-llvm %s -o - -O2 2>&1 | FileCheck --check-prefix=STRING %s + +// ONE: ret i32 0 +// ZERO: ret i32 1 +// SIX: invalid value '6.0' in '-fallow-runtime-check-skip-hot-cutoff=' +// MINUSONE: invalid value '-1.0' in '-fallow-runtime-check-skip-hot-cutoff=' +// STRING: invalid value 'string' in '-fallow-runtime-check-skip-hot-cutoff=' + +int main(int argc, char** argv) { + return __builtin_allow_runtime_check("foo"); +} diff --git a/clang/test/Driver/fallow-runtime-check-skip-hot-cutoff.c b/clang/test/Driver/fallow-runtime-check-skip-hot-cutoff.c new file mode 100644 index 0000000000000..b186e6e74f162 --- /dev/null +++ b/clang/test/Driver/fallow-runtime-check-skip-hot-cutoff.c @@ -0,0 +1,6 @@ +// RUN: %clang -### -fallow-runtime-check-skip-hot-cutoff=1.0 %s 2>&1 | FileCheck %s +// CHECK: -fallow-runtime-check-skip-hot-cutoff=1.0 + +int main(int argc, char** argv) { + return __builtin_allow_runtime_check("foo"); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits