Skip to content

Commit 4ca769a

Browse files
author
Krishna Sai Veera Reddy
committed
Optimize Ord trait implementation for bool
Casting the booleans to `i8`s and converting their difference into `Ordering` generates better assembly than casting them to `u8`s and comparing them.
1 parent d99e0c6 commit 4ca769a

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

src/libcore/cmp.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,7 @@ pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
10061006

10071007
// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
10081008
mod impls {
1009+
use crate::hint::unreachable_unchecked;
10091010
use crate::cmp::Ordering::{self, Less, Greater, Equal};
10101011

10111012
macro_rules! partial_eq_impl {
@@ -1126,7 +1127,15 @@ mod impls {
11261127
impl Ord for bool {
11271128
#[inline]
11281129
fn cmp(&self, other: &bool) -> Ordering {
1129-
(*self as u8).cmp(&(*other as u8))
1130+
// Casting to i8's and converting the difference to an Ordering generates
1131+
// more optimal assembly.
1132+
// See <https://github.com/rust-lang/rust/issues/66780> for more info.
1133+
match (*self as i8) - (*other as i8) {
1134+
-1 => Less,
1135+
0 => Equal,
1136+
1 => Greater,
1137+
_ => unsafe { unreachable_unchecked() },
1138+
}
11301139
}
11311140
}
11321141

src/libcore/tests/cmp.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ fn test_int_totalord() {
99
assert_eq!(12.cmp(&-5), Greater);
1010
}
1111

12+
#[test]
13+
fn test_bool_totalord() {
14+
assert_eq!(true.cmp(&false), Greater);
15+
assert_eq!(false.cmp(&true), Less);
16+
assert_eq!(true.cmp(&true), Equal);
17+
assert_eq!(false.cmp(&false), Equal);
18+
}
19+
1220
#[test]
1321
fn test_mut_int_totalord() {
1422
assert_eq!((&mut 5).cmp(&&mut 10), Less);

src/test/codegen/bool-cmp.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// This is a test for optimal Ord trait implementation for bool.
2+
// See <https://github.com/rust-lang/rust/issues/66780> for more info.
3+
4+
// compile-flags: -C opt-level=3
5+
6+
#![crate_type = "lib"]
7+
8+
use std::cmp::Ordering;
9+
10+
// CHECK-LABEL: @cmp_bool
11+
#[no_mangle]
12+
pub fn cmp_bool(a: bool, b: bool) -> Ordering {
13+
// CHECK: zext i1
14+
// CHECK: zext i1
15+
// CHECK: sub nsw
16+
a.cmp(&b)
17+
}

0 commit comments

Comments
 (0)