Skip to content

Missed optimization: matches! results in worse codgen than a logical or #141497

Open
@ohadravid

Description

@ohadravid

The following two functions have different codegens, and the || version seems to be better than the matches! version:

#[derive(Clone, Copy, PartialEq, Eq)]
pub enum FrameType {
    Key = 0,
    Inter = 1,
    Intra = 2,
    Switch = 3,
}

#[inline(never)]
pub fn is_inter_or_switch_matches(f: FrameType) -> bool {
  matches!(f, FrameType::Inter | FrameType::Switch)
}


#[inline(never)]
pub fn is_inter_or_switch_or(f: FrameType) -> bool {
  f == FrameType::Inter || f == FrameType::Switch
}
example::is_inter_or_switch_matches::h454503befaf9eb0d:
        mov     w8, #253
        sub     w9, w0, #1
        tst     w9, w8
        cset    w0, eq
        ret

example::is_inter_or_switch_or::hdac478b484733164:
        and     w0, w0, #0x1
        ret

using Rust 1.87, https://godbolt.org/z/hnfnWjjYG.

LLVM IR:

; playground::is_inter_or_switch_matches
; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind nonlazybind willreturn memory(none) uwtable
define noundef zeroext i1 @_ZN10playground26is_inter_or_switch_matches17h8e5fad9a7cd067a2E(i8 noundef range(i8 0, 4) %f) unnamed_addr #0 {
start:
  %0 = add nsw i8 %f, -1
  %switch.and = and i8 %0, -3
  %switch.selectcmp = icmp eq i8 %switch.and, 0
  ret i1 %switch.selectcmp
}

; playground::is_inter_or_switch_or
; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind nonlazybind willreturn memory(none) uwtable
define noundef zeroext i1 @_ZN10playground21is_inter_or_switch_or17hd0f9f7ece60fbca8E(i8 noundef range(i8 0, 4) %f) unnamed_addr #0 {
start:
  %0 = and i8 %f, 1
  %_0.sroa.0.0 = icmp ne i8 %0, 0
  ret i1 %_0.sroa.0.0
}

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.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions