Repository: rust
Issue: Weird Match Statement Codegen With Byte Strings
Labels: I-slow,T-compiler,C-bug

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.
-->

It seems that with the following snippet of code results in some rather strange codegen:

```rust
pub enum MyEnum {
    A,
    B,
    C,
    D,
}

impl MyEnum {
    pub fn try_from_matched(value: [u8; 4]) -> Result<Self, ()> {
        match &value {
            b"ABCD" => Ok(Self::A),
            b"EFGH" => Ok(Self::B),
            b"IJKL" => Ok(Self::C),
            b"MNOP" => Ok(Self::D),
            _ => Err(()),
        }
    }    
}
```

The following is produced with `-C opt-level=2`:

```asm
example::MyEnum::try_from_matched:
        lea     edx, [rdi - 65]
        rol     dl, 6
        cmp     dl, 3
        ja      .LBB0_1
        mov     ecx, edi
        shr     ecx, 8
        mov     eax, edi
        shr     eax, 16
        shr     edi, 24
        movzx   edx, dl
        lea     rsi, [rip + .LJTI0_0]
        movsxd  rdx, dword ptr [rsi + 4*rdx]
        add     rdx, rsi
        jmp     rdx
.LBB0_3:
        xor     cl, 66
        xor     al, 67
        or      al, cl
        xor     dil, 68
        or      dil, al
        setne   al
        shl     al, 2
        ret
.LBB0_1:
        mov     al, 4
        ret
.LBB0_4:
        xor     cl, 70
        xor     al, 71
        or      al, cl
        xor     dil, 72
        xor     ecx, ecx
        or      dil, al
        setne   cl
        lea     eax, [rcx + 2*rcx]
        add     eax, 1
        ret
.LBB0_5:
        xor     cl, 74
        xor     al, 75
        or      al, cl
        xor     dil, 76
        or      dil, al
        setne   al
        add     al, al
        add     al, 2
        ret
.LBB0_6:
        xor     cl, 78
        xor     al, 79
        or      al, cl
        xor     dil, 80
        or      dil, al
        sete    cl
        mov     al, 4
        sub     al, cl
        ret
.LJTI0_0:
        .long   .LBB0_3-.LJTI0_0
        .long   .LBB0_4-.LJTI0_0
        .long   .LBB0_5-.LJTI0_0
        .long   .LBB0_6-.LJTI0_0
```

I would expect something like this to be produced instead (specifically with optimizations enabled):

```asm
example::MyEnum::try_from_matched:
        cmp     edi, 1145258561
        je      .LBB0_1
        cmp     edi, 1280002633
        je      .LBB0_5
        cmp     edi, 1212630597
        jne     .LBB0_7
        mov     al, 1
        ret
.LBB0_1:
        xor     eax, eax
        ret
.LBB0_5:
        mov     al, 2
        ret
.LBB0_7:
        cmp     edi, 1347374669
        sete    cl
        mov     al, 4
        sub     al, cl
        ret
```

An example is available here: https://rust.godbolt.org/z/EEKr43rP8

For what it's worth, at `-C opt-level=0` it becomes apparent that the `if/else` version uses `PartialEq` while the `match` version doesn't. I suspect that this is resulting in the optimizations for the two examples being processed differently.

### Meta
<!--
If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions.
-->

`rustc --version --verbose`:
```
1.64.0 (also affects nightly and others)
```