[llvm] [LTO] Fix a crash with thin LTO caching and asm output (PR #138203)

Alexey Karyakin via llvm-commits llvm-commits at lists.llvm.org
Mon May 12 13:20:49 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
----------------
quic-akaryaki wrote:

My analysis above is incorrect. The problem is not because of calling flush() on the raw_ostream but on formatted_raw_ostream, which is legally owned by MCAsmStreamer. There is pending data in the formatted_raw_ostream at the time of MCAsmStreamer destruction and the destructor of formatted_raw_ostream tries to write this data to raw_ostream (TheStream).
So the problem is that MCAsmStreamer writes to the stream during its destruction but by this time, the cached stream has been committed. Regardless of lifetime issues this can't work. It seems #136121 requires more extensive changes from the API users, in particular, to make sure that the stream is not written after explicitly calling commit().

https://github.com/llvm/llvm-project/pull/138203


More information about the llvm-commits mailing list