@@ -566,7 +566,7 @@ extern "C" LLVMRustResult LLVMRustOptimize(
566566 LLVMModuleRef ModuleRef, LLVMTargetMachineRef TMRef,
567567 LLVMRustPassBuilderOptLevel OptLevelRust, LLVMRustOptStage OptStage,
568568 bool IsLinkerPluginLTO, bool NoPrepopulatePasses, bool VerifyIR,
569- bool LintIR, LLVMRustThinLTOBuffer **ThinLTOBufferRef, bool EmitThinLTO,
569+ bool LintIR, LLVMRustThinLTOBuffer **ThinLTOBufferRef,
570570 bool EmitThinLTOSummary, bool MergeFunctions, bool UnrollLoops,
571571 bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls,
572572 bool EmitLifetimeMarkers, registerEnzymeAndPassPipelineFn EnzymePtr,
@@ -808,44 +808,35 @@ extern "C" LLVMRustResult LLVMRustOptimize(
808808 }
809809
810810 ModulePassManager MPM;
811- bool NeedThinLTOBufferPasses = EmitThinLTO ;
811+ bool NeedThinLTOBufferPasses = true ;
812812 auto ThinLTOBuffer = std::make_unique<LLVMRustThinLTOBuffer>();
813813 raw_string_ostream ThinLTODataOS (ThinLTOBuffer->data );
814814 raw_string_ostream ThinLinkDataOS (ThinLTOBuffer->thin_link_data );
815815 bool IsLTO = OptStage == LLVMRustOptStage::ThinLTO ||
816816 OptStage == LLVMRustOptStage::FatLTO;
817817 if (!NoPrepopulatePasses) {
818+ for (const auto &C : PipelineStartEPCallbacks)
819+ PB.registerPipelineStartEPCallback (C);
820+ for (const auto &C : OptimizerLastEPCallbacks)
821+ PB.registerOptimizerLastEPCallback (C);
822+
818823 // The pre-link pipelines don't support O0 and require using
819824 // buildO0DefaultPipeline() instead. At the same time, the LTO pipelines do
820825 // support O0 and using them is required.
821826 if (OptLevel == OptimizationLevel::O0 && !IsLTO) {
822- for (const auto &C : PipelineStartEPCallbacks)
823- PB.registerPipelineStartEPCallback (C);
824- for (const auto &C : OptimizerLastEPCallbacks)
825- PB.registerOptimizerLastEPCallback (C);
826-
827827 // We manually schedule ThinLTOBufferPasses below, so don't pass the value
828828 // to enable it here.
829829 MPM = PB.buildO0DefaultPipeline (OptLevel);
830830 } else {
831- for (const auto &C : PipelineStartEPCallbacks)
832- PB.registerPipelineStartEPCallback (C);
833- for (const auto &C : OptimizerLastEPCallbacks)
834- PB.registerOptimizerLastEPCallback (C);
835-
836831 switch (OptStage) {
837832 case LLVMRustOptStage::PreLinkNoLTO:
838833 if (ThinLTOBufferRef) {
839834 // This is similar to LLVM's `buildFatLTODefaultPipeline`, where the
840835 // bitcode for embedding is obtained after performing
841836 // `ThinLTOPreLinkDefaultPipeline`.
842837 MPM.addPass (PB.buildThinLTOPreLinkDefaultPipeline (OptLevel));
843- if (EmitThinLTO) {
844- MPM.addPass (ThinLTOBitcodeWriterPass (
845- ThinLTODataOS, EmitThinLTOSummary ? &ThinLinkDataOS : nullptr ));
846- } else {
847- MPM.addPass (BitcodeWriterPass (ThinLTODataOS));
848- }
838+ MPM.addPass (ThinLTOBitcodeWriterPass (
839+ ThinLTODataOS, EmitThinLTOSummary ? &ThinLinkDataOS : nullptr ));
849840 *ThinLTOBufferRef = ThinLTOBuffer.release ();
850841 MPM.addPass (PB.buildModuleOptimizationPipeline (
851842 OptLevel, ThinOrFullLTOPhase::None));
@@ -870,6 +861,7 @@ extern "C" LLVMRustResult LLVMRustOptimize(
870861 break ;
871862 case LLVMRustOptStage::FatLTO:
872863 MPM = PB.buildLTODefaultPipeline (OptLevel, nullptr );
864+ NeedThinLTOBufferPasses = false ;
873865 break ;
874866 }
875867 }
@@ -895,9 +887,11 @@ extern "C" LLVMRustResult LLVMRustOptimize(
895887 MPM.addPass (CanonicalizeAliasesPass ());
896888 MPM.addPass (NameAnonGlobalPass ());
897889 }
898- // For `-Copt-level=0`, ThinLTO, or LTO.
890+ // For `-Copt-level=0`, and the pre-link fat/thin LTO stages .
899891 if (ThinLTOBufferRef && *ThinLTOBufferRef == nullptr ) {
900- if (EmitThinLTO) {
892+ // thin lto summaries prevent fat lto, so do not emit them if fat
893+ // lto is requested. See PR #136840 for background information.
894+ if (OptStage != LLVMRustOptStage::PreLinkFatLTO) {
901895 MPM.addPass (ThinLTOBitcodeWriterPass (
902896 ThinLTODataOS, EmitThinLTOSummary ? &ThinLinkDataOS : nullptr ));
903897 } else {
0 commit comments