rust/tests/assembly-llvm
Stuart Cook 48d684111e
Rollup merge of #144549 - folkertdev:va-arg-arm, r=saethlin
match clang's `va_arg` assembly on arm targets

tracking issue: https://github.com/rust-lang/rust/issues/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 https://github.com/rust-lang/rust/pull/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](03dc2a41f3/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
2025-09-12 20:02:10 +10:00
..
asm Updated uitests for new parser 2025-08-22 08:58:45 +02:00
auxiliary Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
compiletest-self-test Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
libs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
naked-functions Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
nvptx-kernel-abi Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
sanitizer/kcfi Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
simd Ignore intrinsic calls in cross-crate-inlining cost model 2025-09-05 20:44:49 -04:00
stack-protector Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
targets compiler: Add {x86_64,aarch64,riscv64gc}-unknown-managarm-mlibc targets 2025-08-29 00:49:29 +02:00
aarch64-pointer-auth.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
aarch64-xray.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
align_offset.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
breakpoint.rs Ignore intrinsic calls in cross-crate-inlining cost model 2025-09-05 20:44:49 -04:00
c-variadic-arm.rs implement va_arg for arm in rustc itself 2025-09-08 13:46:28 +02:00
closure-inherit-target-feature.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
cmse.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
cstring-merging.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
dwarf-mixed-versions-lto.rs Fix tests/assembly-llvm/dwarf-mixed-versions-lto.rs test failure on riscv64 2025-07-23 11:14:07 +00:00
dwarf4.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
dwarf5.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
emit-intel-att-syntax.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
force-target-feature.rs Add an experimental unsafe(force_target_feature) attribute. 2025-08-22 01:26:26 +02:00
is_aligned.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
issue-83585-small-pod-struct-equality.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
loongarch-float-struct-abi.rs Fix LoongArch C function ABI when passing/returning structs containing floats 2025-08-21 18:00:26 +08:00
manual-eq-efficient.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
niche-prefer-zero.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
nvptx-arch-default.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
nvptx-arch-emit-asm.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
nvptx-arch-link-arg.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
nvptx-arch-target-cpu.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
nvptx-atomics.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
nvptx-c-abi-arg-v7.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
nvptx-c-abi-ret-v7.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
nvptx-internalizing.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
nvptx-linking-binary.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
nvptx-linking-cdylib.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
nvptx-safe-naming.rs Fix nvptx-safe-naming.rs test on LLVM 21 2025-07-29 12:15:36 +02:00
panic-no-unwind-no-uwtable.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
panic-unwind-no-uwtable.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
pic-relocation-model.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
pie-relocation-model.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
powerpc64-struct-abi.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
reg-struct-return.rs Add assembly tests verifying the functionality of -Zreg-struct-return for structs of different sizes. 2025-08-27 20:17:08 +02:00
regparm-module-flag.rs Set NumRegisterParameters LLVM module flag to N when -Zregparm=N is 2025-08-13 17:37:30 +02:00
riscv-float-struct-abi.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
riscv-soft-abi-with-float-features.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
rust-abi-arg-attr.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
s390x-backchain-toggle.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
s390x-vector-abi.rs update some s390x codegen tests 2025-08-20 16:35:33 +02:00
simd-bitmask.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
simd-intrinsic-gather.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
simd-intrinsic-mask-load.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
simd-intrinsic-mask-reduce.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
simd-intrinsic-mask-store.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
simd-intrinsic-scatter.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
simd-intrinsic-select.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
slice-is_ascii.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
small_data_threshold.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
sparc-struct-abi.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
stack-probes.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
static-relocation-model.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
strict_provenance.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
target-feature-multiple.rs Rename tests/codegen into tests/codegen-llvm 2025-07-22 14:28:48 +02:00
wasm_exceptions.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
x86-return-float.rs Relax check lines in x86-return-float.rs 2025-07-29 14:08:19 +02:00
x86_64-array-pair-load-store-merge.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
x86_64-bigint-helpers.rs Stop using uadd.with.overflow 2025-08-08 21:59:28 -07:00
x86_64-cmp.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
x86_64-floating-point-clamp.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
x86_64-fortanix-unknown-sgx-lvi-generic-load.rs use minicore for fortanix assembly tests 2025-07-28 13:34:25 +02:00
x86_64-fortanix-unknown-sgx-lvi-generic-ret.rs use minicore for fortanix assembly tests 2025-07-28 13:34:25 +02:00
x86_64-fortanix-unknown-sgx-lvi-inline-assembly.rs use minicore for fortanix assembly tests 2025-07-28 13:34:25 +02:00
x86_64-function-return.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
x86_64-indirect-branch-cs-prefix.rs Add -Zindirect-branch-cs-prefix option 2025-08-17 16:51:42 +02:00
x86_64-mcount.rs Test instrument-mcount 2025-08-26 13:44:00 +00:00
x86_64-no-jump-tables.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
x86_64-sse_crc.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
x86_64-typed-swap.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
x86_64-windows-float-abi.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
x86_64-windows-i128-abi.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00
x86_64-xray.rs Rename tests/assembly into tests/assembly-llvm 2025-07-22 14:27:48 +02:00