Rollup merge of #145651 - borsakv:139093, r=cjgillot

Regression test for const promotion with Option<Ordering>

https://rust.godbolt.org/z/EjxqE8WcT

Fixes rust-lang/rust#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
This commit is contained in:
dianqk 2025-10-11 07:05:53 +08:00 committed by GitHub
commit 486fae11ca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 125 additions and 0 deletions

View file

@ -0,0 +1,46 @@
// MIR for `direct` after PreCodegen
fn direct(_1: Option<std::cmp::Ordering>) -> bool {
debug e => _1;
let mut _0: bool;
scope 1 (inlined <Option<std::cmp::Ordering> as PartialEq>::eq) {
let mut _2: isize;
scope 2 {
scope 3 (inlined <std::cmp::Ordering as PartialEq>::eq) {
let _3: i8;
scope 4 {
scope 5 {
}
}
}
}
}
bb0: {
StorageLive(_2);
_2 = discriminant(_1);
switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4];
}
bb1: {
_0 = const false;
goto -> bb3;
}
bb2: {
StorageLive(_3);
_3 = discriminant(((_1 as Some).0: std::cmp::Ordering));
_0 = Eq(copy _3, const 0_i8);
StorageDead(_3);
goto -> bb3;
}
bb3: {
StorageDead(_2);
return;
}
bb4: {
unreachable;
}
}

View file

@ -0,0 +1,30 @@
//@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0
// Check that comparing `Option<Ordering>` to a constant inlined `Some(...)`
// does not produce unnecessarily complex MIR compared to using a local binding.
//
// Regression test for <https://github.com/rust-lang/rust/issues/139093>.
// Originally, inlined constants like `Some(Ordering::Equal)` would get promoted,
// leading to more MIR (and extra LLVM IR checks) than necessary.
// Both cases should now generate identical MIR.
use std::cmp::Ordering;
// EMIT_MIR const_promotion_option_ordering_eq.direct.PreCodegen.after.mir
pub fn direct(e: Option<Ordering>) -> bool {
// CHECK-LABEL: fn direct(
// CHECK-NOT: promoted[
// CHECK: switchInt(
// CHECK: return
e == Some(Ordering::Equal)
}
// EMIT_MIR const_promotion_option_ordering_eq.with_let.PreCodegen.after.mir
pub fn with_let(e: Option<Ordering>) -> bool {
// CHECK-LABEL: fn with_let(
// CHECK-NOT: promoted[
// CHECK: switchInt(
// CHECK: return
let eq = Ordering::Equal;
e == Some(eq)
}

View file

@ -0,0 +1,49 @@
// MIR for `with_let` after PreCodegen
fn with_let(_1: Option<std::cmp::Ordering>) -> bool {
debug e => _1;
let mut _0: bool;
scope 1 {
debug eq => const Equal;
scope 2 (inlined <Option<std::cmp::Ordering> as PartialEq>::eq) {
let mut _2: isize;
scope 3 {
scope 4 (inlined <std::cmp::Ordering as PartialEq>::eq) {
let _3: i8;
scope 5 {
scope 6 {
}
}
}
}
}
}
bb0: {
StorageLive(_2);
_2 = discriminant(_1);
switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4];
}
bb1: {
_0 = const false;
goto -> bb3;
}
bb2: {
StorageLive(_3);
_3 = discriminant(((_1 as Some).0: std::cmp::Ordering));
_0 = Eq(copy _3, const 0_i8);
StorageDead(_3);
goto -> bb3;
}
bb3: {
StorageDead(_2);
return;
}
bb4: {
unreachable;
}
}