-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Code generation error on AVR using u16::to_be() #98167
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
Comments
Since I looked it up, here's the expected/actual in hex, which makes the bug more clear: input:
expected:
actual:
|
Hi, Could you please check with |
Also: |
I'm analyzing the codegen bug - simplest reproduction so far: #![no_std]
#![no_main]
use panic_halt as _;
#[arduino_hal::entry]
fn main() -> ! {
let pixels = [0];
for pixel in pixels.map(|n| n + 1) { // works with `.into_iter().map()`
print(pixel);
}
loop {
//
}
}
#[inline(never)]
fn print(pixel: u16) {
let dp = unsafe { arduino_hal::Peripherals::steal() };
let pins = arduino_hal::pins!(dp);
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);
let _ = ufmt::uwriteln!(serial, "{}", pixel);
} |
Got it! The simplest reproduction: #![no_std]
#![no_main]
#![feature(bench_black_box)]
use core::hint::black_box;
use panic_halt as _;
#[arduino_hal::entry]
fn main() -> ! {
if let Some(value) = next() {
print(value);
}
loop {
//
}
}
#[inline(never)]
fn next() -> Option<u16> { // this corresponds to `array.into_iter().next()` from the original code
// (note that the author doesn't call those functions by hand, but that's
// how the loop gets desugared)
black_box(Some(12345))
}
#[inline(never)]
fn print(n: u16) {
let dp = unsafe { arduino_hal::Peripherals::steal() };
let pins = arduino_hal::pins!(dp);
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);
let _ = ufmt::uwriteln!(serial, "{}", n);
} This prints After calling
What the code generator says is: ; (so r23:r24 is the input number; r24:r25 is where we want the number to be.)
mov r24, r23
mov r25, r24 ... which always sets mov r25, r24
mov r24, r23 Overall, that's an omission on the LLVM's side (when moving register pairs, it should consider whether the registers are overlapping or not) - I'll try to prepare a patch 🙂 Edit: https://reviews.llvm.org/D128588. |
When expanding a MOVW (16-bit copy) to two MOVs (8-bit copy), the lower byte always comes first. This is incorrect for corner cases like '$r24r23 -> $r25r24', in which the higher byte copy should come first. Current patch fixes that bug as recorded at rust-lang/rust#98167 Reviewed By: benshi001 Differential Revision: https://reviews.llvm.org/D128588
When expanding a MOVW (16-bit copy) to two MOVs (8-bit copy), the lower byte always comes first. This is incorrect for corner cases like '$r24r23 -> $r25r24', in which the higher byte copy should come first. Current patch fixes that bug as recorded at rust-lang/rust#98167 Reviewed By: benshi001 Differential Revision: https://reviews.llvm.org/D128588
I just updated to nightly-2022-07-08 and some weirdness I was seeing with It also fixed the problems I was having with the st7789 crate that led me to file this bug. |
When expanding a MOVW (16-bit copy) to two MOVs (8-bit copy), the lower byte always comes first. This is incorrect for corner cases like '$r24r23 -> $r25r24', in which the higher byte copy should come first. Current patch fixes that bug as recorded at rust-lang/rust#98167 Reviewed By: benshi001 Differential Revision: https://reviews.llvm.org/D128588
Uh oh!
There was an error while loading. Please reload this page.
I tried this code on AVR (arduino Uno = atmega328p) with opt-level="z":
I expected to see this happen:
debug buf [248, 57351, 7936] mapped
Instead, this happened:
debug buf [0, 57568, 7967] mapped
An alternate code that emits the correct output is
This compiler error is corrupting the pixel stream transmitted via SPI to an ST7789 display from an Arduino Uno. What appears to be happening is that instead of the bytes being swapped, the LSB is being copied to the MSB. I do not have the expertise to decompile and examine the assembly code.
Meta
rustc --version --verbose
:The malfunction also occurs with
cargo +nightly
.rustc +nightly --version --verbose
The full code can be cloned from https://github.com/mutantbob/rust-avr-code-generation-bug
The text was updated successfully, but these errors were encountered: