Skip to content

[Optimization] Significantly different assembly output for logically equivalent match patterns with string comparisons #139784

Open
@ZhonghaoPan-nju

Description

@ZhonghaoPan-nju

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

#[no_mangle]
fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
    match s1.len().cmp(&s2.len()) {
        std::cmp::Ordering::Greater|std::cmp::Ordering::Less if s1 != "\"" || s2 != "" => { s1 }
        std::cmp::Ordering::Greater => s1,
        std::cmp::Ordering::Less => s2,
        std::cmp::Ordering::Equal => s1,
    }
}

and:

#[no_mangle]
fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
    let temp_bridge_9 = s1;
    match temp_bridge_9.len().cmp(&s2.len()) {
        std::cmp::Ordering::Greater | std::cmp::Ordering::Less if !(s1 == "\"") || !(s2 == "") => {
            s1
        }
        std::cmp::Ordering::Greater => s1,
        std::cmp::Ordering::Less => s2,
        std::cmp::Ordering::Equal => s1,
    }
}

I expected to see this happen:

longest:
        mov     rdx, rsi
        mov     rax, rdi
        ret

Instead, this happened:

longest:
        mov     r8, rdx
        mov     rdx, rsi
        mov     rax, rdi
        cmp     rsi, rcx
        seta    sil
        sbb     sil, 0
        je      .LBB0_10
        movzx   esi, sil
        cmp     esi, 1
        jne     .LBB0_6
        cmp     rdx, 1
        jne     .LBB0_10
        test    rcx, rcx
        jne     .LBB0_10
        cmp     byte ptr [rax], 34
        jne     .LBB0_10
        mov     edx, 1
.LBB0_10:
        ret
.LBB0_6:
        cmp     rdx, 1
        jne     .LBB0_10
        test    rcx, rcx
        jne     .LBB0_10
        cmp     byte ptr [rax], 34
        jne     .LBB0_10
        xor     edx, edx
        mov     rax, r8
        ret

There are notable discrepancies in the assembly output between the two functionally equivalent implementations of longest. I suspect that the variant logic in the condition s1 != "\"" || s2 != "" may be influencing the compiler's optimization behavior.

I’d greatly appreciate it if you could review these cases.
Thank you for your time and consideration!

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.A-patternsRelating to patterns and pattern matchingC-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