rust-lang / rust-lang/rust

llvm noalias data gets lost when passing large structs

Open
#131,905 6 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-ABI C-optimization T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

https://godbolt.org/z/b8as1TxdP

#[repr(C)]
pub struct Big<'a>(&'a mut u64, &'a mut u64, usize);

#[inline(never)]
pub unsafe fn bad(a: Big) -> u64 {
    *a.0 = 0;
    *a.1 = 1;
    *a.0
}

#[repr(C)]
pub struct Good<'a>(&'a mut u64, &'a mut u64);

#[inline(never)]
pub unsafe fn good(a: Good) -> u64 {
    *a.0 = 0;
    *a.1 = 1;
    *a.0
}
example::bad::h15eeefb1851d2a2e:
        mov     rax, qword ptr [rdi]
        mov     qword ptr [rax], 0
        mov     rcx, qword ptr [rdi + 8]
        mov     qword ptr [rcx], 1
        mov     rax, qword ptr [rax]
        ret

example::good::h034657cbabb42f00:
        mov     qword ptr [rdi], 0
        mov     qword ptr [rsi], 1
        xor     eax, eax
        ret

i expected the functions to emit similar codegen, but the bad one doesn't get the noalias on the references themselves because llvm thinks they're passed by pointer since the struct is large.

maybe alias.scope can help with this?

Meta

rustc --version --verbose:

rustc 1.84.0-nightly (3ed6e3cc6 2024-10-17)
binary: rustc
commit-hash: 3ed6e3cc69857129c1d314daec00119ff47986ed
commit-date: 2024-10-17
host: x86_64-unknown-linux-gnu
release: 1.84.0-nightly
LLVM version: 19.1.1
Compiler returned: 0

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

Start with the Godbolt reproducer and compare the generated assembly for bad and good, then inspect the corresponding Rust compiler and LLVM output for how large-struct arguments and mutable-reference noalias information are represented. Done means the bad case preserves the relevant noalias information and produces codegen comparable to good, with regression coverage for the reproducer.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.