Skip to content

Problems with dead code elimination with opt-level=s #140665

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

Open
newpavlov opened this issue May 5, 2025 · 5 comments
Open

Problems with dead code elimination with opt-level=s #140665

newpavlov opened this issue May 5, 2025 · 5 comments
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues.

Comments

@newpavlov
Copy link
Contributor

(Initially was asked on URLO)

I encountered a weird result while inspecting assembly for my piece of code compiled with opt-level=s:

https://rust.godbolt.org/z/5czhzaKoM

It looks as if dead code elimination was not applied here for some reason. The assembly generated for to_u32s (the only public function in the crate) does not call any other code snippets presented in the generated assembly. I know that unused functions may be eliminated later by linker, but it still looks weird.

@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label May 5, 2025
@nikic
Copy link
Contributor

nikic commented May 5, 2025

This is due to -Zshare-generics: https://rust.godbolt.org/z/cnfnjsEe3

@newpavlov
Copy link
Contributor Author

newpavlov commented May 5, 2025

Hm, but those "shared" generics are not used by this crate, so shouldn't they be eliminated from its binary?

Either way, if it's an expected behavior, feel free to close this issue.

@hanna-kruppe
Copy link
Contributor

hanna-kruppe commented May 5, 2025

If rustc was inlining them and never emitted LLVM IR for them, then sure. But if they get codegen’d, -Zshare-generics means they don’t get internal linkage because the whole point is allowing other codegen units to link to them instead of duplicating the monomorphozations. This forces LLVM to emit the functions even if nothing in that codegen unit uses them.

@jieyouxu jieyouxu added C-discussion Category: Discussion or questions that doesn't represent real issues. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels May 5, 2025
@saethlin
Copy link
Member

saethlin commented May 5, 2025

Hm, but those "shared" generics are not used by this crate, so shouldn't they be eliminated from its binary?

The kind of coordination that this would require to work is far beyond what the combination of rustc and cargo can pull off right now. Downstream crates need to know what symbols are exported by upstream crates so that they can skip instantiating their own copy of them. If the list of exported symbols changed due to LLVM optimizations I'm not sure what we'd even do. Re-analyze LLVM's outputs? This would also break the way that cargo pipelines crate builds; kicking off a downstream crate as soon as just the metadata not the object code is available for all its dependencies. This kind of dead code elimination would require revising metadata information based on object code.

In addition, I don't think LLVM has a way to express that this function can be removed from this library if all calls to it go away, but also please don't mess with its ABI.

All that being said, if you want these symbols to go away, just stick #[inline] on them. Most of the functions instantiated by compiling the code in question are generic and would be eligible for sharing, but aren't because they have #[inline]. Add -Cno-prepopulate-passes --emit=llvm-ir and you can see how many functions are define internal, that's because they are #[inline].

@bjorn3
Copy link
Member

bjorn3 commented May 6, 2025

In any case the linker will omit those unused functions on most platforms due to rustc passing --gc-sections to the linker (and compiling with -ffunction-sections for that to actually be effective at removing dead functions).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues.
Projects
None yet
Development

No branches or pull requests

7 participants