rust-lang / rust-lang/rust

Illegal instructions generated for Arm Cortex-R5 processor when compiling code using floating-point operations

Open
#128,448 21 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-LLVM C-bug I-miscompile I-unsound O-Arm P-medium
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

View all comments

When targeting the Arm Cortex-R5 processor, rustc and llvm generate assembly containing floating-point instructions. These are not available on the Cortex-R5 (only on the Cortex-R5F) and cause the processor to halt.

Details

For example, the following code:

fn add_s(a: f32, b: f32) -> f32 {
    a + b
}

fn add_d(a: f64, b: f64) -> f64 {
    a + b
}

compiled with flags --target armv7r-none-eabi -C opt-level=3 -C target-cpu=cortex-r5 generates the assembly (compiler explorer link):

add_s:
        vmov    s0, r1
        vmov    s2, r0
        vadd.f32        s0, s2, s0
        vmov    r0, s0
        bx      lr

add_d:
        vmov    d0, r2, r3
        vmov    d1, r0, r1
        vadd.f64        d0, d1, d0
        vmov    r0, r1, d0
        bx      lr

Note the vadd.f32 and vadd.f64 instructions, that are available on the Cortex-R5F which has an FPU, but that are illegal instructions on the Cortex-R5 without an FPU.

My expectation is that, using the target armv7r-none-eabi (rather than armv7r-none-eabihf) and the target CPU cortex-r5 (rather than cortex-r5f), rustc and llvm would generate legal instructions for the processor, i.e. use software floating-point features rather than hard-float instructions.

Relevant information

Original thread on URLO: Unexpected codegen for Cortex-R5 without FPU.

The upstream LLVM CPU model for cortex-r5 includes the flag FeatureVFP3_D16, which seems OK for the R5F but wrong for the R5. However, manually disabling that feature doesn't seem to help (see below). Link to llvm repo at tag 18.1.7.

Information from the ARM Cortex-R Series Programmer's Guide: 6.1.6. VFP in the Cortex-R processors.

Things that do work
Skipping the target-cpu flag

Compiling the snippet above with flags --target armv7r-none-eabi -C opt-level=3 generates:

add_s:
        push    {r11, lr}
        bl      __aeabi_fadd
        pop     {r11, pc}

add_d:
        push    {r11, lr}
        bl      __aeabi_dadd
        pop     {r11, pc}
Adding the soft-float target feature

Compiling the snippet above with flags --target armv7r-none-eabi -C opt-level=3 -C target-cpu=cortex-r5 -C target-feature=+soft-float generates:

add_s:
        push    {r11, lr}
        bl      __aeabi_fadd
        pop     {r11, pc}

add_d:
        push    {r11, lr}
        bl      __aeabi_dadd
        pop     {r11, pc}

However, rustc generates the warning:

warning: unknown and unstable feature specified for `-Ctarget-feature`: `soft-float`
  |
  = note: it is still passed through to the codegen backend, but use of this feature might be unsound and the behavior of this feature can change in the future
  = help: consider filing a feature request

warning: 1 warning emitted
Things that don't work
Removing the vfp3d16 target feature

Compiling the snippet above with flags --target armv7r-none-eabi -C opt-level=3 -C target-cpu=cortex-r5 -C target-feature=-vfp3d16 generates:

add_s:
        vmov    s0, r1
        vmov    s2, r0
        vadd.f32        s0, s2, s0
        vmov    r0, s0
        bx      lr

add_d:
        vmov    d0, r2, r3
        vmov    d1, r0, r1
        vadd.f64        d0, d1, d0
        vmov    r0, r1, d0
        bx      lr
Meta

I've tested both stable and nightly toolchains, with same results.

rustc --version --verbose:

rustc 1.80.0 (051478957 2024-07-21)
binary: rustc
commit-hash: 051478957371ee0084a7c0913941d2a8c4757bb9
commit-date: 2024-07-21
host: x86_64-unknown-linux-gnu
release: 1.80.0
LLVM version: 18.1.7

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with the Rust target and code-generation flags shown, then inspect the Cortex-R5 CPU definition in LLVM's ARM.td and the rustc target-feature handling. Compare the generated assembly with the soft-float case; done means armv7r-none-eabi with cortex-r5 emits legal software-floating-point calls without requiring an unstable feature override.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers, embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
50/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.