Skip to content

Commit 04888af

Browse files
authored
Rollup merge of rust-lang#137197 - scottmcm:cmp-20, r=ibraheemdev
Update some comparison codegen tests now that they pass in LLVM20 Fixes rust-lang#106107 Needed one tweak to the default `PartialOrd::le` to get the test to pass. Everything but the derived 2-field `le` test passes even without the change to the defaults in the trait.
2 parents e0dc41a + 3a3aede commit 04888af

File tree

3 files changed

+82
-25
lines changed

3 files changed

+82
-25
lines changed

library/core/src/cmp.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1369,7 +1369,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
13691369
#[stable(feature = "rust1", since = "1.0.0")]
13701370
#[rustc_diagnostic_item = "cmp_partialord_lt"]
13711371
fn lt(&self, other: &Rhs) -> bool {
1372-
matches!(self.partial_cmp(other), Some(Less))
1372+
self.partial_cmp(other).is_some_and(Ordering::is_lt)
13731373
}
13741374

13751375
/// Tests less than or equal to (for `self` and `other`) and is used by the
@@ -1387,7 +1387,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
13871387
#[stable(feature = "rust1", since = "1.0.0")]
13881388
#[rustc_diagnostic_item = "cmp_partialord_le"]
13891389
fn le(&self, other: &Rhs) -> bool {
1390-
matches!(self.partial_cmp(other), Some(Less | Equal))
1390+
self.partial_cmp(other).is_some_and(Ordering::is_le)
13911391
}
13921392

13931393
/// Tests greater than (for `self` and `other`) and is used by the `>`
@@ -1405,7 +1405,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
14051405
#[stable(feature = "rust1", since = "1.0.0")]
14061406
#[rustc_diagnostic_item = "cmp_partialord_gt"]
14071407
fn gt(&self, other: &Rhs) -> bool {
1408-
matches!(self.partial_cmp(other), Some(Greater))
1408+
self.partial_cmp(other).is_some_and(Ordering::is_gt)
14091409
}
14101410

14111411
/// Tests greater than or equal to (for `self` and `other`) and is used by
@@ -1423,7 +1423,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
14231423
#[stable(feature = "rust1", since = "1.0.0")]
14241424
#[rustc_diagnostic_item = "cmp_partialord_ge"]
14251425
fn ge(&self, other: &Rhs) -> bool {
1426-
matches!(self.partial_cmp(other), Some(Greater | Equal))
1426+
self.partial_cmp(other).is_some_and(Ordering::is_ge)
14271427
}
14281428
}
14291429

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//@ compile-flags: -C opt-level=1
2+
//@ min-llvm-version: 20
3+
4+
// The `derive(PartialOrd)` for a 2-field type doesn't override `lt`/`le`/`gt`/`ge`.
5+
// This double-checks that the `Option<Ordering>` intermediate values used
6+
// in the operators for such a type all optimize away.
7+
8+
#![crate_type = "lib"]
9+
10+
use std::cmp::Ordering;
11+
12+
#[derive(PartialOrd, PartialEq)]
13+
pub struct Foo(i32, u32);
14+
15+
// CHECK-LABEL: @check_lt(
16+
// CHECK-SAME: i32{{.+}}%[[A0:.+]], i32{{.+}}%[[A1:.+]], i32{{.+}}%[[B0:.+]], i32{{.+}}%[[B1:.+]])
17+
#[no_mangle]
18+
pub fn check_lt(a: Foo, b: Foo) -> bool {
19+
// CHECK-DAG: %[[EQ:.+]] = icmp eq i32 %[[A0]], %[[B0]]
20+
// CHECK-DAG: %[[R0:.+]] = icmp slt i32 %[[A0]], %[[B0]]
21+
// CHECK-DAG: %[[R1:.+]] = icmp ult i32 %[[A1]], %[[B1]]
22+
// CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[R1]], i1 %[[R0]]
23+
// CHECK-NEXT: ret i1 %[[R]]
24+
a < b
25+
}
26+
27+
// CHECK-LABEL: @check_le(
28+
// CHECK-SAME: i32{{.+}}%[[A0:.+]], i32{{.+}}%[[A1:.+]], i32{{.+}}%[[B0:.+]], i32{{.+}}%[[B1:.+]])
29+
#[no_mangle]
30+
pub fn check_le(a: Foo, b: Foo) -> bool {
31+
// CHECK-DAG: %[[EQ:.+]] = icmp eq i32 %[[A0]], %[[B0]]
32+
// CHECK-DAG: %[[R0:.+]] = icmp sle i32 %[[A0]], %[[B0]]
33+
// CHECK-DAG: %[[R1:.+]] = icmp ule i32 %[[A1]], %[[B1]]
34+
// CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[R1]], i1 %[[R0]]
35+
// CHECK-NEXT: ret i1 %[[R]]
36+
a <= b
37+
}
38+
39+
// CHECK-LABEL: @check_gt(
40+
// CHECK-SAME: i32{{.+}}%[[A0:.+]], i32{{.+}}%[[A1:.+]], i32{{.+}}%[[B0:.+]], i32{{.+}}%[[B1:.+]])
41+
#[no_mangle]
42+
pub fn check_gt(a: Foo, b: Foo) -> bool {
43+
// CHECK-DAG: %[[EQ:.+]] = icmp eq i32 %[[A0]], %[[B0]]
44+
// CHECK-DAG: %[[R0:.+]] = icmp sgt i32 %[[A0]], %[[B0]]
45+
// CHECK-DAG: %[[R1:.+]] = icmp ugt i32 %[[A1]], %[[B1]]
46+
// CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[R1]], i1 %[[R0]]
47+
// CHECK-NEXT: ret i1 %[[R]]
48+
a > b
49+
}
50+
51+
// CHECK-LABEL: @check_ge(
52+
// CHECK-SAME: i32{{.+}}%[[A0:.+]], i32{{.+}}%[[A1:.+]], i32{{.+}}%[[B0:.+]], i32{{.+}}%[[B1:.+]])
53+
#[no_mangle]
54+
pub fn check_ge(a: Foo, b: Foo) -> bool {
55+
// CHECK-DAG: %[[EQ:.+]] = icmp eq i32 %[[A0]], %[[B0]]
56+
// CHECK-DAG: %[[R0:.+]] = icmp sge i32 %[[A0]], %[[B0]]
57+
// CHECK-DAG: %[[R1:.+]] = icmp uge i32 %[[A1]], %[[B1]]
58+
// CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[R1]], i1 %[[R0]]
59+
// CHECK-NEXT: ret i1 %[[R]]
60+
a >= b
61+
}

tests/codegen/comparison-operators-2-tuple.rs

+17-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//@ compile-flags: -C opt-level=1 -Z merge-functions=disabled
22
//@ only-x86_64
3+
//@ min-llvm-version: 20
34

45
#![crate_type = "lib"]
56

@@ -65,12 +66,7 @@ pub fn check_ge_direct(a: TwoTuple, b: TwoTuple) -> bool {
6566
}
6667

6768
//
68-
// These ones are harder, since there are more intermediate values to remove.
69-
//
70-
// `<` seems to be getting lucky right now, so test that doesn't regress.
71-
//
72-
// The others, however, aren't managing to optimize away the extra `select`s yet.
73-
// See <https://github.com/rust-lang/rust/issues/106107> for more about this.
69+
// These used to not optimize as well, but thanks to LLVM 20 they work now 🎉
7470
//
7571

7672
// CHECK-LABEL: @check_lt_via_cmp
@@ -89,34 +85,34 @@ pub fn check_lt_via_cmp(a: TwoTuple, b: TwoTuple) -> bool {
8985
// CHECK-SAME: (i16 noundef %[[A0:.+]], i16 noundef %[[A1:.+]], i16 noundef %[[B0:.+]], i16 noundef %[[B1:.+]])
9086
#[no_mangle]
9187
pub fn check_le_via_cmp(a: TwoTuple, b: TwoTuple) -> bool {
92-
// FIXME-CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]]
93-
// FIXME-CHECK-DAG: %[[CMP0:.+]] = icmp sle i16 %[[A0]], %[[B0]]
94-
// FIXME-CHECK-DAG: %[[CMP1:.+]] = icmp ule i16 %[[A1]], %[[B1]]
95-
// FIXME-CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]]
96-
// FIXME-CHECK: ret i1 %[[R]]
88+
// CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]]
89+
// CHECK-DAG: %[[CMP0:.+]] = icmp sle i16 %[[A0]], %[[B0]]
90+
// CHECK-DAG: %[[CMP1:.+]] = icmp ule i16 %[[A1]], %[[B1]]
91+
// CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]]
92+
// CHECK: ret i1 %[[R]]
9793
Ord::cmp(&a, &b).is_le()
9894
}
9995

10096
// CHECK-LABEL: @check_gt_via_cmp
10197
// CHECK-SAME: (i16 noundef %[[A0:.+]], i16 noundef %[[A1:.+]], i16 noundef %[[B0:.+]], i16 noundef %[[B1:.+]])
10298
#[no_mangle]
10399
pub fn check_gt_via_cmp(a: TwoTuple, b: TwoTuple) -> bool {
104-
// FIXME-CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]]
105-
// FIXME-CHECK-DAG: %[[CMP0:.+]] = icmp sgt i16 %[[A0]], %[[B0]]
106-
// FIXME-CHECK-DAG: %[[CMP1:.+]] = icmp ugt i16 %[[A1]], %[[B1]]
107-
// FIXME-CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]]
108-
// FIXME-CHECK: ret i1 %[[R]]
100+
// CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]]
101+
// CHECK-DAG: %[[CMP0:.+]] = icmp sgt i16 %[[A0]], %[[B0]]
102+
// CHECK-DAG: %[[CMP1:.+]] = icmp ugt i16 %[[A1]], %[[B1]]
103+
// CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]]
104+
// CHECK: ret i1 %[[R]]
109105
Ord::cmp(&a, &b).is_gt()
110106
}
111107

112108
// CHECK-LABEL: @check_ge_via_cmp
113109
// CHECK-SAME: (i16 noundef %[[A0:.+]], i16 noundef %[[A1:.+]], i16 noundef %[[B0:.+]], i16 noundef %[[B1:.+]])
114110
#[no_mangle]
115111
pub fn check_ge_via_cmp(a: TwoTuple, b: TwoTuple) -> bool {
116-
// FIXME-CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]]
117-
// FIXME-CHECK-DAG: %[[CMP0:.+]] = icmp sge i16 %[[A0]], %[[B0]]
118-
// FIXME-CHECK-DAG: %[[CMP1:.+]] = icmp uge i16 %[[A1]], %[[B1]]
119-
// FIXME-CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]]
120-
// FIXME-CHECK: ret i1 %[[R]]
112+
// CHECK-DAG: %[[EQ:.+]] = icmp eq i16 %[[A0]], %[[B0]]
113+
// CHECK-DAG: %[[CMP0:.+]] = icmp sge i16 %[[A0]], %[[B0]]
114+
// CHECK-DAG: %[[CMP1:.+]] = icmp uge i16 %[[A1]], %[[B1]]
115+
// CHECK: %[[R:.+]] = select i1 %[[EQ]], i1 %[[CMP1]], i1 %[[CMP0]]
116+
// CHECK: ret i1 %[[R]]
121117
Ord::cmp(&a, &b).is_ge()
122118
}

0 commit comments

Comments
 (0)