Skip to content

Commit 30fd79c

Browse files
authored
Rollup merge of rust-lang#63767 - lzutao:integer-ord-suboptimal, r=nagisa
Use more optimal Ord implementation for integers Closes rust-lang#63758 r? @nagisa ### Compare results ([godbolt link](https://godbolt.org/z/dsbczy)) Old assembly: ```asm example::cmp1: mov eax, dword ptr [rdi] mov ecx, dword ptr [rsi] cmp eax, ecx setae dl add dl, dl add dl, -1 xor esi, esi cmp eax, ecx movzx eax, dl cmove eax, esi ret ``` New assembly: ```asm example::cmp2: mov eax, dword ptr [rdi] xor ecx, ecx cmp eax, dword ptr [rsi] seta cl mov eax, 255 cmovae eax, ecx ret ``` Old llvm-mca statistics: ``` Iterations: 100 Instructions: 1100 Total Cycles: 243 Total uOps: 1300 Dispatch Width: 6 uOps Per Cycle: 5.35 IPC: 4.53 Block RThroughput: 2.2 ``` New llvm-mca statistics: ``` Iterations: 100 Instructions: 700 Total Cycles: 217 Total uOps: 1100 Dispatch Width: 6 uOps Per Cycle: 5.07 IPC: 3.23 Block RThroughput: 1.8 ```
2 parents 0784395 + f5b16f6 commit 30fd79c

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

src/libcore/cmp.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,9 +1012,11 @@ mod impls {
10121012
impl Ord for $t {
10131013
#[inline]
10141014
fn cmp(&self, other: &$t) -> Ordering {
1015-
if *self == *other { Equal }
1016-
else if *self < *other { Less }
1017-
else { Greater }
1015+
// The order here is important to generate more optimal assembly.
1016+
// See <https://github.com/rust-lang/rust/issues/63758> for more info.
1017+
if *self < *other { Less }
1018+
else if *self > *other { Greater }
1019+
else { Equal }
10181020
}
10191021
}
10201022
)*)

src/test/codegen/integer-cmp.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// This is test for more optimal Ord implementation for integers.
2+
// See <https://github.com/rust-lang/rust/issues/63758> 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_signed
11+
#[no_mangle]
12+
pub fn cmp_signed(a: i64, b: i64) -> Ordering {
13+
// CHECK: icmp slt
14+
// CHECK: icmp sgt
15+
// CHECK: zext i1
16+
// CHECK: select i1
17+
a.cmp(&b)
18+
}
19+
20+
// CHECK-LABEL: @cmp_unsigned
21+
#[no_mangle]
22+
pub fn cmp_unsigned(a: u32, b: u32) -> Ordering {
23+
// CHECK: icmp ult
24+
// CHECK: icmp ugt
25+
// CHECK: zext i1
26+
// CHECK: select i1
27+
a.cmp(&b)
28+
}

0 commit comments

Comments
 (0)