Index: clang/lib/CodeGen/CGExpr.cpp =================================================================== --- clang/lib/CodeGen/CGExpr.cpp +++ clang/lib/CodeGen/CGExpr.cpp @@ -47,6 +47,11 @@ using namespace clang; using namespace CodeGen; +// Experiment to make sanitizers easier to debug +static llvm::cl::opt ClSanitizeDebugDeoptimization( + "sanitizer-de-opt-traps", llvm::cl::Optional, + llvm::cl::desc("Deoptimize traps for sanitizers"), llvm::cl::init(false)); + //===--------------------------------------------------------------------===// // Miscellaneous Helper Methods //===--------------------------------------------------------------------===// @@ -3576,7 +3581,8 @@ TrapBBs.resize(CheckHandlerID + 1); llvm::BasicBlock *&TrapBB = TrapBBs[CheckHandlerID]; - if (!CGM.getCodeGenOpts().OptimizationLevel || !TrapBB) { + if (ClSanitizeDebugDeoptimization || + !CGM.getCodeGenOpts().OptimizationLevel || !TrapBB) { TrapBB = createBasicBlock("trap"); Builder.CreateCondBr(Checked, Cont, TrapBB); EmitBlock(TrapBB); @@ -3590,6 +3596,8 @@ CGM.getCodeGenOpts().TrapFuncName); TrapCall->addFnAttr(A); } + if (ClSanitizeDebugDeoptimization) + TrapCall->addFnAttr(llvm::Attribute::NoMerge); TrapCall->setDoesNotReturn(); TrapCall->setDoesNotThrow(); Builder.CreateUnreachable(); Index: llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp +++ llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp @@ -39,6 +39,11 @@ static cl::opt SingleTrapBB("bounds-checking-single-trap", cl::desc("Use one trap block per function")); +// Experiment to make sanitizers easier to debug +static llvm::cl::opt ClBoundsSanitizeDebugDeoptimization( + "bounds-de-opt-traps", llvm::cl::Optional, + llvm::cl::desc("Deoptimize traps for sanitizers"), llvm::cl::init(false)); + STATISTIC(ChecksAdded, "Bounds checks added"); STATISTIC(ChecksSkipped, "Bounds checks skipped"); STATISTIC(ChecksUnable, "Bounds checks unable to add"); @@ -181,7 +186,7 @@ // will create a fresh block every time it is called. BasicBlock *TrapBB = nullptr; auto GetTrapBB = [&TrapBB](BuilderTy &IRB) { - if (TrapBB && SingleTrapBB) + if (!ClBoundsSanitizeDebugDeoptimization && TrapBB && SingleTrapBB) return TrapBB; Function *Fn = IRB.GetInsertBlock()->getParent(); @@ -194,6 +199,8 @@ auto *F = Intrinsic::getDeclaration(Fn->getParent(), Intrinsic::trap); CallInst *TrapCall = IRB.CreateCall(F, {}); + if (ClBoundsSanitizeDebugDeoptimization) + TrapCall->addFnAttr(llvm::Attribute::NoMerge); TrapCall->setDoesNotReturn(); TrapCall->setDoesNotThrow(); TrapCall->setDebugLoc(DebugLoc);