Repository navigation
Ensure full LTO'd bitcode goes through the normal LTO pipeline instead of the thinlto pipeline #159624
Description
Activity
- addedneeds-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triagingThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
on Jul 20, 2026 It appears that when rust is driving the link that it will unconditionally pipe all bitcode through the thin lto pipeline.
Rustc uses either the ThinLTO or the fat LTO post-link pipeline depending on if
-Clto=thinor-Clto=fatis used, which is exactly what should happen, right? If you ask for ThinLTO, it shouldn't silently do fat LTO instead.Do I understand it correctly that the issue you have is when mixing dependencies compiled with
-Clto=fatwith a leaf crate compiled with-Clto=thin? If I understand correctly, #159029 would fix that case.- addedA-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-LTOArea: Link-time optimization (LTO)Area: Link-time optimization (LTO)
on Jul 21, 2026 It appears that when rust is driving the link that it will unconditionally pipe all bitcode through the thin lto pipeline.
Rustc uses either the ThinLTO or the fat LTO post-link pipeline depending on if
-Clto=thinor-Clto=fatis used, which is exactly what should happen, right? If you ask for ThinLTO, it shouldn't silently do fat LTO instead.The linker usually dispatches to the corresponding pipeline. You don't get participation for cross module optimization in all cases, but the module summary makes those optimizations possible for ThinLTO at least, and improves compatibility. There always needs to be some level of support for mixed Thin and Full LTO, or established mechanisms, like WPD or CFI would fail to work, since they require SplitLTOUnits, that split thin modules into a Thin part and a Full LTO part. I beleive that is the major driver here: we want Fuchsia's kernel to be able to use software based CFI and WPD (which it already does) and we don't want want the new Rust code in the kernel to fail to work or loose out on cross module optimizations. Note Fuchsia, unlike other systems, doesn't require KCFI to have control flow integrity enabled, and has had a working system w/ standard Clang/LLVM CFI working in its kernel for some time. This is a property we'd like to keep.
Do I understand it correctly that the issue you have is when mixing dependencies compiled with
-Clto=fatwith a leaf crate compiled with-Clto=thin? If I understand correctly, #159029 would fix that case.The module summary partially addresses the issue, in that it solves one level of incompatibility. I think even in the case where that is addressed, this assertion would fire. This doesn't happen when the linker drives the LTO process, and that deviation is somewhat surprising (and to me a bit concerning).
For WPD and CFI rustc enforces fat LTO. Rust itself has no use for hybrid LTO AFAIK and non-Rust objects never participate in Rust's LTO implementation anyway. You need
-Clinker-plugin-ltoto make non-Rust objects participate in LTO and for that hybrid LTO should already work fine.You need -Clinker-plugin-lto to make non-Rust objects participate in LTO and for that hybrid LTO should already work fine.
If I'm reading https://doc.rust-lang.org/rustc/linker-plugin-lto.html correctly, then I think
-Clinker-plugin-ltowouldn't work here with a mix of thin lto'd and full lto'd bitcode since one of the requirements is every participating bitcode module must be built with the same flavor of LTO. That is, all full lto xor all thin lto. If it's LLD driving the link though and LLD already supports this mix of full and thin LTO'd bitcode, then I think from an LTO perspective this might not need to be a hard requirement assuming everything emits module summaries.-Clinker-plugin-ltomakes LLD (or whatever linker you use) do the LTO. Without-Clinker-plugin-ltono non-Rust object files would be LTOed and thus using only fat or thin LTO is fine. So once #159029 lands everything should work fine without-Clinker-plugin-ltotoo even when mixing-Clto=thinand-Clto=fatfor dependencies.
(Summarized from https://g-issues.fuchsia.dev/issues/517626589)
If we build an rlib compiled with
-Clto=fatbut use the bitcode in a link using-Clto=thinthen we will hit this assertion inthinLTOInternalizeModule:It appears that when rust is driving the link that it will unconditionally pipe all bitcode through the thin lto pipeline. I believe this is incorrect for these reasons:
Normally this would work if lld drives the link since lld knows how to dispatch which bitcode module goes through which pipeline. We should ensure rust does the same.