Closed
Description
I tried compiling this code with a target of riscv32im-unknown-none-elf
:
#![no_std]
static mut MY_BUFFER: [u32; 4] = [0u32; 4];
#[no_mangle]
unsafe fn using_inout() {
let mut start = MY_BUFFER.as_mut_ptr();
::core::arch::asm!(
"ecall",
inout("a0") start);
_ = start;
}
The assembly generated is incorrect, since it doesn't add in the lower 16 bits of the address of MY_BUFFER
before calling the ecall
:
using_inout:
lui a0, %hi(example::MY_BUFFER::he36bd30b506a9b69)
ecall
ret
As a workaround, changing the inout
to inlateout
seems to fix the problem:
using_inlateout:
lui a0, %hi(example::MY_BUFFER::he36bd30b506a9b69)
addi a0, a0, %lo(example::MY_BUFFER::he36bd30b506a9b69)
ecall
ret
Here is a compiler explorer link for rust nightly that demonstrates the problem:
https://godbolt.org/z/xMjoTo5oY
(For reference in case it gets fixed in nightly, it's also present in rust 1.80.0)
Metadata
Metadata
Assignees
Labels
Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Inline assembly (`asm!(…)`)Category: This is a bug.Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessTarget: RISC-V architectureHigh priorityIssue expected to be fixed by the next major LLVM upgrade, or backported fixes