From 5ee964049a9f0808bc0729fad79be446a2a987cb Mon Sep 17 00:00:00 2001 From: dianqk Date: Sat, 10 Jan 2026 18:34:02 +0800 Subject: [PATCH 1/6] Add FileCheck to if_condition_int.rs --- ...t_opt_bool.SimplifyComparisonIntegral.diff | 2 +- ...opt_floats.SimplifyComparisonIntegral.diff | 2 +- ...comparison.SimplifyComparisonIntegral.diff | 18 ++--- ...t.opt_char.SimplifyComparisonIntegral.diff | 4 +- ...int.opt_i8.SimplifyComparisonIntegral.diff | 4 +- ...ltiple_ifs.SimplifyComparisonIntegral.diff | 8 +- ...t_negative.SimplifyComparisonIntegral.diff | 4 +- ...nt.opt_u32.SimplifyComparisonIntegral.diff | 4 +- tests/mir-opt/if_condition_int.rs | 76 ++++++++++++++++--- 9 files changed, 88 insertions(+), 34 deletions(-) diff --git a/tests/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff index 2350faa05d3f..f2d527326592 100644 --- a/tests/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_2); _2 = copy _1; - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + switchInt(copy _1) -> [0: bb2, otherwise: bb1]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff index 94570017730d..c72a58a145f4 100644 --- a/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff @@ -11,7 +11,7 @@ StorageLive(_2); StorageLive(_3); _3 = copy _1; - _2 = Eq(move _3, const -42f32); + _2 = Eq(copy _1, const -42f32); switchInt(move _2) -> [0: bb2, otherwise: bb1]; } diff --git a/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff index d19b4148405e..29d57722355b 100644 --- a/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff @@ -15,23 +15,20 @@ } bb0: { - StorageLive(_2); + nop; StorageLive(_3); _3 = copy _1; -- _2 = Eq(move _3, const 17_i8); -- StorageDead(_3); + _2 = Eq(copy _1, const 17_i8); + StorageDead(_3); - switchInt(copy _2) -> [0: bb2, otherwise: bb1]; -+ _2 = Eq(copy _3, const 17_i8); -+ nop; -+ switchInt(move _3) -> [17: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [17: bb1, otherwise: bb2]; } bb1: { -+ StorageDead(_3); StorageLive(_6); StorageLive(_7); _7 = copy _2; - _6 = move _7 as i32 (IntToInt); + _6 = copy _2 as i32 (IntToInt); StorageDead(_7); _0 = Add(const 100_i32, move _6); StorageDead(_6); @@ -39,11 +36,10 @@ } bb2: { -+ StorageDead(_3); StorageLive(_4); StorageLive(_5); _5 = copy _2; - _4 = move _5 as i32 (IntToInt); + _4 = copy _2 as i32 (IntToInt); StorageDead(_5); _0 = Add(const 10_i32, move _4); StorageDead(_4); @@ -51,7 +47,7 @@ } bb3: { - StorageDead(_2); + nop; return; } } diff --git a/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff index e47b7e522598..37b41c2aa5ab 100644 --- a/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff @@ -11,10 +11,10 @@ StorageLive(_2); StorageLive(_3); _3 = copy _1; -- _2 = Eq(move _3, const 'x'); +- _2 = Eq(copy _1, const 'x'); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ switchInt(move _3) -> [120: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [120: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff index b6cdc6af8bf4..c92a606090e4 100644 --- a/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff @@ -11,10 +11,10 @@ StorageLive(_2); StorageLive(_3); _3 = copy _1; -- _2 = Eq(move _3, const 42_i8); +- _2 = Eq(copy _1, const 42_i8); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ switchInt(move _3) -> [42: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [42: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff index 31745ac732a2..a73670323b1f 100644 --- a/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff @@ -13,10 +13,10 @@ StorageLive(_2); StorageLive(_3); _3 = copy _1; -- _2 = Eq(move _3, const 42_u32); +- _2 = Eq(copy _1, const 42_u32); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ switchInt(move _3) -> [42: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [42: bb1, otherwise: bb2]; } bb1: { @@ -30,10 +30,10 @@ StorageLive(_4); StorageLive(_5); _5 = copy _1; -- _4 = Ne(move _5, const 21_u32); +- _4 = Ne(copy _1, const 21_u32); - switchInt(move _4) -> [0: bb4, otherwise: bb3]; + nop; -+ switchInt(move _5) -> [21: bb4, otherwise: bb3]; ++ switchInt(move _1) -> [21: bb4, otherwise: bb3]; } bb3: { diff --git a/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff index d747985f6e13..36145ab02bea 100644 --- a/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff @@ -11,10 +11,10 @@ StorageLive(_2); StorageLive(_3); _3 = copy _1; -- _2 = Eq(move _3, const -42_i32); +- _2 = Eq(copy _1, const -42_i32); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ switchInt(move _3) -> [4294967254: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [4294967254: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff index 1d6809a9438a..2cc4a8b76973 100644 --- a/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff @@ -11,10 +11,10 @@ StorageLive(_2); StorageLive(_3); _3 = copy _1; -- _2 = Eq(move _3, const 42_u32); +- _2 = Eq(copy _1, const 42_u32); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ switchInt(move _3) -> [42: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [42: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.rs b/tests/mir-opt/if_condition_int.rs index 4cc2c2b90210..24ef6b85529e 100644 --- a/tests/mir-opt/if_condition_int.rs +++ b/tests/mir-opt/if_condition_int.rs @@ -1,36 +1,76 @@ -// skip-filecheck //@ test-mir-pass: SimplifyComparisonIntegral -// EMIT_MIR if_condition_int.opt_u32.SimplifyComparisonIntegral.diff -// EMIT_MIR if_condition_int.opt_negative.SimplifyComparisonIntegral.diff -// EMIT_MIR if_condition_int.opt_char.SimplifyComparisonIntegral.diff -// EMIT_MIR if_condition_int.opt_i8.SimplifyComparisonIntegral.diff -// EMIT_MIR if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff -// EMIT_MIR if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff -// EMIT_MIR if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff -// EMIT_MIR if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff +// GVN simplifies FileCheck. +//@ compile-flags: -Zmir-enable-passes=+GVN +// EMIT_MIR if_condition_int.opt_u32.SimplifyComparisonIntegral.diff fn opt_u32(x: u32) -> u32 { + // CHECK-LABEL: fn opt_u32( + // FIXME: This should be copy. + // CHECK: switchInt(move _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_u32; + // CHECK: [[BB2]]: + // CHECK: _0 = const 1_u32; if x == 42 { 0 } else { 1 } } +// EMIT_MIR if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff // don't opt: it is already optimal to switch on the bool fn dont_opt_bool(x: bool) -> u32 { + // CHECK-LABEL: fn dont_opt_bool( + // CHECK: switchInt(copy _1) -> [0: [[BB2:bb.*]], otherwise: [[BB1:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_u32; + // CHECK: [[BB2]]: + // CHECK: _0 = const 1_u32; if x { 0 } else { 1 } } +// EMIT_MIR if_condition_int.opt_char.SimplifyComparisonIntegral.diff fn opt_char(x: char) -> u32 { + // CHECK-LABEL: fn opt_char( + // CHECK: switchInt(move _1) -> [120: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_u32; + // CHECK: [[BB2]]: + // CHECK: _0 = const 1_u32; if x == 'x' { 0 } else { 1 } } +// EMIT_MIR if_condition_int.opt_i8.SimplifyComparisonIntegral.diff fn opt_i8(x: i8) -> u32 { + // CHECK-LABEL: fn opt_i8( + // CHECK: switchInt(move _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_u32; + // CHECK: [[BB2]]: + // CHECK: _0 = const 1_u32; if x == 42 { 0 } else { 1 } } +// EMIT_MIR if_condition_int.opt_negative.SimplifyComparisonIntegral.diff fn opt_negative(x: i32) -> u32 { + // CHECK-LABEL: fn opt_negative( + // CHECK: switchInt(move _1) -> [4294967254: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_u32; + // CHECK: [[BB2]]: + // CHECK: _0 = const 1_u32; if x == -42 { 0 } else { 1 } } +// EMIT_MIR if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff fn opt_multiple_ifs(x: u32) -> u32 { + // CHECK-LABEL: fn opt_multiple_ifs( + // CHECK: switchInt(move _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_u32; + // CHECK: [[BB2]]: + // CHECK: switchInt(move _1) -> [21: [[BB4:bb.*]], otherwise: [[BB3:bb.*]]]; + // CHECK: [[BB3]]: + // CHECK: _0 = const 1_u32; + // CHECK: [[BB4]]: + // CHECK: _0 = const 2_u32; if x == 42 { 0 } else if x != 21 { @@ -40,8 +80,18 @@ fn opt_multiple_ifs(x: u32) -> u32 { } } +// EMIT_MIR if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff // test that we optimize, but do not remove the b statement, as that is used later on fn dont_remove_comparison(a: i8) -> i32 { + // CHECK-LABEL: fn dont_remove_comparison( + // CHECK: [[b:_.*]] = Eq(copy _1, const 17_i8); + // CHECK: switchInt(move _1) -> [17: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: [[cast_1:_.*]] = copy [[b]] as i32 (IntToInt); + // CHECK: _0 = Add(const 100_i32, move [[cast_1]]); + // CHECK: [[BB2]]: + // CHECK: [[cast_2:_.*]] = copy [[b]] as i32 (IntToInt); + // CHECK: _0 = Add(const 10_i32, move [[cast_2]]); let b = a == 17; match b { false => 10 + b as i32, @@ -49,8 +99,16 @@ fn dont_remove_comparison(a: i8) -> i32 { } } +// EMIT_MIR if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff // test that we do not optimize on floats fn dont_opt_floats(a: f32) -> i32 { + // CHECK-LABEL: fn dont_opt_floats( + // CHECK: [[cmp:_.*]] = Eq(copy _1, const -42f32); + // CHECK: switchInt(move [[cmp]]) -> [0: [[BB2:bb.*]], otherwise: [[BB1:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_i32; + // CHECK: [[BB2]]: + // CHECK: _0 = const 1_i32; if a == -42.0 { 0 } else { 1 } } From 528fd2a33057644dd3aca50d04a626e4b1527948 Mon Sep 17 00:00:00 2001 From: dianqk Date: Sat, 10 Jan 2026 18:45:33 +0800 Subject: [PATCH 2/6] Add miscompiled test cases --- ...on_ssa_cmp.SimplifyComparisonIntegral.diff | 25 ++++++ ..._ssa_place.SimplifyComparisonIntegral.diff | 25 ++++++ ...ssa_switch.SimplifyComparisonIntegral.diff | 25 ++++++ tests/mir-opt/if_condition_int.rs | 81 +++++++++++++++++++ 4 files changed, 156 insertions(+) create mode 100644 tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff create mode 100644 tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff create mode 100644 tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff diff --git a/tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000000..d0983c660623 --- /dev/null +++ b/tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff @@ -0,0 +1,25 @@ +- // MIR for `on_non_ssa_cmp` before SimplifyComparisonIntegral ++ // MIR for `on_non_ssa_cmp` after SimplifyComparisonIntegral + + fn on_non_ssa_cmp(_1: u64) -> i32 { + let mut _0: i32; + let mut _2: bool; + + bb0: { + _2 = Eq(copy _1, const 42_u64); + _1 = const 43_u64; +- switchInt(copy _2) -> [1: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [42: bb1, otherwise: bb2]; + } + + bb1: { + _0 = const 0_i32; + return; + } + + bb2: { + _0 = const 1_i32; + return; + } + } + diff --git a/tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000000..0c6c8dca4753 --- /dev/null +++ b/tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff @@ -0,0 +1,25 @@ +- // MIR for `on_non_ssa_place` before SimplifyComparisonIntegral ++ // MIR for `on_non_ssa_place` after SimplifyComparisonIntegral + + fn on_non_ssa_place(_1: [u64; 10], _2: usize) -> i32 { + let mut _0: i32; + let mut _3: bool; + + bb0: { + _3 = Eq(copy _1[_2], const 42_u64); + _2 = const 10_usize; +- switchInt(copy _3) -> [1: bb1, otherwise: bb2]; ++ switchInt(move _1[_2]) -> [42: bb1, otherwise: bb2]; + } + + bb1: { + _0 = const 0_i32; + return; + } + + bb2: { + _0 = const 1_i32; + return; + } + } + diff --git a/tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000000..b1b1ab2c2205 --- /dev/null +++ b/tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff @@ -0,0 +1,25 @@ +- // MIR for `on_non_ssa_switch` before SimplifyComparisonIntegral ++ // MIR for `on_non_ssa_switch` after SimplifyComparisonIntegral + + fn on_non_ssa_switch(_1: u64) -> i32 { + let mut _0: i32; + let mut _2: bool; + + bb0: { + _2 = Eq(copy _1, const 42_u64); + _2 = const false; +- switchInt(copy _2) -> [1: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [42: bb1, otherwise: bb2]; + } + + bb1: { + _0 = const 0_i32; + return; + } + + bb2: { + _0 = const 1_i32; + return; + } + } + diff --git a/tests/mir-opt/if_condition_int.rs b/tests/mir-opt/if_condition_int.rs index 24ef6b85529e..ba901f6b9b15 100644 --- a/tests/mir-opt/if_condition_int.rs +++ b/tests/mir-opt/if_condition_int.rs @@ -2,6 +2,11 @@ // GVN simplifies FileCheck. //@ compile-flags: -Zmir-enable-passes=+GVN +#![feature(custom_mir, core_intrinsics)] + +extern crate core; +use core::intrinsics::mir::*; + // EMIT_MIR if_condition_int.opt_u32.SimplifyComparisonIntegral.diff fn opt_u32(x: u32) -> u32 { // CHECK-LABEL: fn opt_u32( @@ -112,6 +117,81 @@ fn dont_opt_floats(a: f32) -> i32 { if a == -42.0 { 0 } else { 1 } } +// EMIT_MIR if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff +#[custom_mir(dialect = "runtime")] +pub fn on_non_ssa_switch(mut v: u64) -> i32 { + mir! { + let a: bool; + { + a = v == 42; + a = false; + match a { + true => bb1, + _ => bb2, + } + + } + bb1 = { + RET = 0; + Return() + } + bb2 = { + RET = 1; + Return() + } + } +} + +// EMIT_MIR if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff +#[custom_mir(dialect = "runtime")] +pub fn on_non_ssa_cmp(mut v: u64) -> i32 { + mir! { + let a: bool; + { + a = v == 42; + v = 43; + match a { + true => bb1, + _ => bb2, + } + + } + bb1 = { + RET = 0; + Return() + } + bb2 = { + RET = 1; + Return() + } + } +} + +// EMIT_MIR if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff +#[custom_mir(dialect = "runtime")] +pub fn on_non_ssa_place(mut v: [u64; 10], mut i: usize) -> i32 { + mir! { + let a: bool; + { + a = v[i] == 42; + i = 10; + match a { + true => bb1, + _ => bb2, + } + + } + bb1 = { + RET = 0; + Return() + } + bb2 = { + RET = 1; + Return() + } + } +} + fn main() { opt_u32(0); opt_char('0'); @@ -121,4 +201,5 @@ fn main() { opt_multiple_ifs(0); dont_remove_comparison(11); dont_opt_floats(1.0); + on_non_ssa_switch(42); } From ac80ccec5f5999e7251474380661be5a84e56683 Mon Sep 17 00:00:00 2001 From: dianqk Date: Sat, 10 Jan 2026 20:10:18 +0800 Subject: [PATCH 3/6] Only use SSA locals in SimplifyComparisonIntegral --- compiler/rustc_middle/src/mir/statement.rs | 6 ++++ .../src/simplify_comparison_integral.rs | 31 ++++++++++++------- ...on_ssa_cmp.SimplifyComparisonIntegral.diff | 3 +- ..._ssa_place.SimplifyComparisonIntegral.diff | 3 +- ...ssa_switch.SimplifyComparisonIntegral.diff | 3 +- tests/mir-opt/if_condition_int.rs | 24 ++++++++++++++ 6 files changed, 52 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index c1f8c46baddb..adaac3d7ffc2 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -374,6 +374,12 @@ impl<'tcx> Place<'tcx> { self.projection.iter().any(|elem| elem.is_indirect()) } + /// Returns `true` if the `Place` always refers to the same memory region + /// whatever the state of the program. + pub fn is_stable_offset(&self) -> bool { + self.projection.iter().all(|elem| elem.is_stable_offset()) + } + /// Returns `true` if this `Place`'s first projection is `Deref`. /// /// This is useful because for MIR phases `AnalysisPhase::PostCleanup` and later, diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index 2643d78990e5..53a796b1179a 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -9,6 +9,8 @@ use rustc_middle::mir::{ use rustc_middle::ty::{Ty, TyCtxt}; use tracing::trace; +use crate::ssa::SsaLocals; + /// Pass to convert `if` conditions on integrals into switches on the integral. /// For an example, it turns something like /// @@ -33,11 +35,12 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { trace!("Running SimplifyComparisonIntegral on {:?}", body.source); + let typing_env = body.typing_env(tcx); + let ssa = SsaLocals::new(tcx, body, typing_env); let helper = OptimizationFinder { body }; - let opts = helper.find_optimizations(); + let opts = helper.find_optimizations(&ssa); let mut storage_deads_to_insert = vec![]; let mut storage_deads_to_remove: Vec<(usize, BasicBlock)> = vec![]; - let typing_env = body.typing_env(tcx); for opt in opts { trace!("SUCCESS: Applying {:?}", opt); // replace terminator with a switchInt that switches on the integer directly @@ -154,19 +157,18 @@ struct OptimizationFinder<'a, 'tcx> { } impl<'tcx> OptimizationFinder<'_, 'tcx> { - fn find_optimizations(&self) -> Vec> { + fn find_optimizations(&self, ssa: &SsaLocals) -> Vec> { self.body .basic_blocks .iter_enumerated() .filter_map(|(bb_idx, bb)| { // find switch - let (place_switched_on, targets, place_switched_on_moved) = - match &bb.terminator().kind { - rustc_middle::mir::TerminatorKind::SwitchInt { discr, targets, .. } => { - Some((discr.place()?, targets, discr.is_move())) - } - _ => None, - }?; + let (discr, targets) = bb.terminator().kind.as_switch()?; + let place_switched_on = discr.place()?; + // Make sure that the place is not modified. + if !ssa.is_ssa(place_switched_on.local) || !place_switched_on.is_stable_offset() { + return None; + } // find the statement that assigns the place being switched on bb.statements.iter().enumerate().rev().find_map(|(stmt_idx, stmt)| { @@ -180,12 +182,12 @@ impl<'tcx> OptimizationFinder<'_, 'tcx> { box (left, right), ) => { let (branch_value_scalar, branch_value_ty, to_switch_on) = - find_branch_value_info(left, right)?; + find_branch_value_info(left, right, ssa)?; Some(OptimizationInfo { bin_op_stmt_idx: stmt_idx, bb_idx, - can_remove_bin_op_stmt: place_switched_on_moved, + can_remove_bin_op_stmt: discr.is_move(), to_switch_on, branch_value_scalar, branch_value_ty, @@ -207,6 +209,7 @@ impl<'tcx> OptimizationFinder<'_, 'tcx> { fn find_branch_value_info<'tcx>( left: &Operand<'tcx>, right: &Operand<'tcx>, + ssa: &SsaLocals, ) -> Option<(Scalar, Ty<'tcx>, Place<'tcx>)> { // check that either left or right is a constant. // if any are, we can use the other to switch on, and the constant as a value in a switch @@ -214,6 +217,10 @@ fn find_branch_value_info<'tcx>( match (left, right) { (Constant(branch_value), Copy(to_switch_on) | Move(to_switch_on)) | (Copy(to_switch_on) | Move(to_switch_on), Constant(branch_value)) => { + // Make sure that the place is not modified. + if !ssa.is_ssa(to_switch_on.local) || !to_switch_on.is_stable_offset() { + return None; + } let branch_value_ty = branch_value.const_.ty(); // we only want to apply this optimization if we are matching on integrals (and chars), // as it is not possible to switch on floats diff --git a/tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff index d0983c660623..ce5a2bf172a9 100644 --- a/tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff @@ -8,8 +8,7 @@ bb0: { _2 = Eq(copy _1, const 42_u64); _1 = const 43_u64; -- switchInt(copy _2) -> [1: bb1, otherwise: bb2]; -+ switchInt(move _1) -> [42: bb1, otherwise: bb2]; + switchInt(copy _2) -> [1: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff index 0c6c8dca4753..7ad0a87f1cdd 100644 --- a/tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff @@ -8,8 +8,7 @@ bb0: { _3 = Eq(copy _1[_2], const 42_u64); _2 = const 10_usize; -- switchInt(copy _3) -> [1: bb1, otherwise: bb2]; -+ switchInt(move _1[_2]) -> [42: bb1, otherwise: bb2]; + switchInt(copy _3) -> [1: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff index b1b1ab2c2205..e2dc97f76b5c 100644 --- a/tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff @@ -8,8 +8,7 @@ bb0: { _2 = Eq(copy _1, const 42_u64); _2 = const false; -- switchInt(copy _2) -> [1: bb1, otherwise: bb2]; -+ switchInt(move _1) -> [42: bb1, otherwise: bb2]; + switchInt(copy _2) -> [1: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.rs b/tests/mir-opt/if_condition_int.rs index ba901f6b9b15..b49f8768253a 100644 --- a/tests/mir-opt/if_condition_int.rs +++ b/tests/mir-opt/if_condition_int.rs @@ -120,6 +120,14 @@ fn dont_opt_floats(a: f32) -> i32 { // EMIT_MIR if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff #[custom_mir(dialect = "runtime")] pub fn on_non_ssa_switch(mut v: u64) -> i32 { + // CHECK-LABEL: fn on_non_ssa_switch( + // CHECK: [[cmp:_.*]] = Eq(copy _1, const 42_u64); + // CHECK: [[cmp]] = const false; + // CHECK: switchInt(copy [[cmp]]) -> [1: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_i32; + // CHECK: [[BB2]]: + // CHECK: _0 = const 1_i32; mir! { let a: bool; { @@ -145,6 +153,14 @@ pub fn on_non_ssa_switch(mut v: u64) -> i32 { // EMIT_MIR if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff #[custom_mir(dialect = "runtime")] pub fn on_non_ssa_cmp(mut v: u64) -> i32 { + // CHECK-LABEL: fn on_non_ssa_cmp( + // CHECK: [[cmp:_.*]] = Eq(copy _1, const 42_u64); + // CHECK: _1 = const 43_u64; + // CHECK: switchInt(copy [[cmp]]) -> [1: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_i32; + // CHECK: [[BB2]]: + // CHECK: _0 = const 1_i32; mir! { let a: bool; { @@ -170,6 +186,14 @@ pub fn on_non_ssa_cmp(mut v: u64) -> i32 { // EMIT_MIR if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff #[custom_mir(dialect = "runtime")] pub fn on_non_ssa_place(mut v: [u64; 10], mut i: usize) -> i32 { + // CHECK-LABEL: fn on_non_ssa_place( + // CHECK: [[cmp:_.*]] = Eq(copy _1[_2], const 42_u64); + // CHECK: _2 = const 10_usize; + // CHECK: switchInt(copy [[cmp]]) -> [1: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_i32; + // CHECK: [[BB2]]: + // CHECK: _0 = const 1_i32; mir! { let a: bool; { From 37f83fb11d187aea102340b1be20f3f65c4c2cac Mon Sep 17 00:00:00 2001 From: dianqk Date: Sat, 10 Jan 2026 20:27:08 +0800 Subject: [PATCH 4/6] Use Copy in the SwitchInt terminator Move can be used only when both the compared operand and the operand on switch are move operands. This commit directly changes to Copy, because I don't know if Move has beneficial. --- .../src/simplify_comparison_integral.rs | 2 +- ..._exponential_common.GVN.32bit.panic-abort.diff | 2 +- ...exponential_common.GVN.32bit.panic-unwind.diff | 2 +- ..._exponential_common.GVN.64bit.panic-abort.diff | 2 +- ...exponential_common.GVN.64bit.panic-unwind.diff | 2 +- ...ove_comparison.SimplifyComparisonIntegral.diff | 2 +- ...n_int.opt_char.SimplifyComparisonIntegral.diff | 2 +- ...ion_int.opt_i8.SimplifyComparisonIntegral.diff | 2 +- ...t_multiple_ifs.SimplifyComparisonIntegral.diff | 4 ++-- ...t.opt_negative.SimplifyComparisonIntegral.diff | 2 +- ...on_int.opt_u32.SimplifyComparisonIntegral.diff | 2 +- tests/mir-opt/if_condition_int.rs | 15 +++++++-------- ...o_digit.PreCodegen.after.32bit.panic-abort.mir | 2 +- ..._digit.PreCodegen.after.32bit.panic-unwind.mir | 2 +- ...o_digit.PreCodegen.after.64bit.panic-abort.mir | 2 +- ..._digit.PreCodegen.after.64bit.panic-unwind.mir | 2 +- 16 files changed, 23 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index 53a796b1179a..b7445a0f7c2e 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -135,7 +135,7 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral { let terminator = bb.terminator_mut(); terminator.kind = - TerminatorKind::SwitchInt { discr: Operand::Move(opt.to_switch_on), targets }; + TerminatorKind::SwitchInt { discr: Operand::Copy(opt.to_switch_on), targets }; } for (idx, bb_idx) in storage_deads_to_remove { diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff index 6baa902b6f4b..2b77aa380a0f 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff @@ -74,7 +74,7 @@ _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG); StorageDead(_23); - switchInt(move _22) -> [0: bb10, otherwise: bb11]; + switchInt(copy _22) -> [0: bb10, otherwise: bb11]; } bb4: { diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff index 36540e038654..ba6d2f3e155c 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff @@ -74,7 +74,7 @@ _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG); StorageDead(_23); - switchInt(move _22) -> [0: bb10, otherwise: bb11]; + switchInt(copy _22) -> [0: bb10, otherwise: bb11]; } bb4: { diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff index 41c350f3eaeb..bf6d9d864d57 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff @@ -74,7 +74,7 @@ _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG); StorageDead(_23); - switchInt(move _22) -> [0: bb10, otherwise: bb11]; + switchInt(copy _22) -> [0: bb10, otherwise: bb11]; } bb4: { diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff index b839bf81eaf4..01c87fd5317a 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff @@ -74,7 +74,7 @@ _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG); StorageDead(_23); - switchInt(move _22) -> [0: bb10, otherwise: bb11]; + switchInt(copy _22) -> [0: bb10, otherwise: bb11]; } bb4: { diff --git a/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff index 29d57722355b..f5f2e0317ead 100644 --- a/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff @@ -21,7 +21,7 @@ _2 = Eq(copy _1, const 17_i8); StorageDead(_3); - switchInt(copy _2) -> [0: bb2, otherwise: bb1]; -+ switchInt(move _1) -> [17: bb1, otherwise: bb2]; ++ switchInt(copy _1) -> [17: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff index 37b41c2aa5ab..22f6443a6c0f 100644 --- a/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff @@ -14,7 +14,7 @@ - _2 = Eq(copy _1, const 'x'); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ switchInt(move _1) -> [120: bb1, otherwise: bb2]; ++ switchInt(copy _1) -> [120: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff index c92a606090e4..d5c48fd04ca6 100644 --- a/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff @@ -14,7 +14,7 @@ - _2 = Eq(copy _1, const 42_i8); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ switchInt(move _1) -> [42: bb1, otherwise: bb2]; ++ switchInt(copy _1) -> [42: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff index a73670323b1f..84d62b813607 100644 --- a/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff @@ -16,7 +16,7 @@ - _2 = Eq(copy _1, const 42_u32); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ switchInt(move _1) -> [42: bb1, otherwise: bb2]; ++ switchInt(copy _1) -> [42: bb1, otherwise: bb2]; } bb1: { @@ -33,7 +33,7 @@ - _4 = Ne(copy _1, const 21_u32); - switchInt(move _4) -> [0: bb4, otherwise: bb3]; + nop; -+ switchInt(move _1) -> [21: bb4, otherwise: bb3]; ++ switchInt(copy _1) -> [21: bb4, otherwise: bb3]; } bb3: { diff --git a/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff index 36145ab02bea..a1cbaff796b3 100644 --- a/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff @@ -14,7 +14,7 @@ - _2 = Eq(copy _1, const -42_i32); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ switchInt(move _1) -> [4294967254: bb1, otherwise: bb2]; ++ switchInt(copy _1) -> [4294967254: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff index 2cc4a8b76973..8101de8cbf38 100644 --- a/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff @@ -14,7 +14,7 @@ - _2 = Eq(copy _1, const 42_u32); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ switchInt(move _1) -> [42: bb1, otherwise: bb2]; ++ switchInt(copy _1) -> [42: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.rs b/tests/mir-opt/if_condition_int.rs index b49f8768253a..5e0961da3cce 100644 --- a/tests/mir-opt/if_condition_int.rs +++ b/tests/mir-opt/if_condition_int.rs @@ -10,8 +10,7 @@ use core::intrinsics::mir::*; // EMIT_MIR if_condition_int.opt_u32.SimplifyComparisonIntegral.diff fn opt_u32(x: u32) -> u32 { // CHECK-LABEL: fn opt_u32( - // FIXME: This should be copy. - // CHECK: switchInt(move _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: switchInt(copy _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; // CHECK: [[BB1]]: // CHECK: _0 = const 0_u32; // CHECK: [[BB2]]: @@ -34,7 +33,7 @@ fn dont_opt_bool(x: bool) -> u32 { // EMIT_MIR if_condition_int.opt_char.SimplifyComparisonIntegral.diff fn opt_char(x: char) -> u32 { // CHECK-LABEL: fn opt_char( - // CHECK: switchInt(move _1) -> [120: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: switchInt(copy _1) -> [120: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; // CHECK: [[BB1]]: // CHECK: _0 = const 0_u32; // CHECK: [[BB2]]: @@ -45,7 +44,7 @@ fn opt_char(x: char) -> u32 { // EMIT_MIR if_condition_int.opt_i8.SimplifyComparisonIntegral.diff fn opt_i8(x: i8) -> u32 { // CHECK-LABEL: fn opt_i8( - // CHECK: switchInt(move _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: switchInt(copy _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; // CHECK: [[BB1]]: // CHECK: _0 = const 0_u32; // CHECK: [[BB2]]: @@ -56,7 +55,7 @@ fn opt_i8(x: i8) -> u32 { // EMIT_MIR if_condition_int.opt_negative.SimplifyComparisonIntegral.diff fn opt_negative(x: i32) -> u32 { // CHECK-LABEL: fn opt_negative( - // CHECK: switchInt(move _1) -> [4294967254: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: switchInt(copy _1) -> [4294967254: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; // CHECK: [[BB1]]: // CHECK: _0 = const 0_u32; // CHECK: [[BB2]]: @@ -67,11 +66,11 @@ fn opt_negative(x: i32) -> u32 { // EMIT_MIR if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff fn opt_multiple_ifs(x: u32) -> u32 { // CHECK-LABEL: fn opt_multiple_ifs( - // CHECK: switchInt(move _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: switchInt(copy _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; // CHECK: [[BB1]]: // CHECK: _0 = const 0_u32; // CHECK: [[BB2]]: - // CHECK: switchInt(move _1) -> [21: [[BB4:bb.*]], otherwise: [[BB3:bb.*]]]; + // CHECK: switchInt(copy _1) -> [21: [[BB4:bb.*]], otherwise: [[BB3:bb.*]]]; // CHECK: [[BB3]]: // CHECK: _0 = const 1_u32; // CHECK: [[BB4]]: @@ -90,7 +89,7 @@ fn opt_multiple_ifs(x: u32) -> u32 { fn dont_remove_comparison(a: i8) -> i32 { // CHECK-LABEL: fn dont_remove_comparison( // CHECK: [[b:_.*]] = Eq(copy _1, const 17_i8); - // CHECK: switchInt(move _1) -> [17: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: switchInt(copy _1) -> [17: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; // CHECK: [[BB1]]: // CHECK: [[cast_1:_.*]] = copy [[b]] as i32 (IntToInt); // CHECK: _0 = Add(const 100_i32, move [[cast_1]]); diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir index b5c23822162c..f3c83f62edf6 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir @@ -28,7 +28,7 @@ fn num_to_digit(_1: char) -> u32 { StorageLive(_3); _3 = discriminant(_2); StorageDead(_2); - switchInt(move _3) -> [1: bb2, otherwise: bb7]; + switchInt(copy _3) -> [1: bb2, otherwise: bb7]; } bb2: { diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir index f22b8835735d..0e55df24cc57 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir @@ -28,7 +28,7 @@ fn num_to_digit(_1: char) -> u32 { StorageLive(_3); _3 = discriminant(_2); StorageDead(_2); - switchInt(move _3) -> [1: bb2, otherwise: bb7]; + switchInt(copy _3) -> [1: bb2, otherwise: bb7]; } bb2: { diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir index b5c23822162c..f3c83f62edf6 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir @@ -28,7 +28,7 @@ fn num_to_digit(_1: char) -> u32 { StorageLive(_3); _3 = discriminant(_2); StorageDead(_2); - switchInt(move _3) -> [1: bb2, otherwise: bb7]; + switchInt(copy _3) -> [1: bb2, otherwise: bb7]; } bb2: { diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir index f22b8835735d..0e55df24cc57 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir @@ -28,7 +28,7 @@ fn num_to_digit(_1: char) -> u32 { StorageLive(_3); _3 = discriminant(_2); StorageDead(_2); - switchInt(move _3) -> [1: bb2, otherwise: bb7]; + switchInt(copy _3) -> [1: bb2, otherwise: bb7]; } bb2: { From 3b1756fbf56fcfede8ac2c1d877ddd1e8a88be8c Mon Sep 17 00:00:00 2001 From: dianqk Date: Sun, 11 Jan 2026 18:10:05 +0800 Subject: [PATCH 5/6] Run SimplifyComparisonIntegral with opt-level 2 --- .../rustc_mir_transform/src/simplify_comparison_integral.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index b7445a0f7c2e..58b5e45672a2 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -29,7 +29,7 @@ pub(super) struct SimplifyComparisonIntegral; impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.mir_opt_level() > 0 + sess.mir_opt_level() > 1 } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { From 5769006794df86e3a27fedbc5317f695c0f153e6 Mon Sep 17 00:00:00 2001 From: dianqk Date: Wed, 14 Jan 2026 18:57:17 +0800 Subject: [PATCH 6/6] Run dummy_span.rs test with SimplifyComparisonIntegral --- tests/debuginfo/dummy_span.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/debuginfo/dummy_span.rs b/tests/debuginfo/dummy_span.rs index fec4f33e3d56..6cf79c46d9a9 100644 --- a/tests/debuginfo/dummy_span.rs +++ b/tests/debuginfo/dummy_span.rs @@ -1,6 +1,8 @@ //@ min-lldb-version: 310 //@ compile-flags:-g +// FIXME: Investigate why test fails without SimplifyComparisonIntegral pass. +//@ compile-flags: -Zmir-enable-passes=+SimplifyComparisonIntegral //@ ignore-backends: gcc // === GDB TESTS ===================================================================================