-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[hwasan] Don't instrument when PGO profile is collected #86739
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[hwasan] Don't instrument when PGO profile is collected #86739
Conversation
Created using spr 1.3.4
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Vitaly Buka (vitalybuka) ChangesFull diff: https://github.com/llvm/llvm-project/pull/86739.diff 3 Files Affected:
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 82b30b8d815629..75ba3f2c3785de 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -717,8 +717,11 @@ static void addSanitizers(const Triple &TargetTriple,
DestructorKind));
}
};
- ASanPass(SanitizerKind::Address, false);
- ASanPass(SanitizerKind::KernelAddress, true);
+ // Don't slow down already slow `ProfileIRInstr` binary.
+ if (!CodeGenOpts.hasProfileIRInstr()) {
+ ASanPass(SanitizerKind::Address, false);
+ ASanPass(SanitizerKind::KernelAddress, true);
+ }
auto HWASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
if (LangOpts.Sanitize.has(Mask)) {
@@ -728,8 +731,11 @@ static void addSanitizers(const Triple &TargetTriple,
/*DisableOptimization=*/CodeGenOpts.OptimizationLevel == 0}));
}
};
- HWASanPass(SanitizerKind::HWAddress, false);
- HWASanPass(SanitizerKind::KernelHWAddress, true);
+ // Don't slow down already slow `ProfileIRInstr` binary.
+ if (!CodeGenOpts.hasProfileIRInstr()) {
+ HWASanPass(SanitizerKind::HWAddress, false);
+ HWASanPass(SanitizerKind::KernelHWAddress, true);
+ }
if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
MPM.addPass(DataFlowSanitizerPass(LangOpts.NoSanitizeFiles));
diff --git a/clang/test/CodeGen/asan-new-pm.ll b/clang/test/CodeGen/asan-new-pm.ll
index 78d195b0ea2471..528dc1f7a7c400 100644
--- a/clang/test/CodeGen/asan-new-pm.ll
+++ b/clang/test/CodeGen/asan-new-pm.ll
@@ -1,6 +1,12 @@
; Test that ASan runs with the new pass manager
; RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - -fsanitize=address %s | FileCheck %s
-; RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - -O1 -fsanitize=address %s | FileCheck %s
+; RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - -fsanitize=address -O1 %s | FileCheck %s
+
+; RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - -fsanitize=address -fprofile-instrument=llvm %s | FileCheck %s -check-prefixes=NOASAN
+; RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - -fsanitize=address -fprofile-instrument=llvm -O1 %s | FileCheck %s -check-prefixes=NOASAN
+
+; RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - -fsanitize=address -fprofile-instrument=clang %s | FileCheck %s
+; RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - -fsanitize=address -fprofile-instrument=clang -O1 %s | FileCheck %s
; CHECK-DAG: @llvm.global_ctors = {{.*}}@asan.module_ctor
@@ -20,3 +26,4 @@ entry:
; CHECK-DAG: __asan_version_mismatch_check_v8
+; NOASAN-NOT: __asan
\ No newline at end of file
diff --git a/clang/test/CodeGen/hwasan-new-pm.c b/clang/test/CodeGen/hwasan-new-pm.c
index 47014698f6df72..8f5a25c82df222 100644
--- a/clang/test/CodeGen/hwasan-new-pm.c
+++ b/clang/test/CodeGen/hwasan-new-pm.c
@@ -3,12 +3,30 @@
// being instrumented properly.
// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -o - -fsanitize=hwaddress %s | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -o - -O1 -fsanitize=hwaddress %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -o - -fsanitize=hwaddress -O1 %s | FileCheck %s
+
+// Don't instrument when collecting profiles, to avoid additional slowdown of slow `profile-instrument` binary.
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -o - -fsanitize=hwaddress -fprofile-instrument=llvm %s | FileCheck %s -check-prefixes=NOHWASAN
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -o - -fsanitize=hwaddress -fprofile-instrument=llvm -O1 %s | FileCheck %s -check-prefixes=NOHWASAN
+
+// Nothing special is done for clang PGO.
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -o - -fsanitize=hwaddress -fprofile-instrument=clang %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -o - -fsanitize=hwaddress -fprofile-instrument=clang -O1 %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -o - -fsanitize=kernel-hwaddress %s | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -o - -O1 -fsanitize=kernel-hwaddress %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -o - -fsanitize=kernel-hwaddress -O1 %s | FileCheck %s
+
+// Don't instrument when collecting profiles, to avoid additional slowdown of slow `profile-instrument` binary.
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -o - -fsanitize=kernel-hwaddress -fprofile-instrument=llvm %s | FileCheck %s -check-prefixes=NOHWASAN
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -o - -fsanitize=kernel-hwaddress -fprofile-instrument=llvm -O1 %s | FileCheck %s -check-prefixes=NOHWASAN
+
+// Nothing special is done for clang PGO.
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -o - -fsanitize=kernel-hwaddress -fprofile-instrument=clang %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -o - -fsanitize=kernel-hwaddress -fprofile-instrument=clang -O1 %s | FileCheck %s
int foo(int *a) { return *a; }
// All the cases above mark the function with sanitize_hwaddress.
// CHECK: sanitize_hwaddress
+// CHECK: declare void @__hwasan_
+// NOHWASAN-NOT: __hwasan
|
why can't hwasan and PGO instrumentation coexist? and this seems like it should be an error at the clang driver level, instead of silently turning off one of the requested features |
They can, but binary is like 5x times slower, on top of 10x slowdown of PGO instrumentation. (don't quote me on these numbers, they are from large but single benchmark, still it's very slow)
|
If it's usable as a configuration, I don't see why we should prevent this. It still may be useful to some people. Seems like this checking should be done at a build system level if you don't want some codebase to compile with this configuration.
Do you mean that if you want a hwasan/PGO optimized build, you want the corresponding PGO instrumented build to also use hwasan? Doesn't PGO instrumentation/use happen before the sanitizer passes run?
|
At the moment builds system can only disable HWASAN, there is no option to enabled HWASAN but drop the pass.
I want PGO optimized binary with HWASAN.
Instrumentation/use happens before sanitizer pass.
|
We already have similar stuff:
|
Alternative is we need a new clang fronted flag to control this behavior. |
checking for ThinLTO pre/post link is a correctness thing though I think I'm still confused on exactly what the use case is and why we can't just ask the user to not specify hwasan in the PGO instrumented build. Just for user convenience? Or does clang change the emitted IR when hwasan is enabled? And that's what will lead to mismatched profiles? |
-fno-sanitize= IR changes:
maybe other reasons, but as is profile does not match if collected with -fno-sanitize=hwsan Maybe we can find work around for 2 and 3, but no. 1 seems require magic flag to pretend to be HWASAN |
Looked into IR and HWASAN instrument stuff which it should not Should be easy to fix. |
ah I see. I feel like this should be a more principled approach that other sanitizers also share, as you've mentioned as an alternative. do people not care about other sanitizers in production? (I'm going to be OOO for a week, so someone else will need to review) |
Actually Asan should not exhibit this behavior, by some lack it does not instrument PGO counters. We likely need that optimization in HWASAN. generic approach could be marking PGO stuff as MD_nosanitize |
We can't do that for msan, dfsan, and probably tsan as they may
be linked with pre-instrumented binary.
Probably we can disable SanitizerCoveragePass and SanitizerBinaryMetadataPass,
but they are not expensive enough to justify diverging pipeline.