Skip to content

something something#4

Closed
Shourya742 wants to merge 1 commit intomasterfrom
2025-04-16-pre-compile-bootstrap
Closed

something something#4
Shourya742 wants to merge 1 commit intomasterfrom
2025-04-16-pre-compile-bootstrap

Conversation

@Shourya742
Copy link
Owner

No description provided.

@Shourya742 Shourya742 force-pushed the 2025-04-16-pre-compile-bootstrap branch 4 times, most recently from eced81c to 895fe51 Compare April 20, 2025 13:34
@Shourya742 Shourya742 force-pushed the 2025-04-16-pre-compile-bootstrap branch from 895fe51 to 73c500a Compare April 20, 2025 13:48
@Shourya742 Shourya742 closed this Aug 13, 2025
Shourya742 pushed a commit that referenced this pull request Sep 15, 2025
match clang's `va_arg` assembly on arm targets

tracking issue: rust-lang#44930

For this example

```rust
#![feature(c_variadic)]

#[unsafe(no_mangle)]
unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 {
    let b = args.arg::<f64>();
    let c = args.arg::<f64>();

    a + b + c
}
```

We currently generate (via llvm):

```asm
variadic:
    sub     sp, sp, #12
    stmib   sp, {r2, r3}
    vmov    d0, r0, r1
    add     r0, sp, #4
    vldr    d1, [sp, #4]
    add     r0, r0, #15
    bic     r0, r0, #7
    vadd.f64        d0, d0, d1
    add     r1, r0, #8
    str     r1, [sp]
    vldr    d1, [r0]
    vadd.f64        d0, d0, d1
    vmov    r0, r1, d0
    add     sp, sp, #12
    bx      lr
```

LLVM is not doing a good job. In fact, it's well-known that LLVM's implementation of `va_arg` is kind of bad, and we implement it ourselves (based on clang) for many targets already. For arm,  our own `emit_ptr_va_arg` saves 3 instructions.

Next, it turns out it's important for LLVM to explicitly start and end the lifetime of the `va_list`. In rust-lang#146059 I already end the lifetime, but when looking at this again, I noticed that it is important to also start it, see https://godbolt.org/z/EGqvKTTsK: failing to explicitly start the lifetime uses an extra register.

So, the combination of `emit_ptr_va_arg` with starting/ending the lifetime makes rustc emit exactly the instructions that clang generates::

```asm
variadic:
    sub     sp, sp, #12
    stmib   sp, {r2, r3}
    vmov    d16, r0, r1
    vldr    d17, [sp, #4]
    vadd.f64        d16, d16, d17
    vldr    d17, [sp, #12]
    vadd.f64        d16, d16, d17
    vmov    r0, r1, d16
    add     sp, sp, #12
    bx      lr
```

The arguments to `emit_ptr_va_arg` are based on [the clang implementation](https://github.com/llvm/llvm-project/blob/03dc2a41f3d9a500e47b513de5c5008c06860d65/clang/lib/CodeGen/Targets/ARM.cpp#L798-L844).

r? ``@workingjubilee`` (I can re-roll if your queue is too full, but you do seem like the right person here)

try-job: armhf-gnu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant