Repository: rust
Issue: 3-way comparison is branchier after 1.71
Labels: A-LLVM,I-slow,A-codegen,P-medium,T-compiler,regression-from-stable-to-stable,C-bug

### Code

The following code contains two impls of the same (or what should be the same) logic. Prior to 1.71.0, the first impl (using `Option::map()` instead of `match`) would generate llvm ir that could be optimized to use `cmov` instructions, but the second impl (using `match` instead) would use jumps instead.

1.71.0+ generate the same (branchy) llvm ir for both implementations. 
The regression goes away if compiling with `-Zinline-mir=no`, but the `match` implementation remains branchy.

```rust
#[derive(PartialEq)]
pub enum WSL {
    Any,
    V1,
    V2,
}

#[inline(never)]
pub fn is_wsl(wsl: Option<WSL>, v: WSL) -> bool {
    wsl.map(|wsl| v == WSL::Any || wsl == v).unwrap_or(false)
}

#[inline(never)]
pub fn is_wsl2(wsl: Option<WSL>, v: WSL) -> bool {
    match (wsl, v) {
        (Some(_), WSL::Any) => true,
        (Some(x), y) => x == y,
        _ => false
    }
}
```

[Godbolt link](https://rust.godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAMzwBtMA7AQwFtMQByARg9KtQYEAysib0QXACx8BBAKoBnTAAUAHpwAMvAFYTStJg1DEArgoKkl9ZATwDKjdAGFUtEywZ7HAGTwNMAHLuAEaYxCAATFykAA6oCoR2DC5uHnpxCbYCvv5BLKHhUZaY1lkMQgRMxAQp7p7RVpg2SRVVBDmBIWGRDZXVtWm9bR15BT0AlJaoJsTI7BwApBEAzAsArABCWMR4AG6YEMpteGLYAI7j6wAiCxoAgjEmwQDUjO7PAOpC3s8LAOwbW53Z4g553BgAT1IQNBzwAatEYaC4RFofd/jd0eiVusNn5aH4Dv59sRLmtMQ8ns8qAxnngFAB9ADuCloEBZtBAzwA8jEygtlk4vt4BdhSM9dlzheNngBaUXPYKoVy/AFIkEcgB0LCYMQg/ycHINEt%2ByxuZs%2B3xAIHBENVTmNHNN5quEvGmpMDCZxF1DJI1DESku6L%2BFKBS1Wm3xhIgxLCZIpjxeNLpjI5EXZrK5vP5guFovFkst3hl8uW2EVytoqsB91hOoIyAQz0ztELMv%2BteBsNBECEqDYEAZk2L1ttHbNCoIpkwaO7PZb/cHqhHEIn5orqmdAtdUPVPYZ2/L1MDmH3GPDoaBHEmnI4a14nm4vFQnAASmYCM8FNNZphfisPCkAQmg3pMCCYEw2yUJMADWIDLMsmqIShqFofonCSLwLASBoGikE%2BWikK%2BHC8AoID4SBHBaJMcCwEgaAsDEdBhOQlCMcx9DhMQXB/HhfB0AQYTkRAwSgaQwR%2BFUEKcEBknMMQELcsE2hNFRQGMWwgjcgwtAydRvBYMEJjAE4Yi0ORz6kFgOpGOIBnWXgxBqXsmCWURmCqE0JhCbJvB%2BEJd5EQSwQ%2BopLhYOJ054DhVkkkqShXJgtnAASRigZMVAGMAChwngmBMryjB%2BTIggiGI7BSKV8hKGo4m6NEBjpaY5j6HgwTkZAkyoHySSWbKTjPD1BCyvQ%2By0DuyxyoNRkmX4/A7ho03PH0wCYCNyCPDuqgABwAGyyntkhyrKyWEDutC0LsLCyk5L4kjsWCdVAzBsCAmD4GUpC7GIJjzBEGhcDtYHFKUSQOAwziuHUIBrNEPiEqM3RcGssTxIkAgDJ4cNo5kSQjF04Qo6DLkCK0/TQ2kOONM0ZN9O0iOExIqPmG0WOw0M1QE/kyNrJMP4zHMEi3pwD4EeJJHPC1jbPFwmp8ZqS0QLghAkAByxcOMvBUTR4GQdBEBwQhSFoabKEYRwWGkDhXD8YRL6cGRFHARlpB0YgKADpxrEUBAHEsdxvH8TQtBCcQIliQ58nSSV0eKcpqk2CVmmMAQOl6eJs2meZllATZhipfMRH4M5zT7O5vCed5vlWQFJTiSFYUQhFRfazssVAfF8SYElKVpaABmZdluX5YVMTFVZ/BlaI4hVVPNUqOoDm6KiTXGJ%2BbUdfA3W9QI/WDcNo2YONk3LVn82oIty2retsqbSY237Ydx33WEj1ufAsasOwH0Yww32/X%2BhoKIIMaZlAhlDVInhpAI1yEzLgqIMh/3ZtIJBZRuZjAQSTWm5R6YoOwWUcmDM4E8yJqiVmFMoEgGkBQ4hnRSESAiPzX8QtNYWzFvbYinApafmQLLeWGhFYthVkQYg6tNbawykbRCyEzamwtlbThJEnaUSkRbCI2FcL4SUY7F2g9JgkgSPYSQQA%3D)

Optimized IR:

```llvm
define noundef zeroext i1 @_ZN7example6is_wsl17h6965abaffb382d78E(i8 noundef %wsl, i8 noundef %0) unnamed_addr #0 {
start:
  %1 = icmp ne i8 %wsl, 3
  %_3.i.i = icmp eq i8 %0, 0
  %_4.i.i = icmp eq i8 %0, %wsl
  %.0.i.i = or i1 %_3.i.i, %_4.i.i
  %.0 = and i1 %1, %.0.i.i
  ret i1 %.0
}
```

compiling to following x86_64:

```asm
example::is_wsl::h6965abaffb382d78:
        cmp     dil, 3
        setne   cl
        test    sil, sil
        sete    dl
        cmp     sil, dil
        sete    al
        or      al, dl
        and     al, cl
        ret
```

vs unoptimized ir and asm:

```llvm
define noundef zeroext i1 @_ZN7example7is_wsl217h164d1336a42bfb8dE(i8 noundef %wsl, i8 noundef %v) unnamed_addr #0 {
start:
  %.not = icmp eq i8 %wsl, 3
  br i1 %.not, label %bb5, label %bb2

bb2:                                              ; preds = %start
  %0 = icmp eq i8 %v, 0
  %1 = icmp eq i8 %wsl, %v
  %spec.select = or i1 %0, %1
  br label %bb5

bb5:                                              ; preds = %bb2, %start
  %.0 = phi i1 [ false, %start ], [ %spec.select, %bb2 ]
  ret i1 %.0
}
```

```asm
example::is_wsl2::h164d1336a42bfb8d:
        cmp     dil, 3
        jne     .LBB1_2
        xor     eax, eax
        ret
.LBB1_2:
        test    sil, sil
        sete    cl
        cmp     dil, sil
        sete    al
        or      al, cl
        ret
```


### Version it worked on

It most recently worked on: 1.70.0

### Version with regression

`rustc --version --verbose`:
```
1.71.0-stable
```

@rustbot modify labels: +regression-from-stable-to-stable -regression-untriaged +A-codegen +C-bug +I-slow +T-compiler

cc https://github.com/rust-lang/rust/pull/91743