-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LLVM] Segfault / "llvm::thinLTOInternalizeModule ... Assertion `GS != DefinedGlobals.end()' failed", again #67855
Comments
Filed a bug upstream. |
This might still be a rustc bug, since apparently a double-promotion is unexpected. Working on a minimal repro now. |
@tmandry is this something that we could/should be pulling in the ICE-breakers on? |
triage: P-high. Assigning to @tmandry and removing I-nominated label. |
Possibly, but I’ll need to put a usable reproducer somewhere. That tends to be more difficult when the target is Fuchsia. I’ve had limited success doing all the minimizing myself. I’ll see if I can reproduce on other targets, and upload a reproducer if so. |
So, from the output of More specifically:
The offending symbol is promoted to a global once in the first optimization run and again in the second, which accounts for the two I can't think of a reason why we would run the same pipeline twice on the same bitcode. Is there one? |
@tmandry are you compiling with |
@alexcrichton Ahh you were right, it has to do with the flags! For the rlib I wasn't passing (EDIT: I was using Apparently we've been doing this for a very long time in Fuchsia without problems. So is it expected that we should be passing |
Oh weird, so I didn't expect that to fix anything nor did I think that the compiler does what it does! Looks like it boils down to this match here which explains:
So it looks like, yes, you'll want to pass |
Agreed on this still being a bug. Also, as it turns out, the old way of doing it is faster for our build! Presumably since we're doing more work up front. For progeny, I'm posting the data here. Here are a couple runs before adding
Here are a couple runs after:
This is on a 72-core machine building a pretty large graph of Rust crates (many executables). |
Interesting, not the results I would have expected! If you have a lot of executables though and you're running ThinLTO on all of them then you're likely basically optimizing the same code over and over. Before |
Right, so by doing more of that work upfront in the rlibs, we save time optimizing the code for each executable. I think there's still a more efficient way of doing all this. For one, we could disable the actual object file output for rlibs. Also, when compiling the executable, the whole ThinLTO pipeline is run again on the individual crate bitcode before building summaries and distributing the codegen to workers. If there were a way to disable that and tell the compiler to assume that rlib bitcode has already been optimized, we could save some time here. Perhaps we could make that automatic with a flag that emits the summary with the rlib, and detect that it's already there in the executable compile. Of course I'm talking about how to optimize a completely-unintended way of using Rust's ThinLTO pipeline. But since it happens to be faster, it might be worth experimenting with. :) |
Heh perhaps! In theory optimization pipelines are quite flexible and we can basically design whatever we want, it's all just a matter of implementation and measurement at some point. |
Teresa Johnson left some really helpful comments on the downside of doing it this way. To summarize, it can affect what gets inlined (for better or for worse), and it disables whole program devirtualization. We'd have to do some more tinkering with the pipeline and measurement to avoid those issues. |
Also, a fix was landed upstream: https://reviews.llvm.org/D72711 |
Oh something I forgot to reply to earlier
This is one of the subjects on #66961 actually, and yeah would help quite a bit in your case since all the codegen happening in each crate isn't actually used.
A good point!
It sounds like this only happens though if we compile with the equivalent of
Yay! |
Ah that's all very relevant, thanks. Subscribed :)
I opened #68262 to track this. Not expecting it to happen anytime soon, but it seems good to have a tracking issue for it. |
…sform-fixes, r=alexcrichton Update LLVM Fixes #67855 (rust-lang/llvm-project#31) Fixes #66036 (rust-lang/llvm-project#32) r? @nikic @alexcrichton
I got a segfault / LLVM assertion failure while compiling a target with ThinLTO enabled. This is the same failure as in #53912, albeit with a different root cause.
In my case, I was dealing with a global named
switch.table._ZN77_$LT$omaha_client..protocol..request..Event$u20$as$u20$core..clone..Clone$GT$5clone17h829b64c9ab982ff5E.llvm.10390335839252477638.llvm.11308644296266801080
.Note the presence of two
.llvm.NNNN
extensions. This means that this was a local which was promoted to a global symbol twice. The implementation ofgetOriginalNameBeforePromote
doesn't handle this case correctly; it strips off both extensions:The fix is actually trivial; just have to change
split
torsplit
so that it only removes the last.llvm.NNNN
extension. Leaving this issue open to track the fix being cherry-picked.The text was updated successfully, but these errors were encountered: