Skip to content

Simpler Logic Produces More Complex Output Than Equivalent Expression #139851

Open
@ZhonghaoPan-nju

Description

@ZhonghaoPan-nju

I tried these codes:
https://godbolt.org/z/sE73ocr4a

#![allow(unused_parens)]
#![allow(non_camel_case_types)]
enum colour {
    red(isize, isize),
    green,
}
impl PartialEq for colour {
    #[no_mangle]
    fn eq(&self, other: &colour) -> bool {
        match *self {
            colour::red(a0, b0) => match (*other) {
                colour::red(a1, b1) => a0 == a1 && b0 == b1,
                colour::green => false,
            },
            colour::green => match (*other) {
                colour::red(..) => false,
                colour::green => true,
            },
        }
    }
}

and:

#![allow(unused_parens)]
#![allow(non_camel_case_types)]
enum colour {
    red(isize, isize),
    green,
}
impl PartialEq for colour {
    #[no_mangle]
    fn eq(&self, other: &colour) -> bool {
        match *self {
            colour::red(a0, b0) => match (*other) {
                colour::red(a1, b1) => !(!(!(a0 != a1)) || !(!(b0 != b1))),
                colour::green => false,
            },
            colour::green => match (*other) {
                colour::red(..) => false,
                colour::green => true,
            },
        }
    }
}

I expected to see this happen:
Both expressions should produce identical assembly code:

eq:
        movzx   eax, byte ptr [rdi]
        mov     rcx, qword ptr [rsi]
        mov     edx, eax
        or      dl, cl
        test    dl, 1
        je      .LBB0_2
        and     al, cl
        and     al, 1
        ret
.LBB0_2:
        mov     rax, qword ptr [rdi + 8]
        xor     rax, qword ptr [rsi + 8]
        mov     rcx, qword ptr [rsi + 16]
        xor     rcx, qword ptr [rdi + 16]
        or      rcx, rax
        sete    al
        and     al, 1
        ret

Instead, this happened:
The first expression with simpler logic a0 == a1 && b0 == b1, generated more complex assembly code than expected:

eq:
        cmp     dword ptr [rdi], 1
        jne     .LBB0_2
        movzx   eax, byte ptr [rsi]
        and     al, 1
        ret
.LBB0_2:
        test    byte ptr [rsi], 1
        jne     .LBB0_3
        mov     rax, qword ptr [rdi + 8]
        cmp     rax, qword ptr [rsi + 8]
        jne     .LBB0_3
        mov     rax, qword ptr [rdi + 16]
        cmp     rax, qword ptr [rsi + 16]
        sete    al
        and     al, 1
        ret
.LBB0_3:
        xor     eax, eax
        and     al, 1
        ret

Thank you!

Meta

rustc 1.85.0-nightly (d117b7f21 2024-12-31)
binary: rustc
commit-hash: d117b7f211835282b3b177dc64245fff0327c04c
commit-date: 2024-12-31
host: x86_64-unknown-linux-gnu
release: 1.85.0-nightly
LLVM version: 19.1.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.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