rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.2k stars 12.7k forks source link

inlining and `--release` builds can result in weird debuginfo relative to source #126940

Open betelgeuse opened 4 months ago

betelgeuse commented 4 months ago

I created this simple example:

use std::arch::aarch64::*;

fn main() {
    let arg = std::env::args().nth(1).unwrap();
    let source = unsafe { vld1_u8(arg.as_ptr()) };
    println!("Hello with {:?}", source);
    let to_minus = unsafe { vcreate_u8(0x0101010101010101) };
    let less = unsafe { vsub_u8(source, to_minus) };
    println!("After subtract {:?}", less);
}

I expected to see this happen: explanation

This should find a line in the output:

CARGO_PROFILE_RELEASE_DEBUG=true cargo objdump --release -- --source -d | grep vld1_u8

Instead, this happened: explanation

I dumped the asm with:

CARGO_PROFILE_RELEASE_DEBUG=true cargo objdump --release -- --source -d | grep emit_asm_example::main -A 50

I had to setup a symlink in root (maybe there's a better way but this was good enough inside a container) to find the sources

:/# ls -l rustc/
total 8
lrwxrwxrwx 1 root root 83 Jun 25 09:27 6b0f4b5ec3aa707ecaa78230722117324a4ce23c -> /usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-gnu/lib/rustlib/src/rust
lrwxrwxrwx 1 root root 83 Jun 25 09:07 79734f1db8dbe322192dea32c0f6b80ab14c4c1d -> /usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-gnu/lib/rustlib/src/rust

The relevant output is:

;     println!("Hello with {:?}", source);
    6524: 90000015      adrp    x21, 0x6000 <core::slice::index::slice_index_order_fail::h5a9a5465262d1439+0x38>
    6528: 910f42b5      add x21, x21, #0x3d0
;     unsafe { copy_nonoverlapping(src, dst, count) }
    652c: fd400280      ldr d0, [x20]
;     println!("Hello with {:?}", source);
    6530: a903d7e8      stp x8, x21, [sp, #0x38]
;         Arguments { pieces, fmt: None, args }
    6534: f00002a8      adrp    x8, 0x5d000 <GCC_except_table0+0x10834>
    6538: 9125c108      add x8, x8, #0x970
    653c: 52800049      mov w9, #0x2                // =2
    6540: 9100e3f6      add x22, sp, #0x38
;         Arguments { pieces, fmt: None, args }
    6544: a900a7e8      stp x8, x9, [sp, #0x8]
    6548: 52800028      mov w8, #0x1                // =1
;         slot.value
    654c: fd0003e0      str d0, [sp]
;         Arguments { pieces, fmt: None, args }
    6550: f9000ff6      str x22, [sp, #0x18]
    6554: a9027fe8      stp x8, xzr, [sp, #0x20]
;     println!("Hello with {:?}", source);
    6558: 910023e0      add x0, sp, #0x8
    655c: 9400603e      bl  0x1e654 <std::io::stdio::_print::h3749cc038f249062>
;     simd_sub(a, b)
    6560: 6f07e7e0      movi    v0.2d, #0xffffffffffffffff
;     let less = unsafe { vsub_u8(source, to_minus) };
    6564: fd4003e1      ldr d1, [sp]
    6568: 910163e8      add x8, sp, #0x58
;         Arguments { pieces, fmt: None, args }
    656c: f00002a9      adrp    x9, 0x5d000 <GCC_except_table0+0x10834>
    6570: 91264129      add x9, x9, #0x990
;     println!("After subtract {:?}", less);
    6574: a903d7e8      stp x8, x21, [sp, #0x38]
    6578: 52800048      mov w8, #0x2                // =2

Only vsub_u8 shows up when it should also have vld1_u8. It seems wrong code gets picked up to the output for the latter.

Meta

rustc --version --verbose:

rustc 1.81.0-nightly (6b0f4b5ec 2024-06-24)
binary: rustc
commit-hash: 6b0f4b5ec3aa707ecaa78230722117324a4ce23c
commit-date: 2024-06-24
host: aarch64-unknown-linux-gnu
release: 1.81.0-nightly
LLVM version: 18.1.7
bjorn3 commented 4 months ago

Why do you expect vld1_u8 to be present in the disassembled executable? You are building in release mode and vld1_u8 is both small and marked as #[inline], so it will be inlined. Also debuginfo is not entirely accurate in release mode, so the lack of any debuginfo corresponding to the line where you call vld1_u8 is not unexpected.

betelgeuse commented 4 months ago

Why do you expect vld1_u8 to be present in the disassembled executable? You are building in release mode and vld1_u8 is both small and marked as #[inline], so it will be inlined. Also debuginfo is not entirely accurate in release mode, so the lack of any debuginfo corresponding to the line where you call vld1_u8 is not unexpected.

Because in my original code from which I created the example there's a line to which to attribute the call. It currently gets annotated like this for the original code.

;     unsafe { copy_nonoverlapping(src, dst, count) }
    cdcc: fc401020      ldur    d0, [x1, #0x1]

Lines four to five of my simple example seem to replicate the issue.