[clang] [llvm] [BoundsChecking] Add parameters to pass (PR #119923)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Vitaly Buka (vitalybuka) Changes This check is a part of UBSAN, but does not support verbose output like other UBSAN checks. This is a step to fix that. --- Full diff: https://github.com/llvm/llvm-project/pull/119923.diff 6 Files Affected: - (modified) clang/lib/CodeGen/BackendUtil.cpp (+2-1) - (modified) llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h (+17-1) - (modified) llvm/lib/Passes/PassBuilder.cpp (+27) - (modified) llvm/lib/Passes/PassRegistry.def (+6-1) - (modified) llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp (+23) - (added) llvm/test/Instrumentation/BoundsChecking/runtimes.ll (+95) ``diff diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 8cf44592a17475..ae0e8b132aa356 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1020,7 +1020,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline( if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) PB.registerScalarOptimizerLateEPCallback( [](FunctionPassManager &FPM, OptimizationLevel Level) { -FPM.addPass(BoundsCheckingPass()); +FPM.addPass( +BoundsCheckingPass(BoundsCheckingPass::ReportingMode::Trap)); }); if (LangOpts.Sanitize.has(SanitizerKind::Realtime)) { diff --git a/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h b/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h index b1b1ece3eff5a0..29959acc29101a 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h +++ b/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h @@ -16,9 +16,25 @@ class Function; /// A pass to instrument code and perform run-time bounds checking on loads, /// stores, and other memory intrinsics. -struct BoundsCheckingPass : PassInfoMixin { +class BoundsCheckingPass : public PassInfoMixin { +public: + enum class ReportingMode { +Trap, +MinRuntime, +MinRuntimeAbort, +FullRuntime, +FullRuntimeAbort, + }; + +private: + ReportingMode Mode = ReportingMode::Trap; + +public: + BoundsCheckingPass(ReportingMode Mode) {} PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); static bool isRequired() { return true; } + void printPipeline(raw_ostream &OS, + function_ref MapClassName2PassName); }; } // end namespace llvm diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 260a34f2e060d6..78df7eed10f31a 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -1286,6 +1286,33 @@ Expected parseRtSanPassOptions(StringRef Params) { return Result; } +Expected +parseBoundsCheckingOptions(StringRef Params) { + BoundsCheckingPass::ReportingMode Mode = + BoundsCheckingPass::ReportingMode::Trap; + while (!Params.empty()) { +StringRef ParamName; +std::tie(ParamName, Params) = Params.split(';'); +if (ParamName == "trap") { + Mode = BoundsCheckingPass::ReportingMode::Trap; +} else if (ParamName == "rt") { + Mode = BoundsCheckingPass::ReportingMode::FullRuntime; +} else if (ParamName == "rt-abort") { + Mode = BoundsCheckingPass::ReportingMode::FullRuntimeAbort; +} else if (ParamName == "min-rt") { + Mode = BoundsCheckingPass::ReportingMode::MinRuntime; +} else if (ParamName == "min-rt-abort") { + Mode = BoundsCheckingPass::ReportingMode::MinRuntimeAbort; +} else { + return make_error( + formatv("invalid BoundsChecking pass parameter '{0}' ", ParamName) + .str(), + inconvertibleErrorCode()); +} + } + return Mode; +} + } // namespace /// Tests whether a pass name starts with a valid prefix for a default pipeline diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 825f2f7f9a494a..c86ff0b5a042c2 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -339,7 +339,6 @@ FUNCTION_PASS("assume-builder", AssumeBuilderPass()) FUNCTION_PASS("assume-simplify", AssumeSimplifyPass()) FUNCTION_PASS("atomic-expand", AtomicExpandPass(TM)) FUNCTION_PASS("bdce", BDCEPass()) -FUNCTION_PASS("bounds-checking", BoundsCheckingPass()) FUNCTION_PASS("break-crit-edges", BreakCriticalEdgesPass()) FUNCTION_PASS("callbr-prepare", CallBrPreparePass()) FUNCTION_PASS("callsite-splitting", CallSiteSplittingPass()) @@ -624,6 +623,12 @@ FUNCTION_PASS_WITH_PARAMS( "rtsan", "RealtimeSanitizerPass", [](RealtimeSanitizerOptions Opts) { return RealtimeSanitizerPass(Opts); }, parseRtSanPassOptions, "") +FUNCTION_PASS_WITH_PARAMS( +"bounds-checking", "BoundsCheckingPass", +[](BoundsCheckingPass::ReportingMode Mode) { + return BoundsCheckingPass(Mode); +}, +parseBoundsCheckingOptions, "trap") #undef FUNCTION_PASS_WITH_PARAMS #ifndef LOOPNEST_PASS diff --git a/llvm/lib/Transforms/I
[clang] [llvm] [BoundsChecking] Add parameters to pass (PR #119923)
llvmbot wrote: @llvm/pr-subscribers-clang-codegen Author: Vitaly Buka (vitalybuka) Changes This check is a part of UBSAN, but does not support verbose output like other UBSAN checks. This is a step to fix that. --- Full diff: https://github.com/llvm/llvm-project/pull/119923.diff 6 Files Affected: - (modified) clang/lib/CodeGen/BackendUtil.cpp (+2-1) - (modified) llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h (+17-1) - (modified) llvm/lib/Passes/PassBuilder.cpp (+27) - (modified) llvm/lib/Passes/PassRegistry.def (+6-1) - (modified) llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp (+23) - (added) llvm/test/Instrumentation/BoundsChecking/runtimes.ll (+95) ``diff diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 8cf44592a17475..ae0e8b132aa356 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1020,7 +1020,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline( if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) PB.registerScalarOptimizerLateEPCallback( [](FunctionPassManager &FPM, OptimizationLevel Level) { -FPM.addPass(BoundsCheckingPass()); +FPM.addPass( +BoundsCheckingPass(BoundsCheckingPass::ReportingMode::Trap)); }); if (LangOpts.Sanitize.has(SanitizerKind::Realtime)) { diff --git a/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h b/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h index b1b1ece3eff5a0..29959acc29101a 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h +++ b/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h @@ -16,9 +16,25 @@ class Function; /// A pass to instrument code and perform run-time bounds checking on loads, /// stores, and other memory intrinsics. -struct BoundsCheckingPass : PassInfoMixin { +class BoundsCheckingPass : public PassInfoMixin { +public: + enum class ReportingMode { +Trap, +MinRuntime, +MinRuntimeAbort, +FullRuntime, +FullRuntimeAbort, + }; + +private: + ReportingMode Mode = ReportingMode::Trap; + +public: + BoundsCheckingPass(ReportingMode Mode) {} PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); static bool isRequired() { return true; } + void printPipeline(raw_ostream &OS, + function_ref MapClassName2PassName); }; } // end namespace llvm diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 260a34f2e060d6..78df7eed10f31a 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -1286,6 +1286,33 @@ Expected parseRtSanPassOptions(StringRef Params) { return Result; } +Expected +parseBoundsCheckingOptions(StringRef Params) { + BoundsCheckingPass::ReportingMode Mode = + BoundsCheckingPass::ReportingMode::Trap; + while (!Params.empty()) { +StringRef ParamName; +std::tie(ParamName, Params) = Params.split(';'); +if (ParamName == "trap") { + Mode = BoundsCheckingPass::ReportingMode::Trap; +} else if (ParamName == "rt") { + Mode = BoundsCheckingPass::ReportingMode::FullRuntime; +} else if (ParamName == "rt-abort") { + Mode = BoundsCheckingPass::ReportingMode::FullRuntimeAbort; +} else if (ParamName == "min-rt") { + Mode = BoundsCheckingPass::ReportingMode::MinRuntime; +} else if (ParamName == "min-rt-abort") { + Mode = BoundsCheckingPass::ReportingMode::MinRuntimeAbort; +} else { + return make_error( + formatv("invalid BoundsChecking pass parameter '{0}' ", ParamName) + .str(), + inconvertibleErrorCode()); +} + } + return Mode; +} + } // namespace /// Tests whether a pass name starts with a valid prefix for a default pipeline diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 825f2f7f9a494a..c86ff0b5a042c2 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -339,7 +339,6 @@ FUNCTION_PASS("assume-builder", AssumeBuilderPass()) FUNCTION_PASS("assume-simplify", AssumeSimplifyPass()) FUNCTION_PASS("atomic-expand", AtomicExpandPass(TM)) FUNCTION_PASS("bdce", BDCEPass()) -FUNCTION_PASS("bounds-checking", BoundsCheckingPass()) FUNCTION_PASS("break-crit-edges", BreakCriticalEdgesPass()) FUNCTION_PASS("callbr-prepare", CallBrPreparePass()) FUNCTION_PASS("callsite-splitting", CallSiteSplittingPass()) @@ -624,6 +623,12 @@ FUNCTION_PASS_WITH_PARAMS( "rtsan", "RealtimeSanitizerPass", [](RealtimeSanitizerOptions Opts) { return RealtimeSanitizerPass(Opts); }, parseRtSanPassOptions, "") +FUNCTION_PASS_WITH_PARAMS( +"bounds-checking", "BoundsCheckingPass", +[](BoundsCheckingPass::ReportingMode Mode) { + return BoundsCheckingPass(Mode); +}, +parseBoundsCheckingOptions, "trap") #undef FUNCTION_PASS_WITH_PARAMS #ifndef LOOPNEST_PASS diff --git a/llvm/lib/Tran
[clang] [llvm] [BoundsChecking] Add parameters to pass (PR #119923)
https://github.com/vitalybuka converted_to_draft https://github.com/llvm/llvm-project/pull/119923 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [BoundsChecking] Add parameters to pass (PR #119923)
https://github.com/vitalybuka created https://github.com/llvm/llvm-project/pull/119923 This check is a part of UBSAN, but does not support verbose output like other UBSAN checks. This is a step to fix that. >From 064dadb7544c00f810f08e11860f6c403a6f336a Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Fri, 13 Dec 2024 12:48:50 -0800 Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?= =?UTF-8?q?l=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.4 --- clang/lib/CodeGen/BackendUtil.cpp | 3 +- .../Instrumentation/BoundsChecking.h | 18 +++- llvm/lib/Passes/PassBuilder.cpp | 27 ++ llvm/lib/Passes/PassRegistry.def | 7 +- .../Instrumentation/BoundsChecking.cpp| 23 + .../BoundsChecking/runtimes.ll| 95 +++ 6 files changed, 170 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Instrumentation/BoundsChecking/runtimes.ll diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 8cf44592a17475..ae0e8b132aa356 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1020,7 +1020,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline( if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) PB.registerScalarOptimizerLateEPCallback( [](FunctionPassManager &FPM, OptimizationLevel Level) { -FPM.addPass(BoundsCheckingPass()); +FPM.addPass( +BoundsCheckingPass(BoundsCheckingPass::ReportingMode::Trap)); }); if (LangOpts.Sanitize.has(SanitizerKind::Realtime)) { diff --git a/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h b/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h index b1b1ece3eff5a0..29959acc29101a 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h +++ b/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h @@ -16,9 +16,25 @@ class Function; /// A pass to instrument code and perform run-time bounds checking on loads, /// stores, and other memory intrinsics. -struct BoundsCheckingPass : PassInfoMixin { +class BoundsCheckingPass : public PassInfoMixin { +public: + enum class ReportingMode { +Trap, +MinRuntime, +MinRuntimeAbort, +FullRuntime, +FullRuntimeAbort, + }; + +private: + ReportingMode Mode = ReportingMode::Trap; + +public: + BoundsCheckingPass(ReportingMode Mode) {} PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); static bool isRequired() { return true; } + void printPipeline(raw_ostream &OS, + function_ref MapClassName2PassName); }; } // end namespace llvm diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 260a34f2e060d6..78df7eed10f31a 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -1286,6 +1286,33 @@ Expected parseRtSanPassOptions(StringRef Params) { return Result; } +Expected +parseBoundsCheckingOptions(StringRef Params) { + BoundsCheckingPass::ReportingMode Mode = + BoundsCheckingPass::ReportingMode::Trap; + while (!Params.empty()) { +StringRef ParamName; +std::tie(ParamName, Params) = Params.split(';'); +if (ParamName == "trap") { + Mode = BoundsCheckingPass::ReportingMode::Trap; +} else if (ParamName == "rt") { + Mode = BoundsCheckingPass::ReportingMode::FullRuntime; +} else if (ParamName == "rt-abort") { + Mode = BoundsCheckingPass::ReportingMode::FullRuntimeAbort; +} else if (ParamName == "min-rt") { + Mode = BoundsCheckingPass::ReportingMode::MinRuntime; +} else if (ParamName == "min-rt-abort") { + Mode = BoundsCheckingPass::ReportingMode::MinRuntimeAbort; +} else { + return make_error( + formatv("invalid BoundsChecking pass parameter '{0}' ", ParamName) + .str(), + inconvertibleErrorCode()); +} + } + return Mode; +} + } // namespace /// Tests whether a pass name starts with a valid prefix for a default pipeline diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 825f2f7f9a494a..c86ff0b5a042c2 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -339,7 +339,6 @@ FUNCTION_PASS("assume-builder", AssumeBuilderPass()) FUNCTION_PASS("assume-simplify", AssumeSimplifyPass()) FUNCTION_PASS("atomic-expand", AtomicExpandPass(TM)) FUNCTION_PASS("bdce", BDCEPass()) -FUNCTION_PASS("bounds-checking", BoundsCheckingPass()) FUNCTION_PASS("break-crit-edges", BreakCriticalEdgesPass()) FUNCTION_PASS("callbr-prepare", CallBrPreparePass()) FUNCTION_PASS("callsite-splitting", CallSiteSplittingPass()) @@ -624,6 +623,12 @@ FUNCTION_PASS_WITH_PARAMS( "rtsan", "RealtimeSanitizerPass", [](RealtimeSanitizerOptions Opts) { return RealtimeSanitizerPass(Opts); }, p