diff --git a/llvm/include/llvm/Transforms/Instrumentation/MemorySanitizer.h b/llvm/include/llvm/Transforms/Instrumentation/MemorySanitizer.h --- a/llvm/include/llvm/Transforms/Instrumentation/MemorySanitizer.h +++ b/llvm/include/llvm/Transforms/Instrumentation/MemorySanitizer.h @@ -19,11 +19,15 @@ namespace llvm { struct MemorySanitizerOptions { - MemorySanitizerOptions() : MemorySanitizerOptions(0, false, false){}; - MemorySanitizerOptions(int TrackOrigins, bool Recover, bool Kernel); + MemorySanitizerOptions() : MemorySanitizerOptions(0, false, false, false){}; + MemorySanitizerOptions(int TrackOrigins, bool Recover, bool Kernel) + : MemorySanitizerOptions(TrackOrigins, Recover, Kernel, false) {} + MemorySanitizerOptions(int TrackOrigins, bool Recover, bool Kernel, + bool EagerChecksRequested); bool Kernel; int TrackOrigins; bool Recover; + bool EagerChecksRequested; }; // Insert MemorySanitizer instrumentation (detection of uninitialized reads) diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -656,6 +656,8 @@ ParamName) .str(), inconvertibleErrorCode()); + } else if (ParamName == "param-retval") { + Result.EagerChecksRequested = true; } else { return make_error( formatv("invalid MemorySanitizer pass parameter '{0}' ", ParamName) diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -412,7 +412,7 @@ return MemorySanitizerPass(Opts); }, parseMSanPassOptions, - "recover;kernel;track-origins=N") + "recover;kernel;track-origins=N,param-retval") FUNCTION_PASS_WITH_PARAMS("simplifycfg", "SimplifyCFGPass", [](SimplifyCFGOptions Opts) { diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -493,6 +493,9 @@ MemorySanitizer(Module &M, MemorySanitizerOptions Options) : CompileKernel(Options.Kernel), TrackOrigins(Options.TrackOrigins), Recover(Options.Recover) { + if (Options.EagerChecksRequested) { + ClEagerChecks = true; + } initializeModule(M); } @@ -665,10 +668,13 @@ } // end anonymous namespace -MemorySanitizerOptions::MemorySanitizerOptions(int TO, bool R, bool K) +MemorySanitizerOptions::MemorySanitizerOptions(int TO, bool R, bool K, + bool EagerChecksRequested) : Kernel(getOptOrDefault(ClEnableKmsan, K)), TrackOrigins(getOptOrDefault(ClTrackOrigins, Kernel ? 2 : TO)), - Recover(getOptOrDefault(ClKeepGoing, Kernel || R)) {} + Recover(getOptOrDefault(ClKeepGoing, Kernel || R)), + EagerChecksRequested( + getOptOrDefault(ClEagerChecks, EagerChecksRequested)) {} PreservedAnalyses MemorySanitizerPass::run(Function &F, FunctionAnalysisManager &FAM) { @@ -695,7 +701,9 @@ OS << "recover;"; if (Options.Kernel) OS << "kernel;"; - OS << "track-origins=" << Options.TrackOrigins; + OS << "track-origins=" << Options.TrackOrigins << ";"; + if (Options.EagerChecksRequested) + OS << "param-retval;"; OS << ">"; } diff --git a/llvm/test/Instrumentation/MemorySanitizer/msan_eager.ll b/llvm/test/Instrumentation/MemorySanitizer/msan_eager.ll --- a/llvm/test/Instrumentation/MemorySanitizer/msan_eager.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/msan_eager.ll @@ -1,6 +1,8 @@ ; 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: 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 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"