diff --git a/llvm/include/llvm/Transforms/Instrumentation/LowerAllowCheckPass.h b/llvm/include/llvm/Transforms/Instrumentation/LowerAllowCheckPass.h index 7b095ea24b4b..37bc72877983 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/LowerAllowCheckPass.h +++ b/llvm/include/llvm/Transforms/Instrumentation/LowerAllowCheckPass.h @@ -27,6 +27,7 @@ class LowerAllowCheckPass : public PassInfoMixin { public: struct Options { std::vector cutoffs; + unsigned int runtime_check = 0; }; explicit LowerAllowCheckPass(LowerAllowCheckPass::Options Opts) diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index f95c32d859d1..bb266ac77689 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -938,6 +938,19 @@ parseLowerAllowCheckPassOptions(StringRef Params) { Result.cutoffs[index] = cutoff; } + } else if (ParamName.starts_with("runtime_check")) { + StringRef ValueString; + std::tie(std::ignore, ValueString) = ParamName.split("="); + int runtime_check; + if (ValueString.getAsInteger(0, runtime_check)) { + return make_error( + formatv("invalid LowerAllowCheck pass runtime_check parameter '{}' " + "({})", + ValueString, Params) + .str(), + inconvertibleErrorCode()); + } + Result.runtime_check = runtime_check; } else { return make_error( formatv("invalid LowerAllowCheck pass parameter '{}'", ParamName) diff --git a/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp b/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp index 196f58a8f1d1..e7a6fa48e900 100644 --- a/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp +++ b/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp @@ -74,7 +74,7 @@ static void emitRemark(IntrinsicInst *II, OptimizationRemarkEmitter &ORE, static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI, const ProfileSummaryInfo *PSI, OptimizationRemarkEmitter &ORE, - const std::vector &cutoffs) { + const LowerAllowCheckPass::Options &Opts) { SmallVector, 16> ReplaceWithValue; std::unique_ptr Rng; @@ -89,8 +89,10 @@ static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI, return HotPercentileCutoff; else if (II->getIntrinsicID() == Intrinsic::allow_ubsan_check) { auto *Kind = cast(II->getArgOperand(0)); - if (Kind->getZExtValue() < cutoffs.size()) - return cutoffs[Kind->getZExtValue()]; + if (Kind->getZExtValue() < Opts.cutoffs.size()) + return Opts.cutoffs[Kind->getZExtValue()]; + } else if (II->getIntrinsicID() == Intrinsic::allow_runtime_check) { + return Opts.runtime_check; } return 0; @@ -157,7 +159,7 @@ PreservedAnalyses LowerAllowCheckPass::run(Function &F, OptimizationRemarkEmitter &ORE = AM.getResult(F); - return removeUbsanTraps(F, BFI, PSI, ORE, Opts.cutoffs) + return removeUbsanTraps(F, BFI, PSI, ORE, Opts) // We do not change the CFG, we only replace the intrinsics with // true or false. ? PreservedAnalyses::none().preserveSet() @@ -193,5 +195,11 @@ void LowerAllowCheckPass::printPipeline( i++; } + if (Opts.runtime_check) { + if (printed) + OS << ";"; + OS << "runtime_check=" << Opts.runtime_check; + } + OS << '>'; } diff --git a/llvm/test/Transforms/lower-builtin-allow-check-remarks.ll b/llvm/test/Transforms/lower-builtin-allow-check-remarks.ll index 190f4b240537..3030cc02f868 100644 --- a/llvm/test/Transforms/lower-builtin-allow-check-remarks.ll +++ b/llvm/test/Transforms/lower-builtin-allow-check-remarks.ll @@ -4,12 +4,21 @@ ; RUN: opt < %s -passes='require,function(lower-allow-check)' -lower-allow-check-percentile-cutoff-hot=0 -pass-remarks=lower-allow-check -pass-remarks-missed=lower-allow-check -S 2>&1 | FileCheck %s ; RUN: opt < %s -passes='require,function(lower-allow-check)' -lower-allow-check-percentile-cutoff-hot=1000000 -pass-remarks=lower-allow-check -pass-remarks-missed=lower-allow-check -S 2>&1 | FileCheck %s --check-prefixes=REMOVE +; RUN: opt < %s -passes='require,function(lower-allow-check)' -pass-remarks=lower-allow-check -pass-remarks-missed=lower-allow-check -S 2>&1 | FileCheck %s --check-prefixes=MIXED +; RUN: opt < %s -passes='require,function(lower-allow-check)' -pass-remarks=lower-allow-check -pass-remarks-missed=lower-allow-check -S 2>&1 | FileCheck %s --check-prefixes=MIXED2 + ; CHECK: remark: :0:0: Allowed check: Kind=test_check F=test_runtime BB=entry1 ; CHECK: remark: :0:0: Allowed check: Kind=7 F=test_ubsan BB=entry2 ; REMOVE: remark: :0:0: Removed check: Kind=test_check F=test_runtime BB=entry1 ; REMOVE: remark: :0:0: Removed check: Kind=7 F=test_ubsan BB=entry2 +; MIXED: remark: :0:0: Removed check: Kind=test_check F=test_runtime BB=entry1 +; MIXED: remark: :0:0: Allowed check: Kind=7 F=test_ubsan BB=entry2 + +; MIXED2: remark: :0:0: Allowed check: Kind=test_check F=test_runtime BB=entry1 +; MIXED2: remark: :0:0: Removed check: Kind=7 F=test_ubsan BB=entry2 + target triple = "x86_64-pc-linux-gnu" define i1 @test_runtime() local_unnamed_addr {