Skip to content

Conversation

@fmayer
Copy link
Contributor

@fmayer fmayer commented Nov 19, 2025

This is currently a no op.
This will be supported for the minimal runtime in a follow up. This allows
to improve codegen for fsanitize-recover by compiling the handlers with
[[clang::preserve_all]]. This makes sure that the caller does not need
to spill any registers. We do not expect this function to be called
frequently, so this is beneficial for code size.

Created using spr 1.3.7
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Nov 19, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 19, 2025

@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-clang

Author: Florian Mayer (fmayer)

Changes

This is currently a no op.

This will be supported for the minimal runtime in a follow up. This allows
to improve codegen for fsanitize-recover by compiling the handlers with
[[clang::preserve_all]]. This makes sure that the caller does not need
to spill any registers. We do not expect this function to be called
frequently, so this is beneficial for code size.


Full diff: https://github.com/llvm/llvm-project/pull/168644.diff

5 Files Affected:

  • (modified) clang/include/clang/Basic/CodeGenOptions.def (+2)
  • (modified) clang/include/clang/Driver/SanitizerArgs.h (+1)
  • (modified) clang/include/clang/Options/Options.td (+5)
  • (modified) clang/lib/Driver/SanitizerArgs.cpp (+6)
  • (modified) clang/test/Driver/fsanitize.c (+5)
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 52360b67b306c..3c9cdf5545c1f 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -270,6 +270,8 @@ CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0, Benign) ///< Enable use-after-delet
 CODEGENOPT(SanitizeCfiCrossDso, 1, 0, Benign) ///< Enable cross-dso support in CFI.
 CODEGENOPT(SanitizeMinimalRuntime, 1, 0, Benign) ///< Use "_minimal" sanitizer runtime for
                                                  ///< diagnostics.
+CODEGENOPT(SanitizePreserveRuntime, 1, 0, Benign) ///< Use "_preserve" sanitizer runtime for
+                                                 ///< diagnostics.
 CODEGENOPT(SanitizeCfiICallGeneralizePointers, 1, 0, Benign) ///< Generalize pointer types in
                                                              ///< CFI icall function signatures
 CODEGENOPT(SanitizeCfiICallNormalizeIntegers, 1, 0, Benign) ///< Normalize integer types in
diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h
index eea7897e96afd..eef482cb577a9 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -67,6 +67,7 @@ class SanitizerArgs {
   bool TsanFuncEntryExit = true;
   bool TsanAtomics = true;
   bool MinimalRuntime = false;
+  bool PreserveRuntime = false;
   // True if cross-dso CFI support if provided by the system (i.e. Android).
   bool ImplicitCfiRuntime = false;
   bool NeedsMemProfRt = false;
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 2f7434d8afe11..a3e0566d9763d 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -2656,6 +2656,11 @@ defm sanitize_minimal_runtime : BoolOption<"f", "sanitize-minimal-runtime",
   PosFlag<SetTrue>,
   NegFlag<SetFalse>>,
   Group<f_clang_Group>;
+defm sanitize_preserve_runtime
+    : BoolOption<"f", "sanitize-preserve-runtime",
+                 CodeGenOpts<"SanitizePreserveRuntime">, DefaultFalse,
+                 PosFlag<SetTrue>, NegFlag<SetFalse>>,
+      Group<f_clang_Group>;
 def fsanitize_link_runtime : Flag<["-"], "fsanitize-link-runtime">,
                            Group<f_clang_Group>;
 def fno_sanitize_link_runtime : Flag<["-"], "fno-sanitize-link-runtime">,
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 420c4cddbc8dd..c5ef3018b2455 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -423,6 +423,9 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
   MinimalRuntime =
       Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
                    options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
+  PreserveRuntime =
+      Args.hasFlag(options::OPT_fsanitize_preserve_runtime,
+                   options::OPT_fno_sanitize_preserve_runtime, PreserveRuntime);
 
   // The object size sanitizer should not be enabled at -O0.
   Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
@@ -1469,6 +1472,9 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
   if (MinimalRuntime)
     CmdArgs.push_back("-fsanitize-minimal-runtime");
 
+  if (PreserveRuntime)
+    CmdArgs.push_back("-fsanitize-preserve-runtime");
+
   if (AsanFieldPadding)
     CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
                                          Twine(AsanFieldPadding)));
diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c
index 263301ad4466a..03241c2fcf91a 100644
--- a/clang/test/Driver/fsanitize.c
+++ b/clang/test/Driver/fsanitize.c
@@ -984,6 +984,11 @@
 // CHECK-UBSAN-MINIMAL: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function),?){18}"}}
 // CHECK-UBSAN-MINIMAL: "-fsanitize-minimal-runtime"
 
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-minimal-runtime -fsanitize-preserve-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-MINIMAL-PRESERVE
+// CHECK-UBSAN-MINIMAL-PRESERVE: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function),?){18}"}}
+// CHECK-UBSAN-MINIMAL-PRESERVE: "-fsanitize-minimal-runtime"
+// CHECK-UBSAN-MINIMAL-PRESERVE: "-fsanitize-preserve-runtime"
+
 // RUN: %clang --target=x86_64-linux-gnu -fsanitize=integer -fsanitize-trap=integer %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INTSAN-TRAP
 // CHECK-INTSAN-TRAP: "-fsanitize-trap=integer-divide-by-zero,shift-base,shift-exponent,signed-integer-overflow,unsigned-integer-overflow,unsigned-shift-base,implicit-unsigned-integer-truncation,implicit-signed-integer-truncation,implicit-integer-sign-change"
 

@fmayer fmayer marked this pull request as draft November 19, 2025 04:19
Created using spr 1.3.7
Created using spr 1.3.7
@fmayer fmayer changed the title [UBsan] add -fsanitize-preserve-runtime flag [UBsan] add -fsanitize-handler-preserve-all-regs flag Nov 20, 2025
@fmayer fmayer requested a review from vitalybuka November 20, 2025 07:43
@fmayer fmayer marked this pull request as ready for review November 20, 2025 07:44
Group<f_clang_Group>;
defm sanitize_handler_preserve_all_regs
: BoolOption<"f", "sanitize-handler-preserve-all-regs",
CodeGenOpts<"SanitizeHandlerPreserveAllRegs">, DefaultFalse,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HelpText<>?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

Created using spr 1.3.7
Created using spr 1.3.7

[skip ci]
Created using spr 1.3.7
@fmayer fmayer changed the base branch from users/fmayer/spr/main.ubsan-add-fsanitize-preserve-runtime-flag to main November 20, 2025 23:46
@github-actions
Copy link

🐧 Linux x64 Test Results

  • 111346 tests passed
  • 4435 tests skipped

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants