-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
add support for unchecked math #59148
Conversation
r? @eddyb (rust_highfive has picked a reviewer for you, use r? to override) |
What's the purpose of these? Wrapping math is zero-overhead on every supported architecture, I believe. |
Previous attempt: #52205 @lachlansneff It's not zero-overhead for optimizations, though. |
@lachlansneff This PR is partially inspired by this blog post: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
|
@eddyb while I don't think that the increase in performance will be that relevant, I will try some quick benchmarks when all additions are replaced with |
I simultaneously have two opinions here:
|
My main reason for not wanting these is that I fear some people will cargo-cult them in the belief that it makes their program faster when really they just escalate all integer overflow bugs in their code to instant UB. |
@rkruppe personally, I'm far more worried about existing utilities in the standard library, like |
I have looked at the speedup of The repo where the default |
The following functions/benchmarks seem like they are actually affected by this.
|
This one, at least, is definitely wrong,
Otherwise, something as simple as Some of the others may be too - if there are any who aren't (wrong optimizations, that is), you should instead open issues about missed optimizations. |
These are only exposed in One thing that one can do with them is implement saturated/checked/wrapping arithmetic in Rust itself on top of these intrinsics only, instead of using the LLVM specific ones. This is not a very practical thing to do, but if the intent is to experiment, I think that's fine. |
Normally when people request a feature they want to use it in their project and most people want it have a trajectory towards (eventual) stability. I don't want to put words in anyone's mouths but I see no reason to expect that these will stay perma-unstable if they're added, except by accident because everyone forgets about them.
I don't understand this at all. For wrapping arithmetic you can't do better than remove the UB on overflow and let the processor do its thing. For checked and saturating arithmetic, even if they're implemented as a code sequence that "looks before it leaps" and thus could have a non-overflowing operating embedded in it, I don't see how the optimizations that need UB-on-overflow would be applicable. |
As far as I can tell, this is not waiting on technical review but waiting on decision from the relevant team. (By the way, what is the relevant team here?) |
@sanxiyn these are perma unstable core intrinsics, so probably the compiler team is the relevant team here. It wouldn't hurt for the lang and lib teams to know that these might become available. |
After reading the conversation here and some personal though I am actually slightly against adding these intrinsics to the language. The most important reason for me is that even only emitting the unchecked versions during codegen does not lead to many performance improvements. All noticeable improvements I've looked at were due to enabling UB after these changes. Personally I would like to only keep the undefined add/sub/mul for codegen and emit them for operations which are guaranteed to not overflow thanks to some kind of range analysis. In case someone wants to use these intrinsics, it should then be possible with the following code: // this currently does not generate add nuw instead of a simple add instruction,
// requires some future optimizations
a.checked_add(b).unwrap_or_else(|| core::hint::unreachable_unchecked()) |
Adding T-Lang + T-Libs for the question of "do we want to expose this to users?" and T-Compiler for "do we want to use this internally for something else?" and nominating for all teams. |
The libs team discussed this during triage and concluded that we see no issues including these eventually in the standard library. Stabilization would certainly be a different story, but adding them eventually was not objected to by anyone. |
I'll note that we're already doing weird things to hack around the lack of these, for example rust/src/libcore/iter/range.rs Lines 170 to 185 in 6cc24f2
I'd much rather see that code as "I'm using Even if these intrinsics never stabilize, I wouldn't be surprised to find a handful of places they're worth it in super-core library pieces like |
@lcnr Based on the commits now showing in here, it looks like something went awry in resolving the conflicts? Maybe try the rebase again? |
And in particular, please rebase, don't merge. |
this was the weirdest rebase I have ever done... Edit: nevermind, I just didn't fully understand the changes made by @eddyb |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
@eddyb should be ready for review |
Added tests for both unsafe and unstable. |
@bors r+ |
📌 Commit d7e0834 has been approved by |
add support for unchecked math add compiler support for ```rust /// Returns the result of an unchecked addition, resulting in /// undefined behavior when `x + y > T::max_value()` or `x + y < T::min_value()`. pub fn unchecked_add<T>(x: T, y: T) -> T; /// Returns the result of an unchecked substraction, resulting in /// undefined behavior when `x - y > T::max_value()` or `x - y < T::min_value()`. pub fn unchecked_sub<T>(x: T, y: T) -> T; /// Returns the result of an unchecked multiplication, resulting in /// undefined behavior when `x * y > T::max_value()` or `x * y < T::min_value()`. pub fn unchecked_mul<T>(x: T, y: T) -> T; ``` cc rust-lang/rfcs#2508
☀️ Test successful - checks-travis, status-appveyor |
add compiler support for
cc rust-lang/rfcs#2508