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

fix unsoundness in Step::forward_unchecked for signed integers #122461

Merged
merged 2 commits into from
Mar 14, 2024

Conversation

the8472
Copy link
Member

@the8472 the8472 commented Mar 13, 2024

Fixes #122420

pub fn foo(a: i8, b: u8) -> i8 {
    unsafe { a.checked_add_unsigned(b).unwrap_unchecked() }
}

still compiles down to a single arithmetic instruction (godbolt).

But we may be losing some loop optimizations if llvm can no longer easily derive that it's a finite counted loop from the no-wrapping flags.

@rustbot
Copy link
Collaborator

rustbot commented Mar 13, 2024

r? @Amanieu

rustbot has assigned @Amanieu.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Mar 13, 2024
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rustbot
Copy link
Collaborator

rustbot commented Mar 13, 2024

The Miri subtree was changed

cc @rust-lang/miri

@@ -1 +1 @@
The loop took around 7s
The loop took around 12s
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this intentional?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test contains a loop over a range of unconstrained integer types which defaults to i32.
Aiui in miri "time" ticks based on the number of mir statements executed or something like that. Since the Range impl changed this also affects rate of time.

Copy link
Member

@saethlin saethlin Mar 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Argh this test again. We should probably do something a bit better here.

When isolation is enabled (the default), Miri doesn't have access to the system clock, so we use the end of a basic block as an extremely crude approximation of clock ticks, so that we can have a clock when isolation is enabled. This test asserts that the magic number for NANOSECONDS_PER_BASIC_BLOCK gets us an isolation clock that's remotely close to the real passage of time. Because when we first did this I think it was off by a factor of 100.

This diff is fine for this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still a bit surprised that the number of basic blocks is almost doubling?

@Amanieu
Copy link
Member

Amanieu commented Mar 14, 2024

@bors r+

@bors
Copy link
Contributor

bors commented Mar 14, 2024

📌 Commit d3cab9f has been approved by Amanieu

It is now in the queue for this repository.

@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-review Status: Awaiting review from the assignee but also interested parties. labels Mar 14, 2024
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Mar 14, 2024
…, r=Amanieu

fix unsoundness in Step::forward_unchecked for signed integers

Fixes rust-lang#122420

```rust
pub fn foo(a: i8, b: u8) -> i8 {
    unsafe { a.checked_add_unsigned(b).unwrap_unchecked() }
}
```

still compiles down to a single arithmetic instruction ([godbolt](https://rust.godbolt.org/z/qsd3xYWfE)).

But we may be losing some loop optimizations if llvm can no longer easily derive that it's a finite counted loop from the no-wrapping flags.
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 14, 2024
…iaskrgr

Rollup of 11 pull requests

Successful merges:

 - rust-lang#104353 (Add CStr::bytes iterator)
 - rust-lang#114038 (unix time module now return result)
 - rust-lang#119676 (rustdoc-search: search types by higher-order functions)
 - rust-lang#120699 (Document `TRACK_DIAGNOSTIC` calls.)
 - rust-lang#121899 (Document how removing a type's field can be bad and what to do instead)
 - rust-lang#121940 (Mention Register Size in `#[warn(asm_sub_register)]`)
 - rust-lang#122397 (Various cleanups around the const eval query providers)
 - rust-lang#122405 (Add methods to create StableMIR constant)
 - rust-lang#122416 (Various style improvements to `rustc_lint::levels`)
 - rust-lang#122440 (const-eval: organize and extend tests for required-consts)
 - rust-lang#122461 (fix unsoundness in Step::forward_unchecked for signed integers)

r? `@ghost`
`@rustbot` modify labels: rollup
jhpratt added a commit to jhpratt/rust that referenced this pull request Mar 14, 2024
…, r=Amanieu

fix unsoundness in Step::forward_unchecked for signed integers

Fixes rust-lang#122420

```rust
pub fn foo(a: i8, b: u8) -> i8 {
    unsafe { a.checked_add_unsigned(b).unwrap_unchecked() }
}
```

still compiles down to a single arithmetic instruction ([godbolt](https://rust.godbolt.org/z/qsd3xYWfE)).

But we may be losing some loop optimizations if llvm can no longer easily derive that it's a finite counted loop from the no-wrapping flags.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Mar 14, 2024
…, r=Amanieu

fix unsoundness in Step::forward_unchecked for signed integers

Fixes rust-lang#122420

```rust
pub fn foo(a: i8, b: u8) -> i8 {
    unsafe { a.checked_add_unsigned(b).unwrap_unchecked() }
}
```

still compiles down to a single arithmetic instruction ([godbolt](https://rust.godbolt.org/z/qsd3xYWfE)).

But we may be losing some loop optimizations if llvm can no longer easily derive that it's a finite counted loop from the no-wrapping flags.
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 14, 2024
…iaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang#104353 (Add CStr::bytes iterator)
 - rust-lang#119676 (rustdoc-search: search types by higher-order functions)
 - rust-lang#120699 (Document `TRACK_DIAGNOSTIC` calls.)
 - rust-lang#121899 (Document how removing a type's field can be bad and what to do instead)
 - rust-lang#122405 (Add methods to create StableMIR constant)
 - rust-lang#122416 (Various style improvements to `rustc_lint::levels`)
 - rust-lang#122421 (Improve `Step` docs)
 - rust-lang#122440 (const-eval: organize and extend tests for required-consts)
 - rust-lang#122461 (fix unsoundness in Step::forward_unchecked for signed integers)

Failed merges:

 - rust-lang#122397 (Various cleanups around the const eval query providers)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 75dc99b into rust-lang:master Mar 14, 2024
11 checks passed
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Mar 14, 2024
Rollup merge of rust-lang#122461 - the8472:fix-step-forward-unchecked, r=Amanieu

fix unsoundness in Step::forward_unchecked for signed integers

Fixes rust-lang#122420

```rust
pub fn foo(a: i8, b: u8) -> i8 {
    unsafe { a.checked_add_unsigned(b).unwrap_unchecked() }
}
```

still compiles down to a single arithmetic instruction ([godbolt](https://rust.godbolt.org/z/qsd3xYWfE)).

But we may be losing some loop optimizations if llvm can no longer easily derive that it's a finite counted loop from the no-wrapping flags.
@rustbot rustbot added this to the 1.78.0 milestone Mar 14, 2024
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.

UB in <Range as Iterator>::advance_by (Step::forward_unchecked) for signed integers
7 participants