Skip to content

Commit

Permalink
Optimize PartialOrd le
Browse files Browse the repository at this point in the history
Closes #73338
This change stops default implementation of `le()` method from generating jumps.
  • Loading branch information
AngelicosPhosphoros committed Apr 4, 2021
1 parent 836c317 commit ed0d8fa
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
3 changes: 2 additions & 1 deletion library/core/src/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,8 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn le(&self, other: &Rhs) -> bool {
matches!(self.partial_cmp(other), Some(Less | Equal))
// Pattern `Some(Less | Eq)` optimizes worse than negating `None | Some(Greater)`.
!matches!(self.partial_cmp(other), None | Some(Greater))
}

/// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
Expand Down
39 changes: 39 additions & 0 deletions src/test/codegen/issue-73338-effecient-cmp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// This test checks that comparison operation
// generated by #[derive(PartialOrd)]
// doesn't contain jumps for C enums

// compile-flags: -Copt-level=3

#![crate_type="lib"]

#[repr(u32)]
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd)]
pub enum Foo {
Zero,
One,
Two,
}

#[no_mangle]
pub fn compare_less(a: Foo, b: Foo)->bool{
// CHECK-NOT: br {{.*}}
a < b
}

#[no_mangle]
pub fn compare_le(a: Foo, b: Foo)->bool{
// CHECK-NOT: br {{.*}}
a <= b
}

#[no_mangle]
pub fn compare_ge(a: Foo, b: Foo)->bool{
// CHECK-NOT: br {{.*}}
a >= b
}

#[no_mangle]
pub fn compare_greater(a: Foo, b: Foo)->bool{
// CHECK-NOT: br {{.*}}
a > b
}

0 comments on commit ed0d8fa

Please sign in to comment.