Skip to content

Commit 486fae1

Browse files
authored
Rollup merge of #145651 - borsakv:139093, r=cjgillot
Regression test for const promotion with Option<Ordering> https://rust.godbolt.org/z/EjxqE8WcT Fixes #139093 Add a regression test to ensure that comparing `Option<Ordering>` to `Some(Ordering::Equal)` does not trigger unnecessary const promotion in MIR. Previously, inlined constants like `Some(Ordering::Equal)` would get promoted, leading to more complex MIR and redundant LLVM IR checks. This test verifies that both the direct form and the `let`-binding form now generate equivalent, simplified MIR. r? cjgillot
2 parents 9725c4b + c86474c commit 486fae1

File tree

3 files changed

+125
-0
lines changed

3 files changed

+125
-0
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// MIR for `direct` after PreCodegen
2+
3+
fn direct(_1: Option<std::cmp::Ordering>) -> bool {
4+
debug e => _1;
5+
let mut _0: bool;
6+
scope 1 (inlined <Option<std::cmp::Ordering> as PartialEq>::eq) {
7+
let mut _2: isize;
8+
scope 2 {
9+
scope 3 (inlined <std::cmp::Ordering as PartialEq>::eq) {
10+
let _3: i8;
11+
scope 4 {
12+
scope 5 {
13+
}
14+
}
15+
}
16+
}
17+
}
18+
19+
bb0: {
20+
StorageLive(_2);
21+
_2 = discriminant(_1);
22+
switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4];
23+
}
24+
25+
bb1: {
26+
_0 = const false;
27+
goto -> bb3;
28+
}
29+
30+
bb2: {
31+
StorageLive(_3);
32+
_3 = discriminant(((_1 as Some).0: std::cmp::Ordering));
33+
_0 = Eq(copy _3, const 0_i8);
34+
StorageDead(_3);
35+
goto -> bb3;
36+
}
37+
38+
bb3: {
39+
StorageDead(_2);
40+
return;
41+
}
42+
43+
bb4: {
44+
unreachable;
45+
}
46+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0
2+
3+
// Check that comparing `Option<Ordering>` to a constant inlined `Some(...)`
4+
// does not produce unnecessarily complex MIR compared to using a local binding.
5+
//
6+
// Regression test for <https://github.com/rust-lang/rust/issues/139093>.
7+
// Originally, inlined constants like `Some(Ordering::Equal)` would get promoted,
8+
// leading to more MIR (and extra LLVM IR checks) than necessary.
9+
// Both cases should now generate identical MIR.
10+
11+
use std::cmp::Ordering;
12+
13+
// EMIT_MIR const_promotion_option_ordering_eq.direct.PreCodegen.after.mir
14+
pub fn direct(e: Option<Ordering>) -> bool {
15+
// CHECK-LABEL: fn direct(
16+
// CHECK-NOT: promoted[
17+
// CHECK: switchInt(
18+
// CHECK: return
19+
e == Some(Ordering::Equal)
20+
}
21+
22+
// EMIT_MIR const_promotion_option_ordering_eq.with_let.PreCodegen.after.mir
23+
pub fn with_let(e: Option<Ordering>) -> bool {
24+
// CHECK-LABEL: fn with_let(
25+
// CHECK-NOT: promoted[
26+
// CHECK: switchInt(
27+
// CHECK: return
28+
let eq = Ordering::Equal;
29+
e == Some(eq)
30+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// MIR for `with_let` after PreCodegen
2+
3+
fn with_let(_1: Option<std::cmp::Ordering>) -> bool {
4+
debug e => _1;
5+
let mut _0: bool;
6+
scope 1 {
7+
debug eq => const Equal;
8+
scope 2 (inlined <Option<std::cmp::Ordering> as PartialEq>::eq) {
9+
let mut _2: isize;
10+
scope 3 {
11+
scope 4 (inlined <std::cmp::Ordering as PartialEq>::eq) {
12+
let _3: i8;
13+
scope 5 {
14+
scope 6 {
15+
}
16+
}
17+
}
18+
}
19+
}
20+
}
21+
22+
bb0: {
23+
StorageLive(_2);
24+
_2 = discriminant(_1);
25+
switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4];
26+
}
27+
28+
bb1: {
29+
_0 = const false;
30+
goto -> bb3;
31+
}
32+
33+
bb2: {
34+
StorageLive(_3);
35+
_3 = discriminant(((_1 as Some).0: std::cmp::Ordering));
36+
_0 = Eq(copy _3, const 0_i8);
37+
StorageDead(_3);
38+
goto -> bb3;
39+
}
40+
41+
bb3: {
42+
StorageDead(_2);
43+
return;
44+
}
45+
46+
bb4: {
47+
unreachable;
48+
}
49+
}

0 commit comments

Comments
 (0)