[llvm] [LTO] Fix a crash with thin LTO caching and asm output (PR #138203)
via llvm-commits
llvm-commits at lists.llvm.org
Wed May 7 09:52:11 PDT 2025
================
@@ -439,27 +439,33 @@ static void codegen(const Config &Conf, TargetMachine *TM,
std::unique_ptr<CachedFileStream> &Stream = *StreamOrErr;
TM->Options.ObjectFilenameForDebug = Stream->ObjectPathName;
- legacy::PassManager CodeGenPasses;
- TargetLibraryInfoImpl TLII(Mod.getTargetTriple());
- CodeGenPasses.add(new TargetLibraryInfoWrapperPass(TLII));
- // No need to make index available if the module is empty.
- // In theory these passes should not use the index for an empty
- // module, however, this guards against doing any unnecessary summary-based
- // analysis in the case of a ThinLTO build where this might be an empty
- // regular LTO combined module, with a large combined index from ThinLTO.
- if (!isEmptyModule(Mod))
- CodeGenPasses.add(
- createImmutableModuleSummaryIndexWrapperPass(&CombinedIndex));
- if (Conf.PreCodeGenPassesHook)
- Conf.PreCodeGenPassesHook(CodeGenPasses);
- if (TM->addPassesToEmitFile(CodeGenPasses, *Stream->OS,
- DwoOut ? &DwoOut->os() : nullptr,
- Conf.CGFileType))
- report_fatal_error("Failed to setup codegen");
- CodeGenPasses.run(Mod);
-
- if (DwoOut)
- DwoOut->keep();
+ // Create the LTO pipeline in its own scope so it gets deleted before
+ // Stream->commit() is called. The commit function of CacheFile deletes
----------------
anjenner wrote:
CachedFileStream::commit calls OS.reset() which deletes the underlying raw stream. A pointer to this stream is kept by the formatted_raw_ostream created by CodeGenTargetMachineImpl::createMCStreamer(). This is then kept by the MCAsmStreamer object. https://github.com/llvm/llvm-project/pull/136121 does change the point at which the deletion of the stream happens since the legacy::PassManager object is destructed before the std::unique_ptr<CachedFileStream> (since the constructor of the former happens later). With https://github.com/llvm/llvm-project/pull/136121 the commit happens before the legacy::PassManager destructor (and hence the MCAsmStreamer destructor, and hence the formatted_raw_stream destructor, and hence the flush() call). This PR causes the legacy::PassManager destructor to be called before the commit operation.
I have checked the other uses of CachedFileStream::commit() for similar lifetime issues, and did not find any.
https://github.com/llvm/llvm-project/pull/138203
More information about the llvm-commits
mailing list