-
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
for signed wrapping remainder, do not compare lhs with MIN #89351
Conversation
r? @dtolnay (rust-highfive has picked a reviewer for you, use r? to override) |
This results in slightly better code generation for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This leaves overflowing_rem
still generating poor code though, right? The current implementation is:
if unlikely!(self == Self::MIN && rhs == -1) {
(0, true)
} else {
(self % rhs, false)
}
If I've correctly understood the optimization in this PR, it seems like we could change that to:
if unlikely!(rhs == -1) {
(0, self == Self::MIN)
} else {
(self % rhs, false)
}
after which changing wrapping_rem
would probably no longer be necessary (but check godbolt).
Yes, after that suggestion, my original change is no longer necessary (and similarly for |
Since the wrapped remainder is going to be 0 for all cases when the rhs is -1, there is no need to divide in this case. Comparing the lhs with MIN is only done for the overflow bool. In particular, this results in better code generation for wrapping remainder, which discards the overflow bool completely.
@bors r+ rollup |
📌 Commit 4ec0377 has been approved by |
…arth Rollup of 10 pull requests Successful merges: - rust-lang#88706 (Normalize associated type projections when checking return type of main) - rust-lang#88828 (Use `libc::sigaction()` instead of `sys::signal()` to prevent a deadlock) - rust-lang#88871 (Fix suggestion for nested struct patterns) - rust-lang#89317 (Move generic error message to separate branches) - rust-lang#89351 (for signed wrapping remainder, do not compare lhs with MIN) - rust-lang#89442 (Add check for duplicated doc aliases) - rust-lang#89502 (Fix Lower/UpperExp formatting for integers and precision zero) - rust-lang#89523 (Make `proc_macro_derive_resolution_fallback` a future-breakage lint) - rust-lang#89532 (Document behavior of `MaybeLiveLocals` regarding enums and field-senstivity) - rust-lang#89546 (Make an initial guess for metadata size to reduce buffer resizes) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Replace some operators in libcore with their short-circuiting equivalents In libcore there are a few occurrences of bitwise operators used in boolean expressions instead of their short-circuiting equivalents. This makes it harder to perform some kinds of source code analysis over libcore, for example [MC/DC] code coverage (a requirement in safety-critical environments). This PR aims to remove as many bitwise operators in boolean expressions from libcore as possible, without any performance regression and without other changes. This means not all bitwise operators are removed, only the ones that don't have any difference with their short-circuiting counterparts. This already simplifies achieving MC/DC coverage, and the other functions can be changed in future PRs. The PR is best reviewed commit-by-commit, and each commit has the resulting assembly in the message. ## Checked integer methods These methods recently switched to bitwise operators in PRs rust-lang#89459 and rust-lang#89351. I confirmed bitwise operators are needed in most of the functions, except these two: * `{integer}::checked_div` ([Godbolt link (nightly)](https://rust.godbolt.org/z/17efh5jPc)) * `{integer}::checked_rem` ([Godbolt link (nightly)](https://rust.godbolt.org/z/85qGWc94K)) `@tspiteri` already mentioned this was the case in rust-lang#89459 (comment), but opted to also switch those two to bitwise operators for consistency. As that makes MC/DC analysis harder this PR proposes switching those two back to short-circuiting operators. ## `{unsigned_ints}::carrying_add` [Godbolt link (1.56.0)](https://rust.godbolt.org/z/vG9vx8x48) In this instance replacing the `|` with `||` produces the exact same assembly when optimizations are enabled, so switching to the short-circuiting operator shouldn't have any impact. ## `{unsigned_ints}::borrowing_sub` [Godbolt link (1.56.0)](https://rust.godbolt.org/z/asEfKaGE4) In this instance replacing the `|` with `||` produces the exact same assembly when optimizations are enabled, so switching to the short-circuiting operator shouldn't have any impact. ## String UTF-8 validation [Godbolt link (1.56.0)](https://rust.godbolt.org/z/a4rEbTvvx) In this instance replacing the `|` with `||` produces practically the same assembly, with the two operands for the "or" swapped: ```asm ; Old mov rax, qword ptr [rdi + rdx + 8] or rax, qword ptr [rdi + rdx] test rax, r9 je .LBB0_7 ; New mov rax, qword ptr [rdi + rdx] or rax, qword ptr [rdi + rdx + 8] test rax, r8 je .LBB0_7 ``` [MC/DC]: https://en.wikipedia.org/wiki/Modified_condition/decision_coverage
Since the wrapped remainder is going to be 0 for all cases when the rhs is -1, there is no need to compare the lhs with MIN.