Skip to content

Commit e7bac3b

Browse files
committed
[msan] Convert Msan to ModulePass
MemorySanitizerPass function pass violatied requirement 4 of function pass to do not insert globals. Msan nees to insert globals for origin tracking, and paramereters tracking. https://llvm.org/docs/WritingAnLLVMPass.html#the-functionpass-class Reviewed By: kstoimenov, fmayer Differential Revision: https://reviews.llvm.org/D133336
1 parent 82b6549 commit e7bac3b

16 files changed

+48
-63
lines changed

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -640,21 +640,18 @@ static void addSanitizers(const Triple &TargetTriple,
640640
MemorySanitizerOptions options(TrackOrigins, Recover, CompileKernel,
641641
CodeGenOpts.SanitizeMemoryParamRetval);
642642
MPM.addPass(ModuleMemorySanitizerPass(options));
643-
FunctionPassManager FPM;
644-
FPM.addPass(MemorySanitizerPass(options));
645643
if (Level != OptimizationLevel::O0) {
646644
// MemorySanitizer inserts complex instrumentation that mostly
647645
// follows the logic of the original code, but operates on
648646
// "shadow" values. It can benefit from re-running some
649647
// general purpose optimization passes.
650-
FPM.addPass(EarlyCSEPass());
648+
MPM.addPass(createModuleToFunctionPassAdaptor(EarlyCSEPass()));
651649
// TODO: Consider add more passes like in
652650
// addGeneralOptsForMemorySanitizer. EarlyCSEPass makes visible
653651
// difference on size. It's not clear if the rest is still
654652
// usefull. InstCombinePass breakes
655653
// compiler-rt/test/msan/select_origin.cpp.
656654
}
657-
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
658655
}
659656
};
660657
MSanPass(SanitizerKind::Memory, false);

llvm/include/llvm/Transforms/Instrumentation/MemorySanitizer.h

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,6 @@ struct MemorySanitizerOptions {
3434
bool EagerChecks;
3535
};
3636

37-
/// A function pass for msan instrumentation.
38-
///
39-
/// Instruments functions to detect unitialized reads. This function pass
40-
/// inserts calls to runtime library functions. If the functions aren't declared
41-
/// yet, the pass inserts the declarations. Otherwise the existing globals are
42-
/// used.
43-
struct MemorySanitizerPass : public PassInfoMixin<MemorySanitizerPass> {
44-
MemorySanitizerPass(MemorySanitizerOptions Options) : Options(Options) {}
45-
46-
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
47-
void printPipeline(raw_ostream &OS,
48-
function_ref<StringRef(StringRef)> MapClassName2PassName);
49-
static bool isRequired() { return true; }
50-
51-
private:
52-
MemorySanitizerOptions Options;
53-
};
54-
5537
/// A module pass for msan instrumentation.
5638
///
5739
/// Instruments functions to detect unitialized reads. This function pass
@@ -62,6 +44,8 @@ struct ModuleMemorySanitizerPass : public PassInfoMixin<ModuleMemorySanitizerPas
6244
ModuleMemorySanitizerPass(MemorySanitizerOptions Options) : Options(Options) {}
6345

6446
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
47+
void printPipeline(raw_ostream &OS,
48+
function_ref<StringRef(StringRef)> MapClassName2PassName);
6549
static bool isRequired() { return true; }
6650

6751
private:

llvm/lib/Passes/PassRegistry.def

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ MODULE_PASS("verify", VerifierPass())
119119
MODULE_PASS("view-callgraph", CallGraphViewerPass())
120120
MODULE_PASS("wholeprogramdevirt", WholeProgramDevirtPass())
121121
MODULE_PASS("dfsan", DataFlowSanitizerPass())
122-
MODULE_PASS("msan-module", ModuleMemorySanitizerPass({}))
123122
MODULE_PASS("module-inline", ModuleInlinerPass())
124123
MODULE_PASS("tsan-module", ModuleThreadSanitizerPass())
125124
MODULE_PASS("sancov-module", ModuleSanitizerCoveragePass())
@@ -154,6 +153,13 @@ MODULE_PASS_WITH_PARAMS("asan-module",
154153
},
155154
parseASanPassOptions,
156155
"kernel")
156+
MODULE_PASS_WITH_PARAMS("msan",
157+
"ModuleMemorySanitizerPass",
158+
[](MemorySanitizerOptions Opts) {
159+
return ModuleMemorySanitizerPass(Opts);
160+
},
161+
parseMSanPassOptions,
162+
"recover;kernel;eager-checks;track-origins=N")
157163
#undef MODULE_PASS_WITH_PARAMS
158164

159165
#ifndef CGSCC_ANALYSIS
@@ -420,13 +426,6 @@ FUNCTION_PASS_WITH_PARAMS("loop-unroll",
420426
"no-profile-peeling;profile-peeling;"
421427
"no-runtime;runtime;"
422428
"no-upperbound;upperbound")
423-
FUNCTION_PASS_WITH_PARAMS("msan",
424-
"MemorySanitizerPass",
425-
[](MemorySanitizerOptions Opts) {
426-
return MemorySanitizerPass(Opts);
427-
},
428-
parseMSanPassOptions,
429-
"recover;kernel;eager-checks;track-origins=N")
430429
FUNCTION_PASS_WITH_PARAMS("simplifycfg",
431430
"SimplifyCFGPass",
432431
[](SimplifyCFGOptions Opts) {

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -669,25 +669,28 @@ MemorySanitizerOptions::MemorySanitizerOptions(int TO, bool R, bool K,
669669
Recover(getOptOrDefault(ClKeepGoing, Kernel || R)),
670670
EagerChecks(getOptOrDefault(ClEagerChecks, EagerChecks)) {}
671671

672-
PreservedAnalyses MemorySanitizerPass::run(Function &F,
673-
FunctionAnalysisManager &FAM) {
674-
MemorySanitizer Msan(*F.getParent(), Options);
675-
if (Msan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F)))
676-
return PreservedAnalyses::none();
677-
return PreservedAnalyses::all();
678-
}
679-
680672
PreservedAnalyses ModuleMemorySanitizerPass::run(Module &M,
681673
ModuleAnalysisManager &AM) {
682-
if (Options.Kernel)
683-
return PreservedAnalyses::all();
684-
insertModuleCtor(M);
685-
return PreservedAnalyses::none();
674+
bool Modified = false;
675+
if (!Options.Kernel) {
676+
insertModuleCtor(M);
677+
Modified = true;
678+
}
679+
680+
auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
681+
for (Function &F : M) {
682+
if (F.empty())
683+
continue;
684+
MemorySanitizer Msan(*F.getParent(), Options);
685+
Modified |=
686+
Msan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F));
687+
}
688+
return Modified ? PreservedAnalyses::none() : PreservedAnalyses::all();
686689
}
687690

688-
void MemorySanitizerPass::printPipeline(
691+
void ModuleMemorySanitizerPass::printPipeline(
689692
raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
690-
static_cast<PassInfoMixin<MemorySanitizerPass> *>(this)->printPipeline(
693+
static_cast<PassInfoMixin<ModuleMemorySanitizerPass> *>(this)->printPipeline(
691694
OS, MapClassName2PassName);
692695
OS << "<";
693696
if (Options.Recover)

llvm/test/Instrumentation/MemorySanitizer/attributes.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt < %s -S -passes='module(msan-module),function(msan)' 2>&1 | FileCheck %s
1+
; RUN: opt < %s -S -passes='module(msan)' 2>&1 | FileCheck %s
22

33
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
44
target triple = "x86_64-unknown-linux-gnu"

llvm/test/Instrumentation/MemorySanitizer/check-array.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt < %s -msan-eager-checks -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan-module),function(msan)' 2>&1 | \
1+
; RUN: opt < %s -msan-eager-checks -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan)' 2>&1 | \
22
; RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK %s
33

44
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"

llvm/test/Instrumentation/MemorySanitizer/check-constant-shadow.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,5 @@ entry:
7575
; CHECK-LABEL: @MaybeUninitializedRetNoUndef
7676
; CONST: br i1 icmp ne (i32 extractelement (<4 x i32> bitcast (<2 x i64> <i64 0, i64 undef> to <4 x i32>), i64 0), i32 0)
7777
; CONST: call void @__msan_warning_with_origin_noreturn
78+
79+
; CHECK: call void @__msan_init()

llvm/test/Instrumentation/MemorySanitizer/check-struct.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan-module),function(msan)' 2>&1 | \
1+
; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan)' 2>&1 | \
22
; RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK %s
33

44
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"

llvm/test/Instrumentation/MemorySanitizer/msan-disable-checks.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
; Test for -msan-disable-checks, which should treat every function in the file
22
; as if it didn't have the sanitize_memory attribute.
3-
; RUN: opt < %s -msan-check-access-address=0 -S -passes='module(msan-module),function(msan)' 2>&1 | FileCheck -allow-deprecated-dag-overlap -check-prefixes=CHECK,INSTR %s
4-
; RUN: opt < %s -msan-check-access-address=0 -S -passes='module(msan-module),function(msan)' -msan-disable-checks=1 2>&1 | FileCheck -allow-deprecated-dag-overlap -check-prefixes=CHECK,NOSANITIZE %s
3+
; RUN: opt < %s -msan-check-access-address=0 -S -passes='module(msan)' 2>&1 | FileCheck -allow-deprecated-dag-overlap -check-prefixes=CHECK,INSTR %s
4+
; RUN: opt < %s -msan-check-access-address=0 -S -passes='module(msan)' -msan-disable-checks=1 2>&1 | FileCheck -allow-deprecated-dag-overlap -check-prefixes=CHECK,NOSANITIZE %s
55

66
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
77
target triple = "x86_64-unknown-linux-gnu"

llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
; RUN: opt < %s -msan-check-access-address=0 -S -passes='module(msan-module),function(msan)' 2>&1 | FileCheck -allow-deprecated-dag-overlap %s --check-prefixes=CHECK,NOORIGINS --implicit-check-not="call void @__msan_warning"
2-
; RUN: opt < %s --passes='module(msan-module),function(msan)' -msan-check-access-address=0 -S | FileCheck -allow-deprecated-dag-overlap %s --check-prefixes=CHECK,NOORIGINS --implicit-check-not="call void @__msan_warning"
3-
; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan-module),function(msan)' 2>&1 | FileCheck -allow-deprecated-dag-overlap -check-prefixes=CHECK,ORIGINS %s --implicit-check-not="call void @__msan_warning"
4-
; RUN: opt < %s -passes='module(msan-module),function(msan)' -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck -allow-deprecated-dag-overlap -check-prefixes=CHECK,ORIGINS %s --implicit-check-not="call void @__msan_warning"
5-
; RUN: opt < %s -passes='module(msan-module),function(msan)' -msan-instrumentation-with-call-threshold=0 -msan-track-origins=1 -S | FileCheck -allow-deprecated-dag-overlap -check-prefixes=CHECK-CALLS %s --implicit-check-not="call void @__msan_warning"
1+
; RUN: opt < %s -msan-check-access-address=0 -S -passes='module(msan)' 2>&1 | FileCheck -allow-deprecated-dag-overlap %s --check-prefixes=CHECK,NOORIGINS --implicit-check-not="call void @__msan_warning"
2+
; RUN: opt < %s --passes='module(msan)' -msan-check-access-address=0 -S | FileCheck -allow-deprecated-dag-overlap %s --check-prefixes=CHECK,NOORIGINS --implicit-check-not="call void @__msan_warning"
3+
; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan)' 2>&1 | FileCheck -allow-deprecated-dag-overlap -check-prefixes=CHECK,ORIGINS %s --implicit-check-not="call void @__msan_warning"
4+
; RUN: opt < %s -passes='module(msan)' -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck -allow-deprecated-dag-overlap -check-prefixes=CHECK,ORIGINS %s --implicit-check-not="call void @__msan_warning"
5+
; RUN: opt < %s -passes='module(msan)' -msan-instrumentation-with-call-threshold=0 -msan-track-origins=1 -S | FileCheck -allow-deprecated-dag-overlap -check-prefixes=CHECK-CALLS %s --implicit-check-not="call void @__msan_warning"
66

77
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
88
target triple = "x86_64-unknown-linux-gnu"

llvm/test/Instrumentation/MemorySanitizer/msan_debug_info.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt < %s -passes='module(msan-module),function(msan)' -msan-instrumentation-with-call-threshold=0 -msan-track-origins=1 -S | FileCheck %s
2+
; RUN: opt < %s -passes='module(msan)' -msan-instrumentation-with-call-threshold=0 -msan-track-origins=1 -S | FileCheck %s
33

44
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
55
target triple = "x86_64-unknown-linux-gnu"

llvm/test/Instrumentation/MemorySanitizer/msan_eager.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -msan-eager-checks -S -passes='module(msan-module),function(msan)' 2>&1 | \
2+
; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -msan-eager-checks -S -passes='module(msan)' 2>&1 | \
33
; RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK %s
44
; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S -passes='msan<eager-checks>' 2>&1 | \
55
; RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK %s

llvm/test/Instrumentation/MemorySanitizer/msan_llvm_launder_invariant.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
; Make sure MSan handles llvm.launder.invariant.group correctly.
22

3-
; RUN: opt < %s -passes='function(msan),default<O1>' -msan-kernel=1 -S | FileCheck -check-prefixes=CHECK %s
4-
; RUN: opt < %s -passes='function(msan),default<O1>' -S | FileCheck -check-prefixes=CHECK %s
3+
; RUN: opt < %s -passes='module(msan),default<O1>' -msan-kernel=1 -S | FileCheck -check-prefixes=CHECK %s
4+
; RUN: opt < %s -passes='module(msan),default<O1>' -S | FileCheck -check-prefixes=CHECK %s
55

66
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
77
target triple = "x86_64-unknown-linux-gnu"

llvm/test/Instrumentation/MemorySanitizer/msan_llvm_strip_invariant.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
; Make sure MSan handles llvm.launder.invariant.group correctly.
22

3-
; RUN: opt < %s -passes='function(msan),default<O1>' -msan-kernel=1 -S | FileCheck -check-prefixes=CHECK %s
4-
; RUN: opt < %s -passes='function(msan),default<O1>' -S | FileCheck -check-prefixes=CHECK %s
3+
; RUN: opt < %s -passes='module(msan),default<O1>' -msan-kernel=1 -S | FileCheck -check-prefixes=CHECK %s
4+
; RUN: opt < %s -passes='module(msan),default<O1>' -S | FileCheck -check-prefixes=CHECK %s
55

66
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
77
target triple = "x86_64-unknown-linux-gnu"

llvm/test/Instrumentation/MemorySanitizer/reduce.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan-module),function(msan)' 2>&1 | \
2+
; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan)' 2>&1 | \
33
; RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK %s
44

55
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"

llvm/test/Other/new-pm-print-pipeline.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@
4040
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(early-cse<>,early-cse<memssa>)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-12
4141
; CHECK-12: function(early-cse<>,early-cse<memssa>)
4242

43-
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='msan-module,function(msan,msan<>,msan<recover;kernel;eager-checks;track-origins=5>)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-13
44-
; CHECK-13: msan-module,function(msan<track-origins=0>,msan<track-origins=0>,msan<recover;kernel;eager-checks;track-origins=5>)
43+
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='msan,module(msan,msan<>,msan<recover;kernel;eager-checks;track-origins=5>)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-13
44+
; CHECK-13: msan<track-origins=0>,msan<track-origins=0>,msan<track-origins=0>,msan<recover;kernel;eager-checks;track-origins=5>
4545

4646
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='module(hwasan<>,hwasan<kernel;recover>)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-14
4747
; CHECK-14: hwasan<>,hwasan<kernel;recover>

0 commit comments

Comments
 (0)