From e7bac3b9fa739f8d167a390a547068aad1d424a7 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Mon, 5 Sep 2022 21:28:02 -0700 Subject: [PATCH] [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 --- clang/lib/CodeGen/BackendUtil.cpp | 5 +--- .../Transforms/Instrumentation/MemorySanitizer.h | 20 ++------------ llvm/lib/Passes/PassRegistry.def | 15 +++++------ .../Transforms/Instrumentation/MemorySanitizer.cpp | 31 ++++++++++++---------- .../Instrumentation/MemorySanitizer/attributes.ll | 2 +- .../Instrumentation/MemorySanitizer/check-array.ll | 2 +- .../MemorySanitizer/check-constant-shadow.ll | 2 ++ .../MemorySanitizer/check-struct.ll | 2 +- .../MemorySanitizer/msan-disable-checks.ll | 4 +-- .../Instrumentation/MemorySanitizer/msan_basic.ll | 10 +++---- .../MemorySanitizer/msan_debug_info.ll | 2 +- .../Instrumentation/MemorySanitizer/msan_eager.ll | 2 +- .../MemorySanitizer/msan_llvm_launder_invariant.ll | 4 +-- .../MemorySanitizer/msan_llvm_strip_invariant.ll | 4 +-- .../test/Instrumentation/MemorySanitizer/reduce.ll | 2 +- llvm/test/Other/new-pm-print-pipeline.ll | 4 +-- 16 files changed, 48 insertions(+), 63 deletions(-) diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 7c4e356..4181ac1 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -640,21 +640,18 @@ static void addSanitizers(const Triple &TargetTriple, MemorySanitizerOptions options(TrackOrigins, Recover, CompileKernel, CodeGenOpts.SanitizeMemoryParamRetval); MPM.addPass(ModuleMemorySanitizerPass(options)); - FunctionPassManager FPM; - FPM.addPass(MemorySanitizerPass(options)); if (Level != OptimizationLevel::O0) { // MemorySanitizer inserts complex instrumentation that mostly // follows the logic of the original code, but operates on // "shadow" values. It can benefit from re-running some // general purpose optimization passes. - FPM.addPass(EarlyCSEPass()); + MPM.addPass(createModuleToFunctionPassAdaptor(EarlyCSEPass())); // TODO: Consider add more passes like in // addGeneralOptsForMemorySanitizer. EarlyCSEPass makes visible // difference on size. It's not clear if the rest is still // usefull. InstCombinePass breakes // compiler-rt/test/msan/select_origin.cpp. } - MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); } }; MSanPass(SanitizerKind::Memory, false); diff --git a/llvm/include/llvm/Transforms/Instrumentation/MemorySanitizer.h b/llvm/include/llvm/Transforms/Instrumentation/MemorySanitizer.h index ad92ed1..5883f81 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/MemorySanitizer.h +++ b/llvm/include/llvm/Transforms/Instrumentation/MemorySanitizer.h @@ -34,24 +34,6 @@ struct MemorySanitizerOptions { bool EagerChecks; }; -/// A function pass for msan instrumentation. -/// -/// Instruments functions to detect unitialized reads. This function pass -/// inserts calls to runtime library functions. If the functions aren't declared -/// yet, the pass inserts the declarations. Otherwise the existing globals are -/// used. -struct MemorySanitizerPass : public PassInfoMixin { - MemorySanitizerPass(MemorySanitizerOptions Options) : Options(Options) {} - - PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM); - void printPipeline(raw_ostream &OS, - function_ref MapClassName2PassName); - static bool isRequired() { return true; } - -private: - MemorySanitizerOptions Options; -}; - /// A module pass for msan instrumentation. /// /// Instruments functions to detect unitialized reads. This function pass @@ -62,6 +44,8 @@ struct ModuleMemorySanitizerPass : public PassInfoMixin MapClassName2PassName); static bool isRequired() { return true; } private: diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index a6aa06c..31cb7f8 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -119,7 +119,6 @@ MODULE_PASS("verify", VerifierPass()) MODULE_PASS("view-callgraph", CallGraphViewerPass()) MODULE_PASS("wholeprogramdevirt", WholeProgramDevirtPass()) MODULE_PASS("dfsan", DataFlowSanitizerPass()) -MODULE_PASS("msan-module", ModuleMemorySanitizerPass({})) MODULE_PASS("module-inline", ModuleInlinerPass()) MODULE_PASS("tsan-module", ModuleThreadSanitizerPass()) MODULE_PASS("sancov-module", ModuleSanitizerCoveragePass()) @@ -154,6 +153,13 @@ MODULE_PASS_WITH_PARAMS("asan-module", }, parseASanPassOptions, "kernel") +MODULE_PASS_WITH_PARAMS("msan", + "ModuleMemorySanitizerPass", + [](MemorySanitizerOptions Opts) { + return ModuleMemorySanitizerPass(Opts); + }, + parseMSanPassOptions, + "recover;kernel;eager-checks;track-origins=N") #undef MODULE_PASS_WITH_PARAMS #ifndef CGSCC_ANALYSIS @@ -420,13 +426,6 @@ FUNCTION_PASS_WITH_PARAMS("loop-unroll", "no-profile-peeling;profile-peeling;" "no-runtime;runtime;" "no-upperbound;upperbound") -FUNCTION_PASS_WITH_PARAMS("msan", - "MemorySanitizerPass", - [](MemorySanitizerOptions Opts) { - return MemorySanitizerPass(Opts); - }, - parseMSanPassOptions, - "recover;kernel;eager-checks;track-origins=N") FUNCTION_PASS_WITH_PARAMS("simplifycfg", "SimplifyCFGPass", [](SimplifyCFGOptions Opts) { diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 09d464d..f12524b 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -669,25 +669,28 @@ MemorySanitizerOptions::MemorySanitizerOptions(int TO, bool R, bool K, Recover(getOptOrDefault(ClKeepGoing, Kernel || R)), EagerChecks(getOptOrDefault(ClEagerChecks, EagerChecks)) {} -PreservedAnalyses MemorySanitizerPass::run(Function &F, - FunctionAnalysisManager &FAM) { - MemorySanitizer Msan(*F.getParent(), Options); - if (Msan.sanitizeFunction(F, FAM.getResult(F))) - return PreservedAnalyses::none(); - return PreservedAnalyses::all(); -} - PreservedAnalyses ModuleMemorySanitizerPass::run(Module &M, ModuleAnalysisManager &AM) { - if (Options.Kernel) - return PreservedAnalyses::all(); - insertModuleCtor(M); - return PreservedAnalyses::none(); + bool Modified = false; + if (!Options.Kernel) { + insertModuleCtor(M); + Modified = true; + } + + auto &FAM = AM.getResult(M).getManager(); + for (Function &F : M) { + if (F.empty()) + continue; + MemorySanitizer Msan(*F.getParent(), Options); + Modified |= + Msan.sanitizeFunction(F, FAM.getResult(F)); + } + return Modified ? PreservedAnalyses::none() : PreservedAnalyses::all(); } -void MemorySanitizerPass::printPipeline( +void ModuleMemorySanitizerPass::printPipeline( raw_ostream &OS, function_ref MapClassName2PassName) { - static_cast *>(this)->printPipeline( + static_cast *>(this)->printPipeline( OS, MapClassName2PassName); OS << "<"; if (Options.Recover) diff --git a/llvm/test/Instrumentation/MemorySanitizer/attributes.ll b/llvm/test/Instrumentation/MemorySanitizer/attributes.ll index d4741e81..43452f5 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/attributes.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/attributes.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -S -passes='module(msan-module),function(msan)' 2>&1 | FileCheck %s +; RUN: opt < %s -S -passes='module(msan)' 2>&1 | FileCheck %s 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" target triple = "x86_64-unknown-linux-gnu" diff --git a/llvm/test/Instrumentation/MemorySanitizer/check-array.ll b/llvm/test/Instrumentation/MemorySanitizer/check-array.ll index 283913f..0e30e65 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/check-array.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/check-array.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -msan-eager-checks -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan-module),function(msan)' 2>&1 | \ +; RUN: opt < %s -msan-eager-checks -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan)' 2>&1 | \ ; RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK %s 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" diff --git a/llvm/test/Instrumentation/MemorySanitizer/check-constant-shadow.ll b/llvm/test/Instrumentation/MemorySanitizer/check-constant-shadow.ll index d268fc4..cd8178c 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/check-constant-shadow.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/check-constant-shadow.ll @@ -75,3 +75,5 @@ entry: ; CHECK-LABEL: @MaybeUninitializedRetNoUndef ; CONST: br i1 icmp ne (i32 extractelement (<4 x i32> bitcast (<2 x i64> to <4 x i32>), i64 0), i32 0) ; CONST: call void @__msan_warning_with_origin_noreturn + +; CHECK: call void @__msan_init() diff --git a/llvm/test/Instrumentation/MemorySanitizer/check-struct.ll b/llvm/test/Instrumentation/MemorySanitizer/check-struct.ll index 1ecf3fc..bc9d699 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/check-struct.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/check-struct.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan-module),function(msan)' 2>&1 | \ +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan)' 2>&1 | \ ; RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK %s 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" diff --git a/llvm/test/Instrumentation/MemorySanitizer/msan-disable-checks.ll b/llvm/test/Instrumentation/MemorySanitizer/msan-disable-checks.ll index aceabf1..d2577c5 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/msan-disable-checks.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/msan-disable-checks.ll @@ -1,7 +1,7 @@ ; Test for -msan-disable-checks, which should treat every function in the file ; as if it didn't have the sanitize_memory attribute. -; 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 -; 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 +; RUN: opt < %s -msan-check-access-address=0 -S -passes='module(msan)' 2>&1 | FileCheck -allow-deprecated-dag-overlap -check-prefixes=CHECK,INSTR %s +; 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 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" target triple = "x86_64-unknown-linux-gnu" diff --git a/llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll b/llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll index 9a9ff61..06712b4 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll @@ -1,8 +1,8 @@ -; 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" -; 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" -; 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" -; 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" -; 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" +; 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" +; 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" +; 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" +; 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" +; 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" 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" target triple = "x86_64-unknown-linux-gnu" diff --git a/llvm/test/Instrumentation/MemorySanitizer/msan_debug_info.ll b/llvm/test/Instrumentation/MemorySanitizer/msan_debug_info.ll index fcda526..d190c875e 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/msan_debug_info.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/msan_debug_info.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -passes='module(msan-module),function(msan)' -msan-instrumentation-with-call-threshold=0 -msan-track-origins=1 -S | FileCheck %s +; RUN: opt < %s -passes='module(msan)' -msan-instrumentation-with-call-threshold=0 -msan-track-origins=1 -S | FileCheck %s 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" target triple = "x86_64-unknown-linux-gnu" diff --git a/llvm/test/Instrumentation/MemorySanitizer/msan_eager.ll b/llvm/test/Instrumentation/MemorySanitizer/msan_eager.ll index 505da98..10fe12b 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/msan_eager.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/msan_eager.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -msan-eager-checks -S -passes='module(msan-module),function(msan)' 2>&1 | \ +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -msan-eager-checks -S -passes='module(msan)' 2>&1 | \ ; RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK %s ; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S -passes='msan' 2>&1 | \ ; RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK %s diff --git a/llvm/test/Instrumentation/MemorySanitizer/msan_llvm_launder_invariant.ll b/llvm/test/Instrumentation/MemorySanitizer/msan_llvm_launder_invariant.ll index 6dd2c44..9f91b31 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/msan_llvm_launder_invariant.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/msan_llvm_launder_invariant.ll @@ -1,7 +1,7 @@ ; Make sure MSan handles llvm.launder.invariant.group correctly. -; RUN: opt < %s -passes='function(msan),default' -msan-kernel=1 -S | FileCheck -check-prefixes=CHECK %s -; RUN: opt < %s -passes='function(msan),default' -S | FileCheck -check-prefixes=CHECK %s +; RUN: opt < %s -passes='module(msan),default' -msan-kernel=1 -S | FileCheck -check-prefixes=CHECK %s +; RUN: opt < %s -passes='module(msan),default' -S | FileCheck -check-prefixes=CHECK %s target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/llvm/test/Instrumentation/MemorySanitizer/msan_llvm_strip_invariant.ll b/llvm/test/Instrumentation/MemorySanitizer/msan_llvm_strip_invariant.ll index 063ca6e..6ea00e4 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/msan_llvm_strip_invariant.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/msan_llvm_strip_invariant.ll @@ -1,7 +1,7 @@ ; Make sure MSan handles llvm.launder.invariant.group correctly. -; RUN: opt < %s -passes='function(msan),default' -msan-kernel=1 -S | FileCheck -check-prefixes=CHECK %s -; RUN: opt < %s -passes='function(msan),default' -S | FileCheck -check-prefixes=CHECK %s +; RUN: opt < %s -passes='module(msan),default' -msan-kernel=1 -S | FileCheck -check-prefixes=CHECK %s +; RUN: opt < %s -passes='module(msan),default' -S | FileCheck -check-prefixes=CHECK %s target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/llvm/test/Instrumentation/MemorySanitizer/reduce.ll b/llvm/test/Instrumentation/MemorySanitizer/reduce.ll index add81a5..8ddac6f 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/reduce.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/reduce.ll @@ -1,5 +1,5 @@ -; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan-module),function(msan)' 2>&1 | \ +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan)' 2>&1 | \ ; RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK %s 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" diff --git a/llvm/test/Other/new-pm-print-pipeline.ll b/llvm/test/Other/new-pm-print-pipeline.ll index 5841702..fc63cbd 100644 --- a/llvm/test/Other/new-pm-print-pipeline.ll +++ b/llvm/test/Other/new-pm-print-pipeline.ll @@ -40,8 +40,8 @@ ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(early-cse<>,early-cse)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-12 ; CHECK-12: function(early-cse<>,early-cse) -; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='msan-module,function(msan,msan<>,msan)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-13 -; CHECK-13: msan-module,function(msan,msan,msan) +; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='msan,module(msan,msan<>,msan)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-13 +; CHECK-13: msan,msan,msan,msan ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='module(hwasan<>,hwasan)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-14 ; CHECK-14: hwasan<>,hwasan -- 2.7.4