Change:
ref: We ran into this linking failure only on i686 Fedora 30+, with LLVM 8. Other arches are fine with LLVM 8, and all arches are fine with LLVM 7 on Fedora 29. I can reproduce this building stock tokei with normal dependencies, so that takes Fedora's crate packaging out of the picture. I also reproduced similar errors with ffsend, but different symbols: and . I can't reproduce this with official stable-1.34, 1.35-beta, nor 1.36-nightly compiler builds. However, I can reproduce it when I build those locally myself, even with a minimal config so I'm using rust's . I have no idea what is the difference in my build at this point.
Using rust master, I bisected LLVM between 7 and 8 to find the point of regression. We gained this in rust when we moved to the monorepo in , especially the change to . I haven't figured out what's wrong with this yet, nor why it would only be affecting i686. As a workaround avoiding ThinLTO, it builds fine with .
any idea why statics would be apparently lost by ThinLTO?
Oh wow starting from a bisected LLVM commit is quite nice, thanks for doing the legwork to find that! That commit in LLVM sounds pretty suspicious though because it sounds like it's working from the assumption that ThinLTO has complete and total knowledge of the entire compilation, I'm not sure there's ever a case you can internalize something that's otherwise public. Especially in Rust's case we can never do that because we don't learn about cross-crate dependencies until the linker, and our ThinLTO phase only ever has total knowledge of one crate, no others. From browsing around the patch it looks like we may be able to fix this though on our end. If is changed to instead of I think that this will be fixed, would you be able to test that out?
Huh, can it be so simple? I did have a suspicious eye on that argument, but the callers in LLVM made me think we would want too. But yes, setting that does seem to work! :tada: I'll run through more tests to make sure that's not regressing anything, but I'm hopeful -- thanks!
With , it failed a couple tests on i686, although x86_64 still passed. :confounded:
Umm, actually those tests fail for me on i686 without modification too... :confused:
Those tests are pretty brittle and are probably likely to produce false negatives, but I'd also be curious to see what causes it! Sounds like otherwise it may be fixed so yay! FWIW all I do when updating llvm is copy their code for thinlto as well and this is the first time that strategy hasn't worked!
:laughing: I'm trying again in the docker image -- if I can get that to pass, I'll open a PR.
Should we be making a distinction between local and global ThinLTO here? The latter should have a full cross-crate picture, right?
I think we could do that if no native libraries are linked, but as soon as there's some native library is somewhere we also don't have the full picture because it could be relying on linking to a static that's only read from Rust (or something like that)

Discussion:
return PrevailingType::Unknown; }; #if LLVM_VERSION_GE(8, 0) <ins> // We don't have a complete picture in our use of ThinLTO, just our immediate // crate, so we need `ImportEnabled = false` to limit internalization. // Otherwise, we sometimes lose `static` values -- see #60184. </ins> computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols, <del> deadIsPrevailing, /* ImportEnabled = */ true); </del> <ins> deadIsPrevailing, /* ImportEnabled = */ false); </ins> #else computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols, deadIsPrevailing); #endif