-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Rustc fails to optimize a common option usage pattern #68667
Comments
It looks like Rust's niche-filling optimization is defeating LLVM's optimizations. In
LLVM ends up inlining the calls to This can be seen by changing the type to a tuple of pub fn unwrap_combinators(a: Option<i32>, b: i32) -> bool {
a.map(|t| (t >= b, ()))
.unwrap_or((false, ()))
.0
}
pub fn unwrap_manual(a: Option<i32>, b: i32) -> bool {
match a {
Some(t) => t >= b,
None => false
}
} which generates the following ASM:
LLVM has all of the information it needs to optimize the original IR - however, it doesn't seem to have an instcombine special-case that would allow it to do so. Unfortunately, neither
The fact that LLVM decides to inline these functions suggets that we might be overly conservative in how we calculating inlining cost. Hopefully, this situation will be improved by #68528, which specifically calls out |
@Aaron1011 I can confirm that, with #68528, |
Should this issue be closed now? Since it's been solved by #68528. Or maybe since it's still under |
This won't be fixed until MIR inlining becomes more usable and should remain open. I would like to see an "I-slow-fixed-by-MIR-inlining" tag so issues like this and #66234 can be triaged more efficiently. |
That makes a lot of sense 🙂 |
It looks like the code is now optimized properly in recent |
Add codegen tests for E-needs-test close rust-lang#36010 close rust-lang#68667 close rust-lang#74938 close rust-lang#83585 close rust-lang#93036 close rust-lang#109328 close rust-lang#110797 close rust-lang#111508 close rust-lang#112509 close rust-lang#113757 close rust-lang#120440 close rust-lang#118392 close rust-lang#71096 r? nikic
Add codegen tests for E-needs-test close rust-lang#36010 close rust-lang#68667 close rust-lang#74938 close rust-lang#83585 close rust-lang#93036 close rust-lang#109328 close rust-lang#110797 close rust-lang#111508 close rust-lang#112509 close rust-lang#113757 close rust-lang#120440 close rust-lang#118392 close rust-lang#71096 r? nikic
Add codegen tests for E-needs-test close rust-lang#36010 close rust-lang#68667 close rust-lang#74938 close rust-lang#83585 close rust-lang#93036 close rust-lang#109328 close rust-lang#110797 close rust-lang#111508 close rust-lang#112509 close rust-lang#113757 close rust-lang#120440 close rust-lang#118392 close rust-lang#71096 r? nikic
Add codegen tests for E-needs-test close rust-lang#36010 close rust-lang#68667 close rust-lang#74938 close rust-lang#83585 close rust-lang#93036 close rust-lang#109328 close rust-lang#110797 close rust-lang#111508 close rust-lang#112509 close rust-lang#113757 close rust-lang#120440 close rust-lang#118392 close rust-lang#71096 r? nikic
Consider following functions
The first pattern is what we often write and the second one is the most efficient manually unrolled version. Surprisingly rustc fails to optimize the former one into the latter as you can see in godbolt listing:
P.S. Yes, I'm aware of
map_or
The text was updated successfully, but these errors were encountered: