Skip to content

Simpler Logic Produces More Complex Output Than Equivalent Expression #139851

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ZhonghaoPan-NJU opened this issue Apr 15, 2025 · 0 comments
Open
Labels
C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged.

Comments

@ZhonghaoPan-NJU
Copy link

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
@ZhonghaoPan-NJU ZhonghaoPan-NJU added the C-bug Category: This is a bug. label Apr 15, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged.
Projects
None yet
Development

No branches or pull requests

2 participants