diff --git a/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.direct.PreCodegen.after.32bit.mir b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.direct.PreCodegen.after.32bit.mir new file mode 100644 index 0000000000000..66b51ad48e7a5 --- /dev/null +++ b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.direct.PreCodegen.after.32bit.mir @@ -0,0 +1,46 @@ +// MIR for `direct` after PreCodegen + +fn direct(_1: Option) -> bool { + debug e => _1; + let mut _0: bool; + scope 1 (inlined as PartialEq>::eq) { + let mut _2: isize; + scope 2 { + scope 3 (inlined ::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; + } +} diff --git a/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.direct.PreCodegen.after.64bit.mir b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.direct.PreCodegen.after.64bit.mir new file mode 100644 index 0000000000000..66b51ad48e7a5 --- /dev/null +++ b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.direct.PreCodegen.after.64bit.mir @@ -0,0 +1,46 @@ +// MIR for `direct` after PreCodegen + +fn direct(_1: Option) -> bool { + debug e => _1; + let mut _0: bool; + scope 1 (inlined as PartialEq>::eq) { + let mut _2: isize; + scope 2 { + scope 3 (inlined ::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; + } +} diff --git a/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.rs b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.rs new file mode 100644 index 0000000000000..6dca2b3b3d62d --- /dev/null +++ b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.rs @@ -0,0 +1,31 @@ +//@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0 +// EMIT_MIR_FOR_EACH_BIT_WIDTH + +// Check that comparing `Option` to a constant inlined `Some(...)` +// does not produce unnecessarily complex MIR compared to using a local binding. +// +// Regression test for . +// 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) -> 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) -> bool { + // CHECK-LABEL: fn with_let( + // CHECK-NOT: promoted[ + // CHECK: switchInt( + // CHECK: return + let eq = Ordering::Equal; + e == Some(eq) +} diff --git a/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.with_let.PreCodegen.after.32bit.mir b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.with_let.PreCodegen.after.32bit.mir new file mode 100644 index 0000000000000..f089e9ad960bd --- /dev/null +++ b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.with_let.PreCodegen.after.32bit.mir @@ -0,0 +1,49 @@ +// MIR for `with_let` after PreCodegen + +fn with_let(_1: Option) -> bool { + debug e => _1; + let mut _0: bool; + scope 1 { + debug eq => const Equal; + scope 2 (inlined as PartialEq>::eq) { + let mut _2: isize; + scope 3 { + scope 4 (inlined ::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; + } +} diff --git a/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.with_let.PreCodegen.after.64bit.mir b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.with_let.PreCodegen.after.64bit.mir new file mode 100644 index 0000000000000..f089e9ad960bd --- /dev/null +++ b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.with_let.PreCodegen.after.64bit.mir @@ -0,0 +1,49 @@ +// MIR for `with_let` after PreCodegen + +fn with_let(_1: Option) -> bool { + debug e => _1; + let mut _0: bool; + scope 1 { + debug eq => const Equal; + scope 2 (inlined as PartialEq>::eq) { + let mut _2: isize; + scope 3 { + scope 4 (inlined ::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; + } +}