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

driftsort implementation uses an out-of-range literal on 16-bit targets #129910

Closed
saethlin opened this issue Sep 2, 2024 · 12 comments · Fixed by #130832
Closed

driftsort implementation uses an out-of-range literal on 16-bit targets #129910

saethlin opened this issue Sep 2, 2024 · 12 comments · Fixed by #130832
Labels
C-bug Category: This is a bug. O-AVR Target: AVR processors (ATtiny, ATmega, etc.) O-msp430 T-libs Relevant to the library team, which will review and decide on the PR/issue.

Comments

@saethlin
Copy link
Member

saethlin commented Sep 2, 2024

Run

cargo +nightly miri setup --target avr-unknown-gnu-atmega328

Or

x check library/core --target avr-unknown-gnu-atmega328

And you'll get this diagnostic (cargo miri setup makes it a warning, lol):

error: literal out of range for `usize`
  --> core/src/slice/sort/stable/mod.rs:62:41
   |
62 |     const MAX_FULL_ALLOC_BYTES: usize = 8_000_000; // 8MB
   |                                         ^^^^^^^^^
   |
   = note: the literal `8_000_000` does not fit into the type `usize` whose range is `0..=65535`
   = note: `#[deny(overflowing_literals)]` on by default

I don't know what effect this has at runtime but it can't be good.

@saethlin saethlin added the C-bug Category: This is a bug. label Sep 2, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Sep 2, 2024
@saethlin saethlin added O-AVR Target: AVR processors (ATtiny, ATmega, etc.) T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Sep 2, 2024
@workingjubilee
Copy link
Member

workingjubilee commented Sep 2, 2024

It's worse than one might think, because many AVR microarchitectures, including the atmega328 we nominally support, have only 2KiB of SRAM, which means that this line is literally impossible:

    // For small inputs 4KiB of stack storage suffices, which allows us to avoid
    // calling the (de-)allocator. Benchmarks showed this was quite beneficial.
    let mut stack_buf = AlignedStorage::<T, 4096>::new();

@workingjubilee
Copy link
Member

these targets should probably use some of the code in #129587 with perhaps a few more tweaks.

@saethlin saethlin removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Sep 3, 2024
@Voultapher
Copy link
Contributor

Voultapher commented Sep 3, 2024

Good to know, 16-bit wasn't something we had in mind during development, in terms of less standard targets, we did test big endian with miri.

I agree with @workingjubilee the code in #129587 would be a better fit for such targets. What kind of tweaks did you have in mind?

@Voultapher
Copy link
Contributor

There are other places in driftsort and ipnsort that use stack arrays, e.g:

let mut stack_array = MaybeUninit::<[T; SMALL_SORT_NETWORK_SCRATCH_LEN]>::uninit();

They are all size bound to <= 4KiB through various means, but still a poor fit for tiny chips.

@orlp
Copy link
Contributor

orlp commented Sep 3, 2024

these targets should probably use some of the code in #129587 with perhaps a few more tweaks.

I think that's necessary, I don't believe driftsort could ever meaningfully run on machines this small.

@workingjubilee
Copy link
Member

What kind of tweaks did you have in mind?

You already figured it out: dropping all the stack arrays to the absolute minimum.

Note that you are not obligated to fix these targets, as usual.

@Voultapher
Copy link
Contributor

I think it should be a single additional cfg_if in the impl, so I don't mind doing it.

@RalfJung
Copy link
Member

(cargo miri setup makes it a warning, lol)

Yeah, we'd get CI failures way too often if we errored on warnings for tier 3 targets.

@RalfJung
Copy link
Member

Related: #130818

@saethlin
Copy link
Member Author

Yeah, we'd get CI failures way too often if we errored on warnings for tier 3 targets.

Who is using Tier 3 targets in CI?

@RalfJung
Copy link
Member

Miri is, by running a test with avr.json.

We should probably change that.

@bors bors closed this as completed in 3a33523 Sep 25, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Sep 25, 2024
Rollup merge of rust-lang#130832 - RalfJung:sort-cfg-mess, r=workingjubilee

fix some cfg logic around optimize_for_size and 16-bit targets

Fixes rust-lang#130818.
Fixes rust-lang#129910.

There are still some warnings when building on a 16bit target:
```
warning: struct `AlignedStorage` is never constructed
   --> /home/r/src/rust/rustc.2/library/core/src/slice/sort/stable/mod.rs:135:8
    |
135 | struct AlignedStorage<T, const N: usize> {
    |        ^^^^^^^^^^^^^^
    |
    = note: `#[warn(dead_code)]` on by default

warning: associated items `new` and `as_uninit_slice_mut` are never used
   --> /home/r/src/rust/rustc.2/library/core/src/slice/sort/stable/mod.rs:141:8
    |
140 | impl<T, const N: usize> AlignedStorage<T, N> {
    | -------------------------------------------- associated items in this implementation
141 |     fn new() -> Self {
    |        ^^^
...
145 |     fn as_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<T>] {
    |        ^^^^^^^^^^^^^^^^^^^

warning: function `quicksort` is never used
  --> /home/r/src/rust/rustc.2/library/core/src/slice/sort/unstable/quicksort.rs:19:15
   |
19 | pub(crate) fn quicksort<'a, T, F>(
   |               ^^^^^^^^^

warning: `core` (lib) generated 3 warnings
```

However, the cfg stuff here is sufficiently messy that I didn't want to touch more of it. I think all `feature = "optimize_for_size"` should become `any(feature = "optimize_for_size", target_pointer_width = "16")` but I am not entirely certain. Warnings are fine, Miri will just ignore them.

Cc `@Voultapher`
@Voultapher
Copy link
Contributor

Thinking a bit more about it, is there any scenario where you'd compile Rust for 16-bit targets and don't want to use optimize_for_size? Independent of sort. I'd think that such targets are always binary-size limited and welcome any reduction of it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. O-AVR Target: AVR processors (ATtiny, ATmega, etc.) O-msp430 T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants