Skip to content

Commit 4258b0e

Browse files
authored
[HWASAN] Follow up for #83503 implement selective instrumentation (#83942)
1. Change tests to use IR instead of -stats to avoid depending on Debug mode 2. Add SkipInstrumentationRandomRate 3. Remove HWASAN from stat strings
1 parent b84f3ea commit 4258b0e

File tree

3 files changed

+86
-40
lines changed

3 files changed

+86
-40
lines changed

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include "llvm/Support/Casting.h"
5353
#include "llvm/Support/CommandLine.h"
5454
#include "llvm/Support/Debug.h"
55+
#include "llvm/Support/RandomNumberGenerator.h"
5556
#include "llvm/Support/raw_ostream.h"
5657
#include "llvm/TargetParser/Triple.h"
5758
#include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h"
@@ -61,6 +62,7 @@
6162
#include "llvm/Transforms/Utils/ModuleUtils.h"
6263
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
6364
#include <optional>
65+
#include <random>
6466

6567
using namespace llvm;
6668

@@ -181,16 +183,23 @@ static cl::opt<bool> ClWithTls(
181183
cl::Hidden, cl::init(true));
182184

183185
static cl::opt<bool>
184-
CSkipHotCode("hwasan-skip-hot-code",
185-
cl::desc("Do not instument hot functions based on FDO."),
186-
cl::Hidden, cl::init(false));
186+
CSelectiveInstrumentation("hwasan-selective-instrumentation",
187+
cl::desc("Use selective instrumentation"),
188+
cl::Hidden, cl::init(false));
187189

188-
static cl::opt<int> HotPercentileCutoff("hwasan-percentile-cutoff-hot",
189-
cl::init(0));
190+
static cl::opt<int> HotPercentileCutoff(
191+
"hwasan-percentile-cutoff-hot", cl::init(0),
192+
cl::desc("Alternative hot percentile cuttoff."
193+
"By default `-profile-summary-cutoff-hot` is used."));
190194

191-
STATISTIC(NumTotalFuncs, "Number of total funcs HWASAN");
192-
STATISTIC(NumInstrumentedFuncs, "Number of HWASAN instrumented funcs");
193-
STATISTIC(NumNoProfileSummaryFuncs, "Number of HWASAN funcs without PS");
195+
static cl::opt<float>
196+
RandomSkipRate("hwasan-random-skip-rate", cl::init(0),
197+
cl::desc("Probability value in the range [0.0, 1.0] "
198+
"to skip instrumentation of a function."));
199+
200+
STATISTIC(NumTotalFuncs, "Number of total funcs");
201+
STATISTIC(NumInstrumentedFuncs, "Number of instrumented funcs");
202+
STATISTIC(NumNoProfileSummaryFuncs, "Number of funcs without PS");
194203

195204
// Mode for selecting how to insert frame record info into the stack ring
196205
// buffer.
@@ -291,6 +300,8 @@ class HWAddressSanitizer {
291300
this->CompileKernel = ClEnableKhwasan.getNumOccurrences() > 0
292301
? ClEnableKhwasan
293302
: CompileKernel;
303+
this->Rng =
304+
RandomSkipRate.getNumOccurrences() ? M.createRNG("hwasan") : nullptr;
294305

295306
initializeModule();
296307
}
@@ -372,6 +383,7 @@ class HWAddressSanitizer {
372383
Module &M;
373384
const StackSafetyGlobalInfo *SSI;
374385
Triple TargetTriple;
386+
std::unique_ptr<RandomNumberGenerator> Rng;
375387

376388
/// This struct defines the shadow mapping using the rule:
377389
/// shadow = (mem >> Scale) + Offset.
@@ -1526,19 +1538,26 @@ void HWAddressSanitizer::sanitizeFunction(Function &F,
15261538
return;
15271539

15281540
NumTotalFuncs++;
1529-
if (CSkipHotCode) {
1530-
auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
1531-
ProfileSummaryInfo *PSI =
1532-
MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
1533-
if (PSI && PSI->hasProfileSummary()) {
1534-
auto &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);
1535-
if ((HotPercentileCutoff.getNumOccurrences() && HotPercentileCutoff >= 0)
1536-
? PSI->isFunctionHotInCallGraphNthPercentile(HotPercentileCutoff,
1537-
&F, BFI)
1538-
: PSI->isFunctionHotInCallGraph(&F, BFI))
1541+
if (CSelectiveInstrumentation) {
1542+
if (RandomSkipRate.getNumOccurrences()) {
1543+
std::bernoulli_distribution D(RandomSkipRate);
1544+
if (D(*Rng))
15391545
return;
15401546
} else {
1541-
++NumNoProfileSummaryFuncs;
1547+
auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
1548+
ProfileSummaryInfo *PSI =
1549+
MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
1550+
if (PSI && PSI->hasProfileSummary()) {
1551+
auto &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);
1552+
if ((HotPercentileCutoff.getNumOccurrences() &&
1553+
HotPercentileCutoff >= 0)
1554+
? PSI->isFunctionHotInCallGraphNthPercentile(
1555+
HotPercentileCutoff, &F, BFI)
1556+
: PSI->isFunctionHotInCallGraph(&F, BFI))
1557+
return;
1558+
} else {
1559+
++NumNoProfileSummaryFuncs;
1560+
}
15421561
}
15431562
}
15441563
NumInstrumentedFuncs++;
Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,28 @@
1-
; RUN: opt < %s -passes='require<profile-summary>,hwasan' -S -stats 2>&1 \
2-
; RUN: -hwasan-skip-hot-code=0 | FileCheck %s --check-prefix=FULL
3-
; RUN: opt < %s -passes='require<profile-summary>,hwasan' -S -stats 2>&1 \
4-
; RUN: -hwasan-skip-hot-code=1 | FileCheck %s --check-prefix=SELSAN
1+
; RUN: opt < %s -passes='require<profile-summary>,hwasan' -S \
2+
; RUN: -hwasan-selective-instrumentation=0 | FileCheck %s --check-prefix=FULL
3+
; RUN: opt < %s -passes='require<profile-summary>,hwasan' -S \
4+
; RUN: -hwasan-selective-instrumentation=1 | FileCheck %s --check-prefix=SELSAN
55

6-
; REQUIRES: asserts
6+
; FULL: @not_sanitized
7+
; FULL-NEXT: %x = alloca i8, i64 4
8+
; FULL: @sanitized_no_ps
9+
; FULL-NEXT: @__hwasan_tls
710

8-
; FULL: 1 hwasan - Number of HWASAN instrumented funcs
9-
; FULL: 1 hwasan - Number of total funcs HWASAN
11+
; SELSAN: @not_sanitized
12+
; SELSAN-NEXT: %x = alloca i8, i64 4
13+
; SELSAN: @sanitized_no_ps
14+
; SELSAN-NEXT: @__hwasan_tls
1015

11-
; SELSAN: 1 hwasan - Number of HWASAN instrumented funcs
12-
; SELSAN: 1 hwasan - Number of HWASAN funcs without PS
13-
; SELSAN: 1 hwasan - Number of total funcs HWASAN
16+
declare void @use(ptr)
1417

15-
define void @not_sanitized() { ret void }
16-
define void @sanitized_no_ps() sanitize_hwaddress { ret void }
18+
define void @not_sanitized() {
19+
%x = alloca i8, i64 4
20+
call void @use(ptr %x)
21+
ret void
22+
}
23+
24+
define void @sanitized_no_ps() sanitize_hwaddress {
25+
%x = alloca i8, i64 4
26+
call void @use(ptr %x)
27+
ret void
28+
}

llvm/test/Instrumentation/HWAddressSanitizer/pgo-opt-out.ll

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,31 @@
1-
; RUN: opt < %s -passes='require<profile-summary>,hwasan' -S -stats 2>&1 \
2-
; RUN: -hwasan-skip-hot-code=1 | FileCheck %s --check-prefix=DEFAULT
3-
; RUN: opt < %s -passes='require<profile-summary>,hwasan' -S -stats 2>&1 \
4-
; RUN: -hwasan-skip-hot-code=1 -hwasan-percentile-cutoff-hot=700000 | FileCheck %s --check-prefix=PERCENT
1+
; RUN: opt < %s -passes='require<profile-summary>,hwasan' -S -hwasan-selective-instrumentation=1 \
2+
; RUN: | FileCheck %s --check-prefix=DEFAULT
3+
; RUN: opt < %s -passes='require<profile-summary>,hwasan' -S -hwasan-selective-instrumentation=1 \
4+
; RUN: -hwasan-percentile-cutoff-hot=700000 | FileCheck %s --check-prefix=HOT_RATE
5+
; RUN: opt < %s -passes='require<profile-summary>,hwasan' -S -hwasan-selective-instrumentation=1 \
6+
; RUN: -hwasan-random-skip-rate=0.0 | FileCheck %s --check-prefix=RANDOM_RATE_0
7+
; RUN: opt < %s -passes='require<profile-summary>,hwasan' -S -hwasan-selective-instrumentation=1 \
8+
; RUN: -hwasan-random-skip-rate=1.0 | FileCheck %s --check-prefix=RANDOM_RATE_1
59

6-
; REQUIRES: asserts
10+
; DEFAULT: @sanitized
11+
; DEFAULT-NEXT: %x = alloca i8, i64 4
712

8-
; DEFAULT: 1 hwasan - Number of total funcs HWASAN
13+
; HOT_RATE: @sanitized
14+
; HOT_RATE-NEXT: @__hwasan_tls
915

10-
; PERCENT: 1 hwasan - Number of HWASAN instrumented funcs
11-
; PERCENT: 1 hwasan - Number of total funcs HWASAN
16+
; RANDOM_RATE_0: @sanitized
17+
; RANDOM_RATE_0-NEXT: @__hwasan_tls
1218

13-
define void @sanitized() sanitize_hwaddress !prof !36 { ret void }
19+
; RANDOM_RATE_1: @sanitized
20+
; RANDOM_RATE_1-NEXT: %x = alloca i8, i64 4
21+
22+
declare void @use(ptr)
23+
24+
define void @sanitized(i32 noundef %0) sanitize_hwaddress !prof !36 {
25+
%x = alloca i8, i64 4
26+
call void @use(ptr %x)
27+
ret void
28+
}
1429

1530
!llvm.module.flags = !{!6}
1631
!6 = !{i32 1, !"ProfileSummary", !7}

0 commit comments

Comments
 (0)