Index: lib/CodeGen/EarlyIfConversion.cpp =================================================================== --- lib/CodeGen/EarlyIfConversion.cpp +++ 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: lib/CodeGen/ExecutionDepsFix.cpp =================================================================== --- lib/CodeGen/ExecutionDepsFix.cpp +++ lib/CodeGen/ExecutionDepsFix.cpp @@ -724,6 +724,8 @@ } bool ExeDepsFix::runOnMachineFunction(MachineFunction &mf) { + if (skipFunction(*mf.getFunction())) + return false; MF = &mf; TII = MF->getSubtarget().getInstrInfo(); TRI = MF->getSubtarget().getRegisterInfo(); Index: lib/CodeGen/IfConversion.cpp =================================================================== --- lib/CodeGen/IfConversion.cpp +++ 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: lib/CodeGen/MachineBlockPlacement.cpp =================================================================== --- lib/CodeGen/MachineBlockPlacement.cpp +++ lib/CodeGen/MachineBlockPlacement.cpp @@ -1430,6 +1430,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: lib/Transforms/Scalar/AlignmentFromAssumptions.cpp =================================================================== --- lib/Transforms/Scalar/AlignmentFromAssumptions.cpp +++ 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: lib/Transforms/Scalar/ConstantProp.cpp =================================================================== --- lib/Transforms/Scalar/ConstantProp.cpp +++ 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: lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp =================================================================== --- lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp +++ 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: lib/Transforms/Scalar/LoopDataPrefetch.cpp =================================================================== --- lib/Transforms/Scalar/LoopDataPrefetch.cpp +++ 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: lib/Transforms/Scalar/LoopDistribute.cpp =================================================================== --- lib/Transforms/Scalar/LoopDistribute.cpp +++ 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: lib/Transforms/Scalar/LoopInterchange.cpp =================================================================== --- lib/Transforms/Scalar/LoopInterchange.cpp +++ 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: lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp =================================================================== --- lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp +++ 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: lib/Transforms/Scalar/Reg2Mem.cpp =================================================================== --- lib/Transforms/Scalar/Reg2Mem.cpp +++ 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: lib/Transforms/Scalar/Scalarizer.cpp =================================================================== --- lib/Transforms/Scalar/Scalarizer.cpp +++ 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: lib/Transforms/Scalar/SimplifyCFGPass.cpp =================================================================== --- lib/Transforms/Scalar/SimplifyCFGPass.cpp +++ lib/Transforms/Scalar/SimplifyCFGPass.cpp @@ -209,7 +209,7 @@ initializeCFGSimplifyPassPass(*PassRegistry::getPassRegistry()); } bool runOnFunction(Function &F) override { - if (PredicateFtor && !PredicateFtor(F)) + if (skipFunction(F) || (PredicateFtor && !PredicateFtor(F))) return false; if (skipFunction(F)) Index: lib/Transforms/Utils/SimplifyInstructions.cpp =================================================================== --- lib/Transforms/Utils/SimplifyInstructions.cpp +++ 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: test/Other/opt-bisect-legacy-pass-manager.ll =================================================================== --- test/Other/opt-bisect-legacy-pass-manager.ll +++ 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(). @@ -56,8 +64,6 @@ ; RUN: opt -disable-output -disable-verify -inline -opt-bisect-limit=-1 %s \ ; RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-INLINE -; CHECK-INLINE: BISECT: running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (<>) -; CHECK-INLINE: BISECT: running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (g) ; CHECK-INLINE: BISECT: running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (f1) ; CHECK-INLINE: BISECT: running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (f2) ; CHECK-INLINE: BISECT: running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (f3) @@ -65,8 +71,6 @@ ; RUN: opt -disable-output -disable-verify -inline -opt-bisect-limit=0 %s \ ; RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-NOT-INLINE -; CHECK-NOT-INLINE: BISECT: NOT running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (<>) -; CHECK-NOT-INLINE: BISECT: NOT running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (g) ; CHECK-NOT-INLINE: BISECT: NOT running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (f1) ; CHECK-NOT-INLINE: BISECT: NOT running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (f2) ; CHECK-NOT-INLINE: BISECT: NOT running pass ({{[0-9]+}}) Function Integration/Inlining on SCC (f3) @@ -107,8 +111,6 @@ ; CHECK-NOT-LOOP-REDUCE: BISECT: NOT running pass ({{[0-9]+}}) Loop Strength Reduction on loop -declare i32 @g() - define void @f1() { entry: br label %loop.0 @@ -137,8 +139,7 @@ define i32 @f3() { entry: - %temp = call i32 @g() - %icmp = icmp ugt i32 %temp, 2 + %icmp = icmp ugt i32 undef, 2 br i1 %icmp, label %bb.true, label %bb.false bb.true: %temp2 = call i32 @f2()