Skip to content

Incorrect handling of lateout pairs in inline asm #101346

Open
@newpavlov

Description

(issue is loosely owned, in terms of P-high tracking, by @wesleywiser and @pnkfelix keeping their eyes on llvm/llvm-project#57550)

Updated bug description

The following Rust function:

pub fn foo() -> u32 {
    let t1: u32;
    let t2: u32;
    unsafe {
        asm!(
            "mov {0:e}, 1",
            "mov eax, 42",
            lateout(reg) t1,
            lateout("eax") t2,
            options(nostack),
        );
    }
    t1
}

Gets compiled into this obviously incorrect assembly:

example::foo:
        mov     eax, 1
        mov     eax, 42
        ret

Godbolt link: https://rust.godbolt.org/z/Yb9v7WobM

LLVM incorrectly reuses register for a pair of lateouts if it can see that one of those does not get used later.

Original description below

We get spurious segfaults in the chacha20 crate when we run tests compiled for i686 target (i686-unknown-linux-gnu to be exact), see RustCrypto/stream-ciphers#304 for more information. Interestingly enough, Rust 1.56 does not have this issue, only 1.57 and later. Changes in the cpufeatures crate which revealed the issue look quite innocent. The issue also disappears if zeroize feature is disabled, which is quite tangential to cpufeatures (it only adds Drop impls). Even weirder, @aumetra's findings show that segfault happens at the following line:

let mut buf = [0u8; MAX_SEEK];

Granted, the chacha20 crate contains a fair bit of unsafe code, as well as its dependencies, so the issue may be caused by unsoundness somewhere in our crates. But the circumstantial evidence makes a potential compiler bug quite probable.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-inline-assemblyArea: Inline assembly (`asm!(…)`)I-miscompileIssue: Correct Rust code lowers to incorrect machine codeI-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.WG-noneIndicates that no working group is assigned to an issue, but it *does* have an active owner

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions