diff --git a/compiler/rustc_mir/src/transform/instcombine.rs b/compiler/rustc_mir/src/transform/instcombine.rs index 3ed0aea1404d4..b69bef18c5fea 100644 --- a/compiler/rustc_mir/src/transform/instcombine.rs +++ b/compiler/rustc_mir/src/transform/instcombine.rs @@ -4,6 +4,7 @@ use crate::transform::{MirPass, MirSource}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::Mutability; use rustc_index::vec::Idx; +use rustc_middle::mir::UnOp; use rustc_middle::mir::{ visit::PlaceContext, visit::{MutVisitor, Visitor}, @@ -14,6 +15,7 @@ use rustc_middle::mir::{ Rvalue, }; use rustc_middle::ty::{self, TyCtxt}; +use smallvec::SmallVec; use std::mem; pub struct InstCombine; @@ -29,8 +31,30 @@ impl<'tcx> MirPass<'tcx> for InstCombine { optimization_finder.optimizations }; + // Since eq_not has elements removed in the visitor, we clone it here, + // such that we can still do the post visitor cleanup. + let clone_eq_not = optimizations.eq_not.clone(); // Then carry out those optimizations. MutVisitor::visit_body(&mut InstCombineVisitor { optimizations, tcx }, body); + eq_not_post_visitor_mutations(body, clone_eq_not); + } +} + +fn eq_not_post_visitor_mutations<'tcx>( + body: &mut Body<'tcx>, + eq_not_opts: FxHashMap>, +) { + for (location, eq_not_opt_info) in eq_not_opts.iter() { + let statements = &mut body.basic_blocks_mut()[location.block].statements; + // We have to make sure that Ne is before any StorageDead as the operand being killed is used in the Ne + if let Some(storage_dead_idx_to_swap_with) = + eq_not_opt_info.storage_dead_idx_to_swap_with_ne + { + statements.swap(location.statement_index, storage_dead_idx_to_swap_with); + } + if let Some(eq_stmt_idx) = eq_not_opt_info.can_remove_eq { + statements[eq_stmt_idx].make_nop(); + } } } @@ -81,6 +105,11 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> { *rvalue = Rvalue::Use(Operand::Copy(place)); } + if let Some(eq_not_opt_info) = self.optimizations.eq_not.remove(&location) { + *rvalue = Rvalue::BinaryOp(BinOp::Ne, eq_not_opt_info.op1, eq_not_opt_info.op2); + debug!("replacing Eq and Not with {:?}", rvalue); + } + self.super_rvalue(rvalue, location) } } @@ -221,6 +250,99 @@ impl OptimizationFinder<'b, 'tcx> { } } + fn find_eq_not(&mut self, rvalue: &Rvalue<'tcx>, location: Location) -> Option<()> { + // Optimize the sequence + // _4 = Eq(move _5, const 2_u8); + // StorageDead(_5); + // _3 = Not(move _4); + // + // into _3 = Ne(move _5, const 2_u8) + if let Rvalue::UnaryOp(UnOp::Not, op) = rvalue { + let place = op.place()?; + // See if we can find a Eq that assigns `place`. + // We limit the search to 3 statements lookback. + // Usually the first 2 statements are `StorageDead`s for operands for Eq. + // We record what is marked dead so that we can reorder StorageDead so it comes after Ne + + // We will maximum see 2 StorageDeads + let mut seen_storage_deads: SmallVec<[_; 2]> = SmallVec::new(); + let lower_index = location.statement_index.saturating_sub(3); + for (stmt_idx, stmt) in self.body.basic_blocks()[location.block].statements + [lower_index..location.statement_index] + .iter() + .enumerate() + .rev() + { + match &stmt.kind { + rustc_middle::mir::StatementKind::Assign(box (l, r)) => { + if *l == place { + match r { + // FIXME(simonvandel): extend for Ne-Not pair + Rvalue::BinaryOp(BinOp::Eq, op1, op2) => { + // We need to make sure that the StorageDeads we saw are for + // either `op1`or `op2` of Eq. Else we bail the optimization. + for (dead_local, _) in seen_storage_deads.iter() { + let dead_local_matches = [op1, op2].iter().any(|x| { + Some(*dead_local) == x.place().map(|x| x.local) + }); + if !dead_local_matches { + return None; + } + } + + // Recall that we are optimizing a sequence that looks like + // this: + // _4 = Eq(move _5, move _6); + // StorageDead(_5); + // StorageDead(_6); + // _3 = Not(move _4); + // + // If we do a naive replace of Not -> Ne, we up with this: + // StorageDead(_5); + // StorageDead(_6); + // _3 = Ne(move _5, move _6); + // + // Notice that `_5` and `_6` are marked dead before being used. + // To combat this we want to swap Ne with the StorageDead + // closest to Eq, i.e `StorageDead(_5)` in this example. + let storage_dead_to_swap = + seen_storage_deads.last().map(|(_, idx)| *idx); + + // If the operand of Not is moved into it, + // and that same operand is the lhs of the Eq assignment, + // then we can safely remove the Eq + let can_remove_eq = if op.is_move() { + Some(stmt_idx + lower_index) + } else { + None + }; + + self.optimizations.eq_not.insert( + location, + EqNotOptInfo { + op1: op1.clone(), + op2: op2.clone(), + storage_dead_idx_to_swap_with_ne: storage_dead_to_swap, + can_remove_eq, + }, + ); + return Some(()); + } + _ => {} + } + } + } + rustc_middle::mir::StatementKind::StorageDead(dead) => { + seen_storage_deads.push((*dead, stmt_idx + lower_index)); + } + // If we see a pattern other than (0..=2) StorageDeads and then an Eq assignment, we conservatively bail + _ => return None, + } + } + } + Some(()) + } + fn find_operand_in_equality_comparison_pattern( &self, l: &Operand<'tcx>, @@ -265,16 +387,32 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> { let _ = self.find_deref_of_address(rvalue, location); + let _ = self.find_eq_not(rvalue, location); + self.find_unneeded_equality_comparison(rvalue, location); self.super_rvalue(rvalue, location) } } +#[derive(Clone)] +struct EqNotOptInfo<'tcx> { + /// First operand of the Eq in the Eq-Not pair + op1: Operand<'tcx>, + /// Second operand of the Eq in the Eq-Not pair + op2: Operand<'tcx>, + /// Statement index of the `StorageDead` we want to swap with Ne. + /// None if no `StorageDead` exists between Eq and Not pair) + storage_dead_idx_to_swap_with_ne: Option, + // Statement index of the Eq. None if it can not be removed + can_remove_eq: Option, +} + #[derive(Default)] struct OptimizationList<'tcx> { and_stars: FxHashSet, arrays_lengths: FxHashMap>, unneeded_equality_comparison: FxHashMap>, unneeded_deref: FxHashMap>, + eq_not: FxHashMap>, } diff --git a/src/test/mir-opt/eq_not.opt_both_moved.InstCombine.diff b/src/test/mir-opt/eq_not.opt_both_moved.InstCombine.diff new file mode 100644 index 0000000000000..a0c3f474a8ce0 --- /dev/null +++ b/src/test/mir-opt/eq_not.opt_both_moved.InstCombine.diff @@ -0,0 +1,55 @@ +- // MIR for `opt_both_moved` before InstCombine ++ // MIR for `opt_both_moved` after InstCombine + + fn opt_both_moved(_1: u8) -> () { + debug x => _1; // in scope 0 at $DIR/eq_not.rs:18:19: 18:20 + let mut _0: (); // return place in scope 0 at $DIR/eq_not.rs:18:26: 18:26 + let _2: (); // in scope 0 at $DIR/eq_not.rs:19:5: 19:21 + let mut _3: bool; // in scope 0 at $DIR/eq_not.rs:19:5: 19:21 + let mut _4: bool; // in scope 0 at $DIR/eq_not.rs:19:13: 19:19 + let mut _5: u8; // in scope 0 at $DIR/eq_not.rs:19:13: 19:14 + let mut _6: u8; // in scope 0 at $DIR/eq_not.rs:19:18: 19:19 + let mut _7: !; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + + bb0: { + StorageLive(_2); // scope 0 at $DIR/eq_not.rs:19:5: 19:21 + StorageLive(_3); // scope 0 at $DIR/eq_not.rs:19:5: 19:21 + StorageLive(_4); // scope 0 at $DIR/eq_not.rs:19:13: 19:19 + StorageLive(_5); // scope 0 at $DIR/eq_not.rs:19:13: 19:14 + _5 = _1; // scope 0 at $DIR/eq_not.rs:19:13: 19:14 + StorageLive(_6); // scope 0 at $DIR/eq_not.rs:19:18: 19:19 + _6 = _1; // scope 0 at $DIR/eq_not.rs:19:18: 19:19 +- _4 = Eq(move _5, move _6); // scope 0 at $DIR/eq_not.rs:19:13: 19:19 +- StorageDead(_6); // scope 0 at $DIR/eq_not.rs:19:18: 19:19 ++ nop; // scope 0 at $DIR/eq_not.rs:19:13: 19:19 ++ _3 = Ne(move _5, move _6); // scope 0 at $DIR/eq_not.rs:19:5: 19:21 + StorageDead(_5); // scope 0 at $DIR/eq_not.rs:19:18: 19:19 +- _3 = Not(move _4); // scope 0 at $DIR/eq_not.rs:19:5: 19:21 ++ StorageDead(_6); // scope 0 at $DIR/eq_not.rs:19:18: 19:19 + StorageDead(_4); // scope 0 at $DIR/eq_not.rs:19:20: 19:21 + switchInt(_3) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/eq_not.rs:19:5: 19:21 + } + + bb1: { + _2 = const (); // scope 0 at $DIR/eq_not.rs:19:5: 19:21 + StorageDead(_3); // scope 0 at $DIR/eq_not.rs:19:20: 19:21 + StorageDead(_2); // scope 0 at $DIR/eq_not.rs:19:20: 19:21 + _0 = const (); // scope 0 at $DIR/eq_not.rs:18:26: 20:2 + return; // scope 0 at $DIR/eq_not.rs:20:2: 20:2 + } + + bb2: { + StorageLive(_7); // scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + begin_panic::<&str>(const "assertion failed: x == x"); // scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/std/src/macros.rs:LL:COL + // + literal: Const { ty: fn(&str) -> ! {std::rt::begin_panic::<&str>}, val: Value(Scalar()) } + // ty::Const + // + ty: &str + // + val: Value(Slice { data: Allocation { bytes: [97, 115, 115, 101, 114, 116, 105, 111, 110, 32, 102, 97, 105, 108, 101, 100, 58, 32, 120, 32, 61, 61, 32, 120], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [16777215], len: Size { raw: 24 } }, size: Size { raw: 24 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 24 }) + // mir::Constant + // + span: $DIR/eq_not.rs:1:1: 1:1 + // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [97, 115, 115, 101, 114, 116, 105, 111, 110, 32, 102, 97, 105, 108, 101, 100, 58, 32, 120, 32, 61, 61, 32, 120], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [16777215], len: Size { raw: 24 } }, size: Size { raw: 24 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 24 }) } + } + } + diff --git a/src/test/mir-opt/eq_not.opt_has_later_use.InstCombine.diff b/src/test/mir-opt/eq_not.opt_has_later_use.InstCombine.diff new file mode 100644 index 0000000000000..cfc13c8108e63 --- /dev/null +++ b/src/test/mir-opt/eq_not.opt_has_later_use.InstCombine.diff @@ -0,0 +1,62 @@ +- // MIR for `opt_has_later_use` before InstCombine ++ // MIR for `opt_has_later_use` after InstCombine + + fn opt_has_later_use(_1: Vec) -> u8 { + debug x => _1; // in scope 0 at $DIR/eq_not.rs:12:22: 12:23 + let mut _0: u8; // return place in scope 0 at $DIR/eq_not.rs:12:37: 12:39 + let _2: bool; // in scope 0 at $DIR/eq_not.rs:13:9: 13:10 + let mut _3: bool; // in scope 0 at $DIR/eq_not.rs:13:14: 13:28 + let mut _4: usize; // in scope 0 at $DIR/eq_not.rs:13:15: 13:22 + let mut _5: &std::vec::Vec; // in scope 0 at $DIR/eq_not.rs:13:15: 13:16 + let mut _6: bool; // in scope 0 at $DIR/eq_not.rs:14:8: 14:9 + scope 1 { + debug x => _2; // in scope 1 at $DIR/eq_not.rs:13:9: 13:10 + } + scope 2 { + debug self => _5; // in scope 2 at $SRC_DIR/alloc/src/vec.rs:LL:COL + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/eq_not.rs:13:9: 13:10 + StorageLive(_3); // scope 0 at $DIR/eq_not.rs:13:14: 13:28 + StorageLive(_4); // scope 0 at $DIR/eq_not.rs:13:15: 13:22 + StorageLive(_5); // scope 0 at $DIR/eq_not.rs:13:15: 13:16 + _5 = &_1; // scope 0 at $DIR/eq_not.rs:13:15: 13:16 + _4 = ((*_5).1: usize); // scope 2 at $SRC_DIR/alloc/src/vec.rs:LL:COL + StorageDead(_5); // scope 0 at $DIR/eq_not.rs:13:21: 13:22 +- _3 = Eq(move _4, const 2_usize); // scope 0 at $DIR/eq_not.rs:13:14: 13:28 ++ nop; // scope 0 at $DIR/eq_not.rs:13:14: 13:28 ++ _2 = Ne(move _4, const 2_usize); // scope 0 at $DIR/eq_not.rs:13:13: 13:28 + StorageDead(_4); // scope 0 at $DIR/eq_not.rs:13:27: 13:28 +- _2 = Not(move _3); // scope 0 at $DIR/eq_not.rs:13:13: 13:28 + StorageDead(_3); // scope 0 at $DIR/eq_not.rs:13:27: 13:28 + StorageLive(_6); // scope 1 at $DIR/eq_not.rs:14:8: 14:9 + _6 = _2; // scope 1 at $DIR/eq_not.rs:14:8: 14:9 + switchInt(_6) -> [false: bb2, otherwise: bb3]; // scope 1 at $DIR/eq_not.rs:14:5: 14:26 + } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/eq_not.rs:12:1: 15:2 + } + + bb2: { + _0 = const 1_u8; // scope 1 at $DIR/eq_not.rs:14:23: 14:24 + goto -> bb4; // scope 1 at $DIR/eq_not.rs:14:5: 14:26 + } + + bb3: { + _0 = const 0_u8; // scope 1 at $DIR/eq_not.rs:14:12: 14:13 + goto -> bb4; // scope 1 at $DIR/eq_not.rs:14:5: 14:26 + } + + bb4: { + StorageDead(_2); // scope 0 at $DIR/eq_not.rs:15:1: 15:2 + StorageDead(_6); // scope 0 at $DIR/eq_not.rs:15:1: 15:2 + drop(_1) -> [return: bb5, unwind: bb1]; // scope 0 at $DIR/eq_not.rs:15:1: 15:2 + } + + bb5: { + return; // scope 0 at $DIR/eq_not.rs:15:2: 15:2 + } + } + diff --git a/src/test/mir-opt/eq_not.opt_has_storage.InstCombine.diff b/src/test/mir-opt/eq_not.opt_has_storage.InstCombine.diff new file mode 100644 index 0000000000000..a03147a8fe124 --- /dev/null +++ b/src/test/mir-opt/eq_not.opt_has_storage.InstCombine.diff @@ -0,0 +1,69 @@ +- // MIR for `opt_has_storage` before InstCombine ++ // MIR for `opt_has_storage` after InstCombine + + fn opt_has_storage(_1: Vec) -> () { + debug x => _1; // in scope 0 at $DIR/eq_not.rs:7:20: 7:21 + let mut _0: (); // return place in scope 0 at $DIR/eq_not.rs:7:32: 7:32 + let _2: (); // in scope 0 at $DIR/eq_not.rs:8:5: 8:27 + let mut _3: bool; // in scope 0 at $DIR/eq_not.rs:8:5: 8:27 + let mut _4: bool; // in scope 0 at $DIR/eq_not.rs:8:13: 8:25 + let mut _5: usize; // in scope 0 at $DIR/eq_not.rs:8:13: 8:20 + let mut _6: &std::vec::Vec; // in scope 0 at $DIR/eq_not.rs:8:13: 8:14 + let mut _7: !; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + scope 1 { + debug self => _6; // in scope 1 at $SRC_DIR/alloc/src/vec.rs:LL:COL + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/eq_not.rs:8:5: 8:27 + StorageLive(_3); // scope 0 at $DIR/eq_not.rs:8:5: 8:27 + StorageLive(_4); // scope 0 at $DIR/eq_not.rs:8:13: 8:25 + StorageLive(_5); // scope 0 at $DIR/eq_not.rs:8:13: 8:20 + StorageLive(_6); // scope 0 at $DIR/eq_not.rs:8:13: 8:14 + _6 = &_1; // scope 0 at $DIR/eq_not.rs:8:13: 8:14 + _5 = ((*_6).1: usize); // scope 1 at $SRC_DIR/alloc/src/vec.rs:LL:COL + StorageDead(_6); // scope 0 at $DIR/eq_not.rs:8:19: 8:20 +- _4 = Eq(move _5, const 2_usize); // scope 0 at $DIR/eq_not.rs:8:13: 8:25 ++ nop; // scope 0 at $DIR/eq_not.rs:8:13: 8:25 ++ _3 = Ne(move _5, const 2_usize); // scope 0 at $DIR/eq_not.rs:8:5: 8:27 + StorageDead(_5); // scope 0 at $DIR/eq_not.rs:8:24: 8:25 +- _3 = Not(move _4); // scope 0 at $DIR/eq_not.rs:8:5: 8:27 + StorageDead(_4); // scope 0 at $DIR/eq_not.rs:8:26: 8:27 + switchInt(_3) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/eq_not.rs:8:5: 8:27 + } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/eq_not.rs:7:1: 9:2 + } + + bb2 (cleanup): { + drop(_1) -> bb1; // scope 0 at $DIR/eq_not.rs:9:1: 9:2 + } + + bb3: { + _2 = const (); // scope 0 at $DIR/eq_not.rs:8:5: 8:27 + StorageDead(_3); // scope 0 at $DIR/eq_not.rs:8:26: 8:27 + StorageDead(_2); // scope 0 at $DIR/eq_not.rs:8:26: 8:27 + _0 = const (); // scope 0 at $DIR/eq_not.rs:7:32: 9:2 + drop(_1) -> [return: bb5, unwind: bb1]; // scope 0 at $DIR/eq_not.rs:9:1: 9:2 + } + + bb4: { + StorageLive(_7); // scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + begin_panic::<&str>(const "assertion failed: x.len() == 2") -> bb2; // scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/std/src/macros.rs:LL:COL + // + literal: Const { ty: fn(&str) -> ! {std::rt::begin_panic::<&str>}, val: Value(Scalar()) } + // ty::Const + // + ty: &str + // + val: Value(Slice { data: Allocation { bytes: [97, 115, 115, 101, 114, 116, 105, 111, 110, 32, 102, 97, 105, 108, 101, 100, 58, 32, 120, 46, 108, 101, 110, 40, 41, 32, 61, 61, 32, 50], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1073741823], len: Size { raw: 30 } }, size: Size { raw: 30 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 30 }) + // mir::Constant + // + span: $DIR/eq_not.rs:1:1: 1:1 + // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [97, 115, 115, 101, 114, 116, 105, 111, 110, 32, 102, 97, 105, 108, 101, 100, 58, 32, 120, 46, 108, 101, 110, 40, 41, 32, 61, 61, 32, 50], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1073741823], len: Size { raw: 30 } }, size: Size { raw: 30 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 30 }) } + } + + bb5: { + return; // scope 0 at $DIR/eq_not.rs:9:2: 9:2 + } + } + diff --git a/src/test/mir-opt/eq_not.opt_simple.InstCombine.diff b/src/test/mir-opt/eq_not.opt_simple.InstCombine.diff new file mode 100644 index 0000000000000..b8ba46f97c35c --- /dev/null +++ b/src/test/mir-opt/eq_not.opt_simple.InstCombine.diff @@ -0,0 +1,50 @@ +- // MIR for `opt_simple` before InstCombine ++ // MIR for `opt_simple` after InstCombine + + fn opt_simple(_1: u8) -> () { + debug x => _1; // in scope 0 at $DIR/eq_not.rs:2:15: 2:16 + let mut _0: (); // return place in scope 0 at $DIR/eq_not.rs:2:22: 2:22 + let _2: (); // in scope 0 at $DIR/eq_not.rs:3:5: 3:21 + let mut _3: bool; // in scope 0 at $DIR/eq_not.rs:3:5: 3:21 + let mut _4: bool; // in scope 0 at $DIR/eq_not.rs:3:13: 3:19 + let mut _5: u8; // in scope 0 at $DIR/eq_not.rs:3:13: 3:14 + let mut _6: !; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + + bb0: { + StorageLive(_2); // scope 0 at $DIR/eq_not.rs:3:5: 3:21 + StorageLive(_3); // scope 0 at $DIR/eq_not.rs:3:5: 3:21 + StorageLive(_4); // scope 0 at $DIR/eq_not.rs:3:13: 3:19 + StorageLive(_5); // scope 0 at $DIR/eq_not.rs:3:13: 3:14 + _5 = _1; // scope 0 at $DIR/eq_not.rs:3:13: 3:14 +- _4 = Eq(move _5, const 2_u8); // scope 0 at $DIR/eq_not.rs:3:13: 3:19 ++ nop; // scope 0 at $DIR/eq_not.rs:3:13: 3:19 ++ _3 = Ne(move _5, const 2_u8); // scope 0 at $DIR/eq_not.rs:3:5: 3:21 + StorageDead(_5); // scope 0 at $DIR/eq_not.rs:3:18: 3:19 +- _3 = Not(move _4); // scope 0 at $DIR/eq_not.rs:3:5: 3:21 + StorageDead(_4); // scope 0 at $DIR/eq_not.rs:3:20: 3:21 + switchInt(_3) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/eq_not.rs:3:5: 3:21 + } + + bb1: { + _2 = const (); // scope 0 at $DIR/eq_not.rs:3:5: 3:21 + StorageDead(_3); // scope 0 at $DIR/eq_not.rs:3:20: 3:21 + StorageDead(_2); // scope 0 at $DIR/eq_not.rs:3:20: 3:21 + _0 = const (); // scope 0 at $DIR/eq_not.rs:2:22: 4:2 + return; // scope 0 at $DIR/eq_not.rs:4:2: 4:2 + } + + bb2: { + StorageLive(_6); // scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + begin_panic::<&str>(const "assertion failed: x == 2"); // scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/std/src/macros.rs:LL:COL + // + literal: Const { ty: fn(&str) -> ! {std::rt::begin_panic::<&str>}, val: Value(Scalar()) } + // ty::Const + // + ty: &str + // + val: Value(Slice { data: Allocation { bytes: [97, 115, 115, 101, 114, 116, 105, 111, 110, 32, 102, 97, 105, 108, 101, 100, 58, 32, 120, 32, 61, 61, 32, 50], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [16777215], len: Size { raw: 24 } }, size: Size { raw: 24 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 24 }) + // mir::Constant + // + span: $DIR/eq_not.rs:1:1: 1:1 + // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [97, 115, 115, 101, 114, 116, 105, 111, 110, 32, 102, 97, 105, 108, 101, 100, 58, 32, 120, 32, 61, 61, 32, 50], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [16777215], len: Size { raw: 24 } }, size: Size { raw: 24 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 24 }) } + } + } + diff --git a/src/test/mir-opt/eq_not.rs b/src/test/mir-opt/eq_not.rs new file mode 100644 index 0000000000000..7584289ff42e1 --- /dev/null +++ b/src/test/mir-opt/eq_not.rs @@ -0,0 +1,27 @@ +// EMIT_MIR eq_not.opt_simple.InstCombine.diff +fn opt_simple(x: u8) { + assert!(x == 2); +} + +// EMIT_MIR eq_not.opt_has_storage.InstCombine.diff +fn opt_has_storage(x: Vec) { + assert!(x.len() == 2); +} + +// EMIT_MIR eq_not.opt_has_later_use.InstCombine.diff +fn opt_has_later_use(x: Vec) -> u8 { + let x = !(x.len() == 2); + if x { 0 } else { 1 } +} + +// EMIT_MIR eq_not.opt_both_moved.InstCombine.diff +fn opt_both_moved(x: u8) { + assert!(x == x); +} + +fn main() { + opt_simple(0); + opt_has_storage(vec![]); + opt_has_later_use(vec![]); + opt_both_moved(0); +} diff --git a/src/test/mir-opt/inst_combine_deref.do_not_miscompile.InstCombine.diff b/src/test/mir-opt/inst_combine_deref.do_not_miscompile.InstCombine.diff index 23c18bde2262b..7716243fdd746 100644 --- a/src/test/mir-opt/inst_combine_deref.do_not_miscompile.InstCombine.diff +++ b/src/test/mir-opt/inst_combine_deref.do_not_miscompile.InstCombine.diff @@ -49,9 +49,11 @@ StorageLive(_9); // scope 4 at $DIR/inst_combine_deref.rs:60:13: 60:21 StorageLive(_10); // scope 4 at $DIR/inst_combine_deref.rs:60:13: 60:15 _10 = (*_3); // scope 4 at $DIR/inst_combine_deref.rs:60:13: 60:15 - _9 = Eq(move _10, const 99_i32); // scope 4 at $DIR/inst_combine_deref.rs:60:13: 60:21 +- _9 = Eq(move _10, const 99_i32); // scope 4 at $DIR/inst_combine_deref.rs:60:13: 60:21 ++ nop; // scope 4 at $DIR/inst_combine_deref.rs:60:13: 60:21 ++ _8 = Ne(move _10, const 99_i32); // scope 4 at $DIR/inst_combine_deref.rs:60:5: 60:23 StorageDead(_10); // scope 4 at $DIR/inst_combine_deref.rs:60:20: 60:21 - _8 = Not(move _9); // scope 4 at $DIR/inst_combine_deref.rs:60:5: 60:23 +- _8 = Not(move _9); // scope 4 at $DIR/inst_combine_deref.rs:60:5: 60:23 StorageDead(_9); // scope 4 at $DIR/inst_combine_deref.rs:60:22: 60:23 switchInt(_8) -> [false: bb1, otherwise: bb2]; // scope 4 at $DIR/inst_combine_deref.rs:60:5: 60:23 } diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff index a8662b96566cc..46d484b4cc7a5 100644 --- a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff +++ b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff @@ -6,50 +6,48 @@ let _1: i32; // in scope 0 at $DIR/issue-73223.rs:2:9: 2:14 let mut _2: std::option::Option; // in scope 0 at $DIR/issue-73223.rs:2:23: 2:30 let mut _4: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _5: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _6: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _7: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _8: &std::fmt::Arguments; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let _9: std::fmt::Arguments; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _10: &[std::fmt::ArgumentV1; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let _11: [std::fmt::ArgumentV1; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _12: (&&i32, &&i32); // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _5: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _6: &std::fmt::Arguments; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let _7: std::fmt::Arguments; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _8: &[std::fmt::ArgumentV1; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let _9: [std::fmt::ArgumentV1; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _10: (&&i32, &&i32); // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let _11: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _12: &&i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let _13: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _14: &&i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _15: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _16: std::fmt::ArgumentV1; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _17: std::fmt::ArgumentV1; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _14: std::fmt::ArgumentV1; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _15: std::fmt::ArgumentV1; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL scope 1 { debug split => _1; // in scope 1 at $DIR/issue-73223.rs:2:9: 2:14 let _3: std::option::Option; // in scope 1 at $DIR/issue-73223.rs:7:9: 7:14 scope 3 { debug _prev => _3; // in scope 3 at $DIR/issue-73223.rs:7:9: 7:14 scope 4 { - debug left_val => _13; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - debug right_val => _15; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug left_val => _11; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _13; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 5 { - debug arg0 => _20; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - debug arg1 => _23; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug arg0 => _18; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug arg1 => _21; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 6 { - debug x => _20; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - debug f => _19; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _18: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 6 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _19: for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 6 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _20: &&i32; // in scope 6 at $SRC_DIR/std/src/macros.rs:LL:COL + debug x => _18; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + debug f => _17; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + let mut _16: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 6 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _17: for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 6 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _18: &&i32; // in scope 6 at $SRC_DIR/std/src/macros.rs:LL:COL } scope 8 { - debug x => _23; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - debug f => _22; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _21: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 8 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _22: for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 8 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _23: &&i32; // in scope 8 at $SRC_DIR/std/src/macros.rs:LL:COL + debug x => _21; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + debug f => _20; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + let mut _19: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 8 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _20: for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 8 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _21: &&i32; // in scope 8 at $SRC_DIR/std/src/macros.rs:LL:COL } } scope 10 { - debug pieces => (_9.0: &[&str]); // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - debug args => _25; // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _24: std::option::Option<&[std::fmt::rt::v1::Argument]>; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _25: &[std::fmt::ArgumentV1]; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL + debug pieces => (_7.0: &[&str]); // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + debug args => _23; // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + let mut _22: std::option::Option<&[std::fmt::rt::v1::Argument]>; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _23: &[std::fmt::ArgumentV1]; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL } } } @@ -78,17 +76,11 @@ // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[1])) } - _13 = (_4.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _15 = (_4.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _11 = (_4.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _13 = (_4.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_5); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_6); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_7); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _7 = (*_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _6 = Eq(move _7, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_7); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _5 = Not(move _6); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_6); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - switchInt(_5) -> [false: bb1, otherwise: bb2]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _5 = (*_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _5) -> [1_i32: bb1, otherwise: bb2]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } bb1: { @@ -98,73 +90,74 @@ } bb2: { - (_9.0: &[&str]) = const main::promoted[0] as &[&str] (Pointer(Unsize)); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_5); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_7.0: &[&str]) = const main::promoted[0] as &[&str] (Pointer(Unsize)); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: &[&str; 3] // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &[&str; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) } - StorageLive(_11); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - (_12.0: &&i32) = &_13; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_14); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _14 = &_15; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - (_12.1: &&i32) = move _14; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageDead(_14); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - _20 = (_12.0: &&i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _23 = (_12.1: &&i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _19 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer)); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_9); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + (_10.0: &&i32) = &_11; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _12 = &_13; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_10.1: &&i32) = move _12; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageDead(_12); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + _18 = (_10.0: &&i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _21 = (_10.1: &&i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _17 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer)); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> {<&i32 as std::fmt::Debug>::fmt}, val: Value(Scalar()) } - StorageLive(_18); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _18 = transmute:: fn(&'r &i32, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>>(move _19) -> bb3; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_16); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _16 = transmute:: fn(&'r &i32, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>>(move _17) -> bb3; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/fmt/mod.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) -> for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> {std::intrinsics::transmute:: fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>>}, val: Value(Scalar()) } } bb3: { - (_16.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(move _20) -> bb4; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_14.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(move _18) -> bb4; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/fmt/mod.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(&&i32) -> &core::fmt::Opaque {std::intrinsics::transmute::<&&i32, &core::fmt::Opaque>}, val: Value(Scalar()) } } bb4: { - (_16.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _18; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_18); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _22 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer)); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_14.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _16; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_16); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _20 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer)); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> {<&i32 as std::fmt::Debug>::fmt}, val: Value(Scalar()) } - StorageLive(_21); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _21 = transmute:: fn(&'r &i32, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>>(move _22) -> bb5; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_19); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _19 = transmute:: fn(&'r &i32, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>>(move _20) -> bb5; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/fmt/mod.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) -> for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> {std::intrinsics::transmute:: fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>>}, val: Value(Scalar()) } } bb5: { - (_17.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(move _23) -> bb6; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_15.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(move _21) -> bb6; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/fmt/mod.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(&&i32) -> &core::fmt::Opaque {std::intrinsics::transmute::<&&i32, &core::fmt::Opaque>}, val: Value(Scalar()) } } bb6: { - (_17.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _21; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_21); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _11 = [move _16, move _17]; // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL - _10 = &_11; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - _25 = move _10 as &[std::fmt::ArgumentV1] (Pointer(Unsize)); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageLive(_24); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - discriminant(_24) = 0; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_9.1: std::option::Option<&[std::fmt::rt::v1::Argument]>) = move _24; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_9.2: &[std::fmt::ArgumentV1]) = move _25; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_24); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_15.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _19; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_19); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _9 = [move _14, move _15]; // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL _8 = &_9; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - begin_panic_fmt(move _8); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + _23 = move _8 as &[std::fmt::ArgumentV1] (Pointer(Unsize)); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageLive(_22); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + discriminant(_22) = 0; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_7.1: std::option::Option<&[std::fmt::rt::v1::Argument]>) = move _22; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_7.2: &[std::fmt::ArgumentV1]) = move _23; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_22); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _6 = &_7; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + begin_panic_fmt(move _6); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL // mir::Constant // + span: $SRC_DIR/std/src/macros.rs:LL:COL // + literal: Const { ty: for<'r, 's> fn(&'r std::fmt::Arguments<'s>) -> ! {std::rt::begin_panic_fmt}, val: Value(Scalar()) } diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff index 302612f5a0a28..bffce2c8f931a 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff @@ -148,12 +148,12 @@ _17 = (*_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _18 = const 1_i32; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _16 = Eq(move _17, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + nop; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _15 = Ne(_17, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + nop; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _15 = Not(move _16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - switchInt(_15) -> [false: bb4, otherwise: bb5]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _17) -> [1_i32: bb4, otherwise: bb5]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } bb3: { @@ -161,6 +161,7 @@ } bb4: { + StorageDead(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _8 = const (); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -174,6 +175,7 @@ } bb5: { + StorageDead(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_19); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageLive(_20); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageLive(_21); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL