Index: llvm/trunk/lib/CodeGen/EarlyIfConversion.cpp =================================================================== --- llvm/trunk/lib/CodeGen/EarlyIfConversion.cpp +++ llvm/trunk/lib/CodeGen/EarlyIfConversion.cpp @@ -785,6 +785,9 @@ bool EarlyIfConverter::runOnMachineFunction(MachineFunction &MF) { DEBUG(dbgs() << "********** EARLY IF-CONVERSION **********\n" << "********** Function: " << MF.getName() << '\n'); + if (skipFunction(*MF.getFunction())) + return false; + // Only run if conversion if the target wants it. const TargetSubtargetInfo &STI = MF.getSubtarget(); if (!STI.enableEarlyIfConversion()) Index: llvm/trunk/lib/CodeGen/ExecutionDepsFix.cpp =================================================================== --- llvm/trunk/lib/CodeGen/ExecutionDepsFix.cpp +++ llvm/trunk/lib/CodeGen/ExecutionDepsFix.cpp @@ -726,6 +726,8 @@ } bool ExeDepsFix::runOnMachineFunction(MachineFunction &mf) { + if (skipFunction(*mf.getFunction())) + return false; MF = &mf; TII = MF->getSubtarget().getInstrInfo(); TRI = MF->getSubtarget().getRegisterInfo(); Index: llvm/trunk/lib/CodeGen/IfConversion.cpp =================================================================== --- llvm/trunk/lib/CodeGen/IfConversion.cpp +++ llvm/trunk/lib/CodeGen/IfConversion.cpp @@ -282,7 +282,8 @@ INITIALIZE_PASS_END(IfConverter, "if-converter", "If Converter", false, false) bool IfConverter::runOnMachineFunction(MachineFunction &MF) { - if (PredicateFtor && !PredicateFtor(*MF.getFunction())) + if (skipFunction(*MF.getFunction()) || + (PredicateFtor && !PredicateFtor(*MF.getFunction()))) return false; const TargetSubtargetInfo &ST = MF.getSubtarget(); Index: llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp +++ llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp @@ -1442,6 +1442,9 @@ } bool MachineBlockPlacement::runOnMachineFunction(MachineFunction &F) { + if (skipFunction(*F.getFunction())) + return false; + // Check for single-block functions and skip them. if (std::next(F.begin()) == F.end()) return false; Index: llvm/trunk/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp +++ llvm/trunk/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp @@ -411,6 +411,9 @@ } bool AlignmentFromAssumptions::runOnFunction(Function &F) { + if (skipFunction(F)) + return false; + bool Changed = false; auto &AC = getAnalysis().getAssumptionCache(F); SE = &getAnalysis().getSE(); Index: llvm/trunk/lib/Transforms/Scalar/ConstantProp.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/ConstantProp.cpp +++ llvm/trunk/lib/Transforms/Scalar/ConstantProp.cpp @@ -61,6 +61,9 @@ } bool ConstantPropagation::runOnFunction(Function &F) { + if (skipFunction(F)) + return false; + // Initialize the worklist to all of the instructions ready to process... std::set WorkList; for (Instruction &I: instructions(&F)) Index: llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp +++ llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp @@ -1383,6 +1383,9 @@ } bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) { + if (skipLoop(L)) + return false; + if (L->getBlocks().size() >= LoopSizeCutoff) { DEBUG(dbgs() << "irce: giving up constraining loop, too large\n";); return false; Index: llvm/trunk/lib/Transforms/Scalar/LoopDataPrefetch.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopDataPrefetch.cpp +++ llvm/trunk/lib/Transforms/Scalar/LoopDataPrefetch.cpp @@ -147,6 +147,9 @@ } bool LoopDataPrefetch::runOnFunction(Function &F) { + if (skipFunction(F)) + return false; + LI = &getAnalysis().getLoopInfo(); SE = &getAnalysis().getSE(); DL = &F.getParent()->getDataLayout(); Index: llvm/trunk/lib/Transforms/Scalar/LoopDistribute.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopDistribute.cpp +++ llvm/trunk/lib/Transforms/Scalar/LoopDistribute.cpp @@ -871,6 +871,9 @@ } bool runOnFunction(Function &F) override { + if (skipFunction(F)) + return false; + auto *LI = &getAnalysis().getLoopInfo(); auto *LAA = &getAnalysis(); auto *DT = &getAnalysis().getDomTree(); Index: llvm/trunk/lib/Transforms/Scalar/LoopInterchange.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopInterchange.cpp +++ llvm/trunk/lib/Transforms/Scalar/LoopInterchange.cpp @@ -449,6 +449,9 @@ } bool runOnFunction(Function &F) override { + if (skipFunction(F)) + return false; + SE = &getAnalysis().getSE(); LI = &getAnalysis().getLoopInfo(); DA = &getAnalysis(); Index: llvm/trunk/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp +++ llvm/trunk/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp @@ -57,6 +57,9 @@ } bool PartiallyInlineLibCalls::runOnFunction(Function &F) { + if (skipFunction(F)) + return false; + bool Changed = false; Function::iterator CurrBB; TargetLibraryInfo *TLI = Index: llvm/trunk/lib/Transforms/Scalar/Reg2Mem.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/Reg2Mem.cpp +++ llvm/trunk/lib/Transforms/Scalar/Reg2Mem.cpp @@ -68,7 +68,7 @@ false, false) bool RegToMem::runOnFunction(Function &F) { - if (F.isDeclaration()) + if (F.isDeclaration() || skipFunction(F)) return false; // Insert all new allocas into entry block. Index: llvm/trunk/lib/Transforms/Scalar/Scalarizer.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/Scalarizer.cpp +++ llvm/trunk/lib/Transforms/Scalar/Scalarizer.cpp @@ -252,6 +252,8 @@ } bool Scalarizer::runOnFunction(Function &F) { + if (skipFunction(F)) + return false; assert(Gathered.empty() && Scattered.empty()); for (BasicBlock &BB : F) { for (BasicBlock::iterator II = BB.begin(), IE = BB.end(); II != IE;) { Index: llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp +++ llvm/trunk/lib/Transforms/Scalar/SimplifyCFGPass.cpp @@ -209,10 +209,7 @@ initializeCFGSimplifyPassPass(*PassRegistry::getPassRegistry()); } bool runOnFunction(Function &F) override { - if (PredicateFtor && !PredicateFtor(F)) - return false; - - if (skipFunction(F)) + if (skipFunction(F) || (PredicateFtor && !PredicateFtor(F))) return false; AssumptionCache *AC = Index: llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp +++ llvm/trunk/lib/Transforms/Utils/SimplifyInstructions.cpp @@ -48,6 +48,9 @@ /// runOnFunction - Remove instructions that simplify. bool runOnFunction(Function &F) override { + if (skipFunction(F)) + return false; + const DominatorTreeWrapperPass *DTWP = getAnalysisIfAvailable(); const DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr; Index: llvm/trunk/test/Other/opt-bisect-legacy-pass-manager.ll =================================================================== --- llvm/trunk/test/Other/opt-bisect-legacy-pass-manager.ll +++ llvm/trunk/test/Other/opt-bisect-legacy-pass-manager.ll @@ -26,6 +26,14 @@ ; CHECK-SKIP-ALL-NOT: BISECT: running pass ({{[0-9]+}}) +; Verify that no passes run at -O0 are skipped +; RUN: opt -opt-bisect-limit=0 < %s 2>&1 | FileCheck %s --check-prefix=OPTBISECT-O0 +; RUN: opt -opt-bisect-limit=0 < %s | llc -O0 -opt-bisect-limit=0 2>&1 | FileCheck %s --check-prefix=OPTBISECT-O0 +; OPTBISECT-O0-NOT: BISECT: NOT running + +; FIXME: There are still some AMDGPU passes being skipped that run at -O0. +; XFAIL: r600, amdgcn + ; Verify that we can use the opt-bisect-helper.py script (derived from ; utils/bisect) to locate the optimization that inlines the call to ; f2() in f3().