Rollup merge of #114721 - danflapjax:bool-ord-optimization, r=cuviper

Optimizing the rest of bool's Ord implementation

After coming across issue #66780, I realized that the other functions provided by Ord (`min`, `max`, and `clamp`) were similarly inefficient for bool. This change provides implementations for them in terms of boolean operators, resulting in much simpler assembly and faster code.
Fixes issue #114653

[Comparison on Godbolt](https://rust.godbolt.org/z/5nb5P8e8j)

`max` assembly before:
```assembly
example::max:
        mov     eax, edi
        mov     ecx, eax
        neg     cl
        mov     edx, esi
        not     dl
        cmp     dl, cl
        cmove   eax, esi
        ret
```
`max` assembly after:
```assembly
example::max:
        mov     eax, edi
        or      eax, esi
        ret
```
`clamp` assembly before:
```assembly
example:🗜️
        mov     eax, esi
        sub     al, dl
        inc     al
        cmp     al, 2
        jae     .LBB1_1
        mov     eax, edi
        sub     al, sil
        movzx   ecx, dil
        sub     dil, dl
        cmp     dil, 1
        movzx   edx, dl
        cmovne  edx, ecx
        cmp     al, -1
        movzx   eax, sil
        cmovne  eax, edx
        ret
.LBB1_1:
        ; identical assert! code
```
`clamp` assembly after:
```assembly
example:🗜️
        test    edx, edx
        jne     .LBB1_2
        test    sil, sil
        jne     .LBB1_3
.LBB1_2:
        or      dil, sil
        and     dil, dl
        mov     eax, edi
        ret
.LBB1_3:
        ; identical assert! code
```
This commit is contained in:
Matthias Krüger 2023-08-16 08:43:49 +02:00 committed by GitHub
commit 4b2d87d82c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1406,6 +1406,22 @@ fn cmp(&self, other: &bool) -> Ordering {
_ => unsafe { unreachable_unchecked() },
}
}
#[inline]
fn min(self, other: bool) -> bool {
self & other
}
#[inline]
fn max(self, other: bool) -> bool {
self | other
}
#[inline]
fn clamp(self, min: bool, max: bool) -> bool {
assert!(min <= max);
self.max(min).min(max)
}
}
ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }