-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
[ubsan][hwasan] Let mixing filters #100680
[ubsan][hwasan] Let mixing filters #100680
Conversation
Created using spr 1.3.4 [skip ci]
Created using spr 1.3.4
@llvm/pr-subscribers-compiler-rt-sanitizer @llvm/pr-subscribers-llvm-transforms Author: Vitaly Buka (vitalybuka) ChangesNow the check will be enabled only if each filter is satisfied. Full diff: https://github.com/llvm/llvm-project/pull/100680.diff 4 Files Affected:
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index a0e63bf12400e..812874ff3c173 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -1528,11 +1528,7 @@ static void emitRemark(const Function &F, OptimizationRemarkEmitter &ORE,
bool HWAddressSanitizer::selectiveInstrumentationShouldSkip(
Function &F, FunctionAnalysisManager &FAM) const {
- bool Skip = [&]() {
- if (ClRandomSkipRate.getNumOccurrences()) {
- std::bernoulli_distribution D(ClRandomSkipRate);
- return !D(*Rng);
- }
+ auto SkipHot = [&]() {
if (!ClHotPercentileCutoff.getNumOccurrences())
return false;
auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
@@ -1544,7 +1540,16 @@ bool HWAddressSanitizer::selectiveInstrumentationShouldSkip(
}
return PSI->isFunctionHotInCallGraphNthPercentile(
ClHotPercentileCutoff, &F, FAM.getResult<BlockFrequencyAnalysis>(F));
- }();
+ };
+
+ auto SkipRandom = [&]() {
+ if (!ClRandomSkipRate.getNumOccurrences())
+ return false;
+ std::bernoulli_distribution D(ClRandomSkipRate);
+ return !D(*Rng);
+ };
+
+ bool Skip = SkipRandom() || SkipHot();
emitRemark(F, FAM.getResult<OptimizationRemarkEmitterAnalysis>(F), Skip);
return Skip;
}
diff --git a/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp b/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp
index 0115809e939e8..19cf7dc7e7544 100644
--- a/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp
+++ b/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp
@@ -76,13 +76,25 @@ static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI,
SmallVector<std::pair<IntrinsicInst *, bool>, 16> ReplaceWithValue;
std::unique_ptr<RandomNumberGenerator> Rng;
- auto ShouldRemove = [&](bool IsHot) {
- if (!RandomRate.getNumOccurrences())
- return IsHot;
+ auto GetRng = [&]() -> RandomNumberGenerator & {
if (!Rng)
Rng = F.getParent()->createRNG(F.getName());
- std::bernoulli_distribution D(RandomRate);
- return !D(*Rng);
+ return *Rng;
+ };
+
+ auto ShouldRemoveHot = [&](const BasicBlock &BB) {
+ return HotPercentileCutoff.getNumOccurrences() && PSI &&
+ PSI->isHotCountNthPercentile(
+ HotPercentileCutoff, BFI.getBlockProfileCount(&BB).value_or(0));
+ };
+
+ auto ShouldRemoveRandom = [&]() {
+ return RandomRate.getNumOccurrences() &&
+ !std::bernoulli_distribution(RandomRate)(GetRng());
+ };
+
+ auto ShouldRemove = [&](const BasicBlock &BB) {
+ return ShouldRemoveRandom() || ShouldRemoveHot(BB);
};
for (BasicBlock &BB : F) {
@@ -96,13 +108,7 @@ static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI,
case Intrinsic::allow_runtime_check: {
++NumChecksTotal;
- bool IsHot = false;
- if (PSI) {
- uint64_t Count = BFI.getBlockProfileCount(&BB).value_or(0);
- IsHot = PSI->isHotCountNthPercentile(HotPercentileCutoff, Count);
- }
-
- bool ToRemove = ShouldRemove(IsHot);
+ bool ToRemove = ShouldRemove(BB);
ReplaceWithValue.push_back({
II,
ToRemove,
diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/pgo-opt-out.ll b/llvm/test/Instrumentation/HWAddressSanitizer/pgo-opt-out.ll
index 01eda4e35d7c1..0ef94235fd515 100644
--- a/llvm/test/Instrumentation/HWAddressSanitizer/pgo-opt-out.ll
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/pgo-opt-out.ll
@@ -2,6 +2,8 @@
; RUN: opt < %s -passes='require<profile-summary>,hwasan' -pass-remarks=hwasan -pass-remarks-missed=hwasan -S -hwasan-percentile-cutoff-hot=990000 2>&1 | FileCheck %s --check-prefix=NONE
; RUN: opt < %s -passes='require<profile-summary>,hwasan' -pass-remarks=hwasan -pass-remarks-missed=hwasan -S -hwasan-random-rate=1.0 2>&1 | FileCheck %s --check-prefix=ALL
; RUN: opt < %s -passes='require<profile-summary>,hwasan' -pass-remarks=hwasan -pass-remarks-missed=hwasan -S -hwasan-random-rate=0.0 2>&1 | FileCheck %s --check-prefix=NONE
+; RUN: opt < %s -passes='require<profile-summary>,hwasan' -pass-remarks=hwasan -pass-remarks-missed=hwasan -S -hwasan-random-rate=1.0 -hwasan-percentile-cutoff-hot=990000 2>&1 | FileCheck %s --check-prefix=NONE
+; RUN: opt < %s -passes='require<profile-summary>,hwasan' -pass-remarks=hwasan -pass-remarks-missed=hwasan -S -hwasan-random-rate=0.0 -hwasan-percentile-cutoff-hot=700000 2>&1 | FileCheck %s --check-prefix=NONE
; ALL: remark: <unknown>:0:0: Sanitized: F=sanitize
; ALL: @sanitized
diff --git a/llvm/test/Transforms/lower-builtin-allow-check.ll b/llvm/test/Transforms/lower-builtin-allow-check.ll
index 2f6fa96ffd9c5..bcd9722d2b289 100644
--- a/llvm/test/Transforms/lower-builtin-allow-check.ll
+++ b/llvm/test/Transforms/lower-builtin-allow-check.ll
@@ -309,7 +309,7 @@ define dso_local noundef i32 @veryHot(ptr noundef readonly %0) !prof !39 {
; ALL70-LABEL: define dso_local noundef i32 @veryHot(
; ALL70-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF17:![0-9]+]] {
; ALL70-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP0]], null
-; ALL70-NEXT: [[HOT:%.*]] = xor i1 true, true
+; ALL70-NEXT: [[HOT:%.*]] = xor i1 false, true
; ALL70-NEXT: [[TMP2:%.*]] = or i1 [[CHK]], [[HOT]]
; ALL70-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]]
; ALL70: 3:
|
Created using spr 1.3.4 [skip ci]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is ShouldRemoveRandom() || ShouldRemoveHot(BB);
the most interpretable way to combine these filters? e.g., suppose ClRandomSkipRate = 0.6 and ClHotPercentileCutoff is 750000 (75%th). What is the percentage of checks that is skipped?
Perhaps another approach could be to have three settings:
- hot percentile cutoff: this by default doesn't skip anything
- random skip percentage for hot functions
- random skip percentage for cold functions
The fully random case is equivalent to setting the same random skip percentage for hot and cold functions. The skip-hot-functions-only case is equivalent to setting the random skip percentage for cold functions to zero. This also enables new combinations e.g., instrument 90% of hot functions and 10% of cold functions, or 90% of hot functions and 0% of cold functions.
I don't see value in randomizing 'hot', the cost is very different, so user should rather change "hot percentile cutoff" or disable hot filter. |
Now the check will be enabled only if each filter is satisfied.