diff options
author | Thurston Dang <thurston@google.com> | 2025-01-30 09:37:16 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-30 09:37:16 -0800 |
commit | 9c0606a08b7e81df59afa3894830cb5c374f99ac (patch) | |
tree | 2bac01286cf88dcc3d38a3440fc385d1c9726266 /clang/lib/CodeGen | |
parent | 2f48ca3aec4aa81b81d8591773bf29b4c72c623f (diff) | |
download | llvm-9c0606a08b7e81df59afa3894830cb5c374f99ac.zip llvm-9c0606a08b7e81df59afa3894830cb5c374f99ac.tar.gz llvm-9c0606a08b7e81df59afa3894830cb5c374f99ac.tar.bz2 |
Reapply "[ubsan] Connect -fsanitize-skip-hot-cutoff to LowerAllowCheckPass<cutoffs>" (#125032) (#125037)
This reverts commit 928cad49beec0120686478f502899222e836b545 i.e.,
relands dccd27112722109d2e2f03e8da9ce8690f06e11b, with a fix to avoid
use-after-scope by changing the lambda to capture by value.
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/BackendUtil.cpp | 23 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 28 |
2 files changed, 32 insertions, 19 deletions
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 3e65eeb..97e9bbc 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -795,14 +795,23 @@ static void addSanitizers(const Triple &TargetTriple, PB.registerOptimizerLastEPCallback(SanitizersCallback); } - if (LowerAllowCheckPass::IsRequested()) { + // SanitizeSkipHotCutoffs: doubles with range [0, 1] + // Opts.cutoffs: unsigned ints with range [0, 1000000] + auto ScaledCutoffs = CodeGenOpts.SanitizeSkipHotCutoffs.getAllScaled(1000000); + + // TODO: remove IsRequested() + if (LowerAllowCheckPass::IsRequested() || ScaledCutoffs.has_value()) { // We want to call it after inline, which is about OptimizerEarlyEPCallback. - PB.registerOptimizerEarlyEPCallback([&](ModulePassManager &MPM, - OptimizationLevel Level, - ThinOrFullLTOPhase Phase) { - LowerAllowCheckPass::Options Opts; - MPM.addPass(createModuleToFunctionPassAdaptor(LowerAllowCheckPass(Opts))); - }); + PB.registerOptimizerEarlyEPCallback( + [ScaledCutoffs](ModulePassManager &MPM, OptimizationLevel Level, + ThinOrFullLTOPhase Phase) { + LowerAllowCheckPass::Options Opts; + // TODO: after removing IsRequested(), make this unconditional + if (ScaledCutoffs.has_value()) + Opts.cutoffs = ScaledCutoffs.value(); + MPM.addPass( + createModuleToFunctionPassAdaptor(LowerAllowCheckPass(Opts))); + }); } } diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 9676e61..bf8df27 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -3614,29 +3614,33 @@ void CodeGenFunction::EmitCheck( llvm::Value *RecoverableCond = nullptr; llvm::Value *TrapCond = nullptr; bool NoMerge = false; + // Expand checks into: + // (Check1 || !allow_ubsan_check) && (Check2 || !allow_ubsan_check) ... + // We need separate allow_ubsan_check intrinsics because they have separately + // specified cutoffs. + // This expression looks expensive but will be simplified after + // LowerAllowCheckPass. for (auto &[Check, Ord] : Checked) { + llvm::Value *GuardedCheck = Check; + if (ClSanitizeGuardChecks || + (CGM.getCodeGenOpts().SanitizeSkipHotCutoffs[Ord] > 0)) { + llvm::Value *Allow = Builder.CreateCall( + CGM.getIntrinsic(llvm::Intrinsic::allow_ubsan_check), + llvm::ConstantInt::get(CGM.Int8Ty, Ord)); + GuardedCheck = Builder.CreateOr(Check, Builder.CreateNot(Allow)); + } + // -fsanitize-trap= overrides -fsanitize-recover=. llvm::Value *&Cond = CGM.getCodeGenOpts().SanitizeTrap.has(Ord) ? TrapCond : CGM.getCodeGenOpts().SanitizeRecover.has(Ord) ? RecoverableCond : FatalCond; - Cond = Cond ? Builder.CreateAnd(Cond, Check) : Check; + Cond = Cond ? Builder.CreateAnd(Cond, GuardedCheck) : GuardedCheck; if (!CGM.getCodeGenOpts().SanitizeMergeHandlers.has(Ord)) NoMerge = true; } - if (ClSanitizeGuardChecks) { - llvm::Value *Allow = - Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::allow_ubsan_check), - llvm::ConstantInt::get(CGM.Int8Ty, CheckHandler)); - - for (llvm::Value **Cond : {&FatalCond, &RecoverableCond, &TrapCond}) { - if (*Cond) - *Cond = Builder.CreateOr(*Cond, Builder.CreateNot(Allow)); - } - } - if (TrapCond) EmitTrapCheck(TrapCond, CheckHandler, NoMerge); if (!FatalCond && !RecoverableCond) |