Skip to content

Fields should not alias Vec content. #71354

Open
@nbp

Description

@nbp

I tried this code ( https://rust.godbolt.org/z/GuvQi9 ), which mutates a field while reading the content of a buffer.

use std::vec::Vec;

pub fn foo(v: &mut Vec<usize>) -> usize {
    assert!(v.len() > 2);
    let s1 = v.pop().unwrap();
    let s2 = v.pop().unwrap();
    s1 + s2
}

Here the assertion is capable of removing the branches which are within the pop function, to make a branch-less function apart from the assertion code:

        […]
        mov     rcx, qword ptr [rdi + 16]
        […]
        lea     rax, [rcx - 1]
        mov     qword ptr [rdi + 16], rax
        […]
        lea     rsi, [rcx - 2]
        mov     qword ptr [rdi + 16], rsi
        […]

However, the generated code still contains a spill of the len field of the vector for each pop-ed value which is used. The reason is that LLVM does not know whether the read type can alias or not the field which is being written to. This aliasing reason is inconsistent with the fact that the len field from which the value which is written back to memory is aliased in the rcx register.

I would have expected the generated code to contain a single update of the len field, instead of 2.

Testing with -C opt-level=3 does not change the result.

Meta

Tested with both rustc --version --verbose:

rustc 1.42.0 (b8cedc004 2020-03-09)
binary: rustc
commit-hash: b8cedc00407a4c56a3bda1ed605c6fc166655447
commit-date: 2020-03-09
host: x86_64-unknown-linux-gnu
release: 1.42.0
LLVM version: 9.0

and

rustc 1.44.0-nightly (7f3df5772 2020-04-16)
binary: rustc
commit-hash: 7f3df5772439eee1c512ed2eb540beef1124d236
commit-date: 2020-04-16
host: x86_64-unknown-linux-gnu
release: 1.44.0-nightly
LLVM version: 9.0

edit: remove the -Zmutable_noalias as this seems to optimize this minimized test case. #71354 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-codegenArea: Code generationC-enhancementCategory: An issue proposing an enhancement or a PR with one.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-slowIssue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions