Skip to content
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

Merged
merged 1 commit into from
Oct 6, 2021

Conversation

tspiteri
Copy link
Contributor

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.

@rust-highfive
Copy link
Collaborator

r? @dtolnay

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 29, 2021
@tspiteri
Copy link
Contributor Author

This results in slightly better code generation for wrapping_rem and wrapping_rem_euclid.

Copy link
Member

@dtolnay dtolnay left a 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).

@dtolnay dtolnay added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-libs Relevant to the library team, which will review and decide on the PR/issue. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 3, 2021
@tspiteri
Copy link
Contributor Author

tspiteri commented Oct 5, 2021

Yes, after that suggestion, my original change is no longer necessary (and similarly for rem_euclid).

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.
@dtolnay
Copy link
Member

dtolnay commented Oct 5, 2021

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Oct 5, 2021

📌 Commit 4ec0377 has been approved by dtolnay

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Oct 5, 2021
bors added a commit to rust-lang-ci/rust that referenced this pull request Oct 5, 2021
…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
@bors bors merged commit e745e09 into rust-lang:master Oct 6, 2021
@rustbot rustbot added this to the 1.57.0 milestone Oct 6, 2021
bors added a commit to rust-lang-ci/rust that referenced this pull request Oct 29, 2021
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
@tspiteri tspiteri deleted the wrapping_rem branch November 10, 2021 19:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants