Skip to content

Incorrect code generated from inline assembly with inout register on riscv32im-unknown-none-elf #128212

Closed

Description

@shkoo

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)

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Jul 25, 2024
  2. tgross35 commented on Jul 25, 2024

    @tgross35
    Member

    I haven't looked into this too much yet, but do you know if it reproduces using C's inline assembly fed through clang? This seems like it could be an LLVM problem.

  3. flaub commented on Jul 26, 2024

    @flaub
    Contributor

    It appears that this bug starts to appear in 1.77.

    Using riscv32i-unknown-none-elf target:

    1.76: https://godbolt.org/z/bKosKqvfW
    1.77: https://godbolt.org/z/MYacc9na7

  4. flaub commented on Jul 26, 2024

    @flaub
    Contributor

    Could it be that this is the same underlying issue?
    #126221

  5. tgross35 commented on Jul 26, 2024

    @tgross35
    Member

    Did you mean between 1.77 and 1.78? The two links look the same to me.

    It looks like this has to be a regression in LLVM, which was bumped to version 18 in 1.78, because we seem to generate the exact same IR. Could you file an issue with LLVM?

    https://godbolt.org/z/Te9efcnMz

    Could it be that this is the same underlying issue? #126221

    It looks like it, I will close that one because this one has more detail.

  6. added
    WG-llvmWorking group: LLVM backend code generation
    and removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Jul 26, 2024
  7. added
    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.
    I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
    and removed
    WG-llvmWorking group: LLVM backend code generation
    on Jul 26, 2024
  8. added
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Jul 26, 2024
  9. apiraino commented on Jul 26, 2024

    @apiraino
    Contributor

    WG-prioritization assigning priority (Zulip discussion).

    Being an unsound issue, maybe let's see what we can do. Compile target is Tier 2.

    @rustbot label -I-prioritize +P-high

  10. added
    P-highHigh priority
    and removed
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Jul 26, 2024
  11. added
    llvm-fixed-upstreamIssue expected to be fixed by the next major LLVM upgrade, or backported fixes
    on Jul 27, 2024
  12. tgross35 commented on Jul 27, 2024

    @tgross35
    Member

    Fix applied to LLVM 19.x llvm/llvm-project#100843

  13. added 3 commits that reference this issue on Jul 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-inline-assemblyArea: Inline assembly (`asm!(…)`)C-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessO-riscvTarget: RISC-V architectureP-highHigh priorityllvm-fixed-upstreamIssue expected to be fixed by the next major LLVM upgrade, or backported fixes

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions