diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -1836,10 +1836,24 @@ MPM.addPass(HotColdSplittingPass()); // Add late LTO optimization passes. + FunctionPassManager LateFPM; + + // LoopSink pass sinks instructions hoisted by LICM, which serves as a + // canonicalization pass that enables other optimizations. As a result, + // LoopSink pass needs to be a very late IR pass to avoid undoing LICM + // result too early. + LateFPM.addPass(LoopSinkPass()); + + // This hoists/decomposes div/rem ops. It should run after other sink/hoist + // passes to avoid re-sinking, but before SimplifyCFG because it can allow + // flattening of blocks. + LateFPM.addPass(DivRemPairsPass()); + // Delete basic blocks, which optimization passes may have killed. - MPM.addPass(createModuleToFunctionPassAdaptor(SimplifyCFGPass( + LateFPM.addPass(SimplifyCFGPass( SimplifyCFGOptions().convertSwitchRangeToICmp(true).hoistCommonInsts( - true)))); + true))); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(LateFPM))); // Drop bodies of available eternally objects to improve GlobalDCE. MPM.addPass(EliminateAvailableExternallyPass()); diff --git a/llvm/test/Other/new-pm-lto-defaults.ll b/llvm/test/Other/new-pm-lto-defaults.ll --- a/llvm/test/Other/new-pm-lto-defaults.ll +++ b/llvm/test/Other/new-pm-lto-defaults.ll @@ -135,6 +135,8 @@ ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass on foo ; CHECK-O23SZ-NEXT: Running pass: LowerTypeTestsPass ; CHECK-O-NEXT: Running pass: LowerTypeTestsPass +; CHECK-O23SZ-NEXT: Running pass: LoopSink +; CHECK-O23SZ-NEXT: Running pass: DivRemPairs ; CHECK-O23SZ-NEXT: Running pass: SimplifyCFGPass ; CHECK-O23SZ-NEXT: Running pass: EliminateAvailableExternallyPass ; CHECK-O23SZ-NEXT: Running pass: GlobalDCEPass