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 · 1 comment
Open
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-optimization Category: An issue highlighting optimization opportunities or PRs implementing such I-slow Issue: Problems and improvements with respect to performance of generated code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

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
@saethlin
Copy link
Member

alive2 says the optimization is valid: https://alive2.llvm.org/ce/z/6ag-eE

@saethlin saethlin added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. I-slow Issue: Problems and improvements with respect to performance of generated code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-optimization Category: An issue highlighting optimization opportunities or PRs implementing such and removed C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Apr 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-optimization Category: An issue highlighting optimization opportunities or PRs implementing such I-slow Issue: Problems and improvements with respect to performance of generated code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants