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.llvm-fixed-upstreamIssue expected to be fixed by the next major LLVM upgrade, or backported fixes

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions