LTO on Windows MSVC?


Does LTO actually do anything on the MSVC target?

I noticed a big size improvement for the GNU target but for MSVC it didn’t change anything.


LLVM currently uses link.exe from MSVC toolchain. We can do little about it.


Yes LTO does actually do stuff on the MSVC target. Rust does LTO before calling the linker, so it works regardless of what linker you’re using.

However, the size difference you’re seeing is actually because LTO does two things, it allows for whole program optimization so it can inline any rust function into any other rust function regardless of crate boundaries, and it also doesn’t emit unreferenced Rust code. This latter bit is the difference you’re seeing because link.exe is quite amazing and is already capable of stripping unreferenced code and merging identical comdats, while ld.exe is really really bad at this. As a result, the GNU linker leaves a lot of unreferenced code hanging around which LTO can trivially remove and cause massive space savings. Meanwhile MSVC would always strip unreferenced code anyway, so LTO has minimal effect on size. However LTO still enables cross module inlining so it has value even on MSVC.


Ah, I see.