Author: Vitaly Buka Date: 2025-01-09T20:19:01-08:00 New Revision: 9c2de994a18b8eb50634e620af762ed28ec5dcc2
URL: https://github.com/llvm/llvm-project/commit/9c2de994a18b8eb50634e620af762ed28ec5dcc2 DIFF: https://github.com/llvm/llvm-project/commit/9c2de994a18b8eb50634e620af762ed28ec5dcc2.diff LOG: [nfc][BoundsChecking] Refactor BoundsCheckingOptions (#122346) Remove ReportingMode and ReportingOpts. Added: Modified: clang/lib/CodeGen/BackendUtil.cpp llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h llvm/lib/Passes/PassBuilder.cpp llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 2dbab785658aa4..f350accfc530bf 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1025,26 +1025,21 @@ void EmitAssemblyHelper::RunOptimizationPipeline( // Register callbacks to schedule sanitizer passes at the appropriate part // of the pipeline. if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) - PB.registerScalarOptimizerLateEPCallback( - [this](FunctionPassManager &FPM, OptimizationLevel Level) { - BoundsCheckingPass::ReportingMode Mode; - bool Merge = CodeGenOpts.SanitizeMergeHandlers.has( - SanitizerKind::LocalBounds); - - if (CodeGenOpts.SanitizeTrap.has(SanitizerKind::LocalBounds)) { - Mode = BoundsCheckingPass::ReportingMode::Trap; - } else if (CodeGenOpts.SanitizeMinimalRuntime) { - Mode = CodeGenOpts.SanitizeRecover.has(SanitizerKind::LocalBounds) - ? BoundsCheckingPass::ReportingMode::MinRuntime - : BoundsCheckingPass::ReportingMode::MinRuntimeAbort; - } else { - Mode = CodeGenOpts.SanitizeRecover.has(SanitizerKind::LocalBounds) - ? BoundsCheckingPass::ReportingMode::FullRuntime - : BoundsCheckingPass::ReportingMode::FullRuntimeAbort; - } - BoundsCheckingPass::BoundsCheckingOptions Options(Mode, Merge); - FPM.addPass(BoundsCheckingPass(Options)); - }); + PB.registerScalarOptimizerLateEPCallback([this](FunctionPassManager &FPM, + OptimizationLevel Level) { + BoundsCheckingPass::BoundsCheckingOptions Options; + Options.Merge = + CodeGenOpts.SanitizeMergeHandlers.has(SanitizerKind::LocalBounds); + if (!CodeGenOpts.SanitizeTrap.has(SanitizerKind::LocalBounds)) { + Options.Rt = { + /*MinRuntime=*/static_cast<bool>( + CodeGenOpts.SanitizeMinimalRuntime), + /*MayReturn=*/ + CodeGenOpts.SanitizeRecover.has(SanitizerKind::LocalBounds), + }; + } + FPM.addPass(BoundsCheckingPass(Options)); + }); // Don't add sanitizers if we are here from ThinLTO PostLink. That already // done on PreLink stage. diff --git a/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h b/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h index ee71aa64f85eed..9c0506428bd625 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h +++ b/llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h @@ -10,6 +10,7 @@ #define LLVM_TRANSFORMS_INSTRUMENTATION_BOUNDSCHECKING_H #include "llvm/IR/PassManager.h" +#include <optional> namespace llvm { class Function; @@ -19,19 +20,15 @@ class Function; class BoundsCheckingPass : public PassInfoMixin<BoundsCheckingPass> { public: - enum class ReportingMode { - Trap, - MinRuntime, - MinRuntimeAbort, - FullRuntime, - FullRuntimeAbort, - }; - struct BoundsCheckingOptions { - BoundsCheckingOptions(ReportingMode Mode, bool Merge); - - ReportingMode Mode; - bool Merge; + struct Runtime { + Runtime(bool MinRuntime, bool MayReturn) + : MinRuntime(MinRuntime), MayReturn(MayReturn) {} + bool MinRuntime; + bool MayReturn; + }; + std::optional<Runtime> Rt; // Trap if empty. + bool Merge = false; }; BoundsCheckingPass(BoundsCheckingOptions Options) : Options(Options) {} diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 30b8d7c9499488..b75387ac556e39 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -1286,21 +1286,32 @@ parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) { Expected<BoundsCheckingPass::BoundsCheckingOptions> parseBoundsCheckingOptions(StringRef Params) { - BoundsCheckingPass::BoundsCheckingOptions Options( - BoundsCheckingPass::ReportingMode::Trap, false); + BoundsCheckingPass::BoundsCheckingOptions Options; while (!Params.empty()) { StringRef ParamName; std::tie(ParamName, Params) = Params.split(';'); if (ParamName == "trap") { - Options.Mode = BoundsCheckingPass::ReportingMode::Trap; + Options.Rt = std::nullopt; } else if (ParamName == "rt") { - Options.Mode = BoundsCheckingPass::ReportingMode::FullRuntime; + Options.Rt = { + /*MinRuntime=*/false, + /*MayReturn=*/true, + }; } else if (ParamName == "rt-abort") { - Options.Mode = BoundsCheckingPass::ReportingMode::FullRuntimeAbort; + Options.Rt = { + /*MinRuntime=*/false, + /*MayReturn=*/false, + }; } else if (ParamName == "min-rt") { - Options.Mode = BoundsCheckingPass::ReportingMode::MinRuntime; + Options.Rt = { + /*MinRuntime=*/true, + /*MayReturn=*/true, + }; } else if (ParamName == "min-rt-abort") { - Options.Mode = BoundsCheckingPass::ReportingMode::MinRuntimeAbort; + Options.Rt = { + /*MinRuntime=*/true, + /*MayReturn=*/false, + }; } else if (ParamName == "merge") { Options.Merge = true; } else { diff --git a/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp b/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp index 41e50385812460..3d2a2663230c06 100644 --- a/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp +++ b/llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp @@ -43,10 +43,6 @@ STATISTIC(ChecksUnable, "Bounds checks unable to add"); using BuilderTy = IRBuilder<TargetFolder>; -BoundsCheckingPass::BoundsCheckingOptions::BoundsCheckingOptions( - ReportingMode Mode, bool Merge) - : Mode(Mode), Merge(Merge) {} - /// Gets the conditions under which memory accessing instructions will overflow. /// /// \p Ptr is the pointer that will be read/written, and \p InstVal is either @@ -166,42 +162,19 @@ static void insertBoundsCheck(Value *Or, BuilderTy &IRB, GetTrapBBT GetTrapBB) { BranchInst::Create(TrapBB, Cont, Or, OldBB); } -struct ReportingOpts { - bool MayReturn = false; - bool UseTrap = false; - bool MinRuntime = false; - bool MayMerge = true; - StringRef Name; - - ReportingOpts(BoundsCheckingPass::ReportingMode Mode, bool Merge) { - switch (Mode) { - case BoundsCheckingPass::ReportingMode::Trap: - UseTrap = true; - break; - case BoundsCheckingPass::ReportingMode::MinRuntime: - Name = "__ubsan_handle_local_out_of_bounds_minimal"; - MinRuntime = true; - MayReturn = true; - break; - case BoundsCheckingPass::ReportingMode::MinRuntimeAbort: - Name = "__ubsan_handle_local_out_of_bounds_minimal_abort"; - MinRuntime = true; - break; - case BoundsCheckingPass::ReportingMode::FullRuntime: - Name = "__ubsan_handle_local_out_of_bounds"; - MayReturn = true; - break; - case BoundsCheckingPass::ReportingMode::FullRuntimeAbort: - Name = "__ubsan_handle_local_out_of_bounds_abort"; - break; - } - - MayMerge = Merge; - } -}; +static std::string getRuntimeCallName( + const BoundsCheckingPass::BoundsCheckingOptions::Runtime &Opts) { + std::string Name = "__ubsan_handle_local_out_of_bounds"; + if (Opts.MinRuntime) + Name += "_minimal"; + if (!Opts.MayReturn) + Name += "_abort"; + return Name; +} -static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI, - ScalarEvolution &SE, const ReportingOpts &Opts) { +static bool +addBoundsChecking(Function &F, TargetLibraryInfo &TLI, ScalarEvolution &SE, + const BoundsCheckingPass::BoundsCheckingOptions &Opts) { if (F.hasFnAttribute(Attribute::NoSanitizeBounds)) return false; @@ -239,11 +212,16 @@ static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI, TrapInfo.push_back(std::make_pair(&I, Or)); } + std::string Name; + if (Opts.Rt) + Name = getRuntimeCallName(*Opts.Rt); + // Create a trapping basic block on demand using a callback. Depending on // flags, this will either create a single block for the entire function or // will create a fresh block every time it is called. BasicBlock *ReuseTrapBB = nullptr; - auto GetTrapBB = [&ReuseTrapBB, &Opts](BuilderTy &IRB, BasicBlock *Cont) { + auto GetTrapBB = [&ReuseTrapBB, &Opts, &Name](BuilderTy &IRB, + BasicBlock *Cont) { Function *Fn = IRB.GetInsertBlock()->getParent(); auto DebugLoc = IRB.getCurrentDebugLocation(); IRBuilder<>::InsertPointGuard Guard(IRB); @@ -257,23 +235,24 @@ static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI, BasicBlock *TrapBB = BasicBlock::Create(Fn->getContext(), "trap", Fn); IRB.SetInsertPoint(TrapBB); - bool DebugTrapBB = !Opts.MayMerge; - CallInst *TrapCall = Opts.UseTrap - ? InsertTrap(IRB, DebugTrapBB) - : InsertCall(IRB, Opts.MayReturn, Opts.Name); + bool DebugTrapBB = !Opts.Merge; + CallInst *TrapCall = Opts.Rt ? InsertCall(IRB, Opts.Rt->MayReturn, Name) + : InsertTrap(IRB, DebugTrapBB); if (DebugTrapBB) TrapCall->addFnAttr(llvm::Attribute::NoMerge); TrapCall->setDoesNotThrow(); TrapCall->setDebugLoc(DebugLoc); - if (Opts.MayReturn) { + + bool MayReturn = Opts.Rt && Opts.Rt->MayReturn; + if (MayReturn) { IRB.CreateBr(Cont); } else { TrapCall->setDoesNotReturn(); IRB.CreateUnreachable(); } - if (!Opts.MayReturn && SingleTrapBB && !DebugTrapBB) + if (!MayReturn && SingleTrapBB && !DebugTrapBB) ReuseTrapBB = TrapBB; return TrapBB; @@ -292,8 +271,7 @@ PreservedAnalyses BoundsCheckingPass::run(Function &F, FunctionAnalysisManager & auto &TLI = AM.getResult<TargetLibraryAnalysis>(F); auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F); - if (!addBoundsChecking(F, TLI, SE, - ReportingOpts(Options.Mode, Options.Merge))) + if (!addBoundsChecking(F, TLI, SE, Options)) return PreservedAnalyses::all(); return PreservedAnalyses::none(); @@ -303,22 +281,15 @@ void BoundsCheckingPass::printPipeline( raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) { static_cast<PassInfoMixin<BoundsCheckingPass> *>(this)->printPipeline( OS, MapClassName2PassName); - switch (Options.Mode) { - case ReportingMode::Trap: - OS << "<trap"; - break; - case ReportingMode::MinRuntime: - OS << "<min-rt"; - break; - case ReportingMode::MinRuntimeAbort: - OS << "<min-rt-abort"; - break; - case ReportingMode::FullRuntime: - OS << "<rt"; - break; - case ReportingMode::FullRuntimeAbort: - OS << "<rt-abort"; - break; + OS << "<"; + if (Options.Rt) { + if (Options.Rt->MinRuntime) + OS << "min-"; + OS << "rt"; + if (!Options.Rt->MayReturn) + OS << "-abort"; + } else { + OS << "trap"; } if (Options.Merge) OS << ";merge"; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits