From 8393037d106a28b47e1f6c18f9138a84fc740604 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 15 Sep 2020 02:13:23 +0200 Subject: [PATCH 01/10] Add an intra-basic-block copy propagation pass --- compiler/rustc_middle/src/mir/visit.rs | 8 ++ compiler/rustc_mir/src/transform/bbcp.rs | 165 +++++++++++++++++++++++ compiler/rustc_mir/src/transform/mod.rs | 2 + 3 files changed, 175 insertions(+) create mode 100644 compiler/rustc_mir/src/transform/bbcp.rs diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 58dd0bc00d204..2031d2cff92be 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -1196,6 +1196,14 @@ impl PlaceContext { matches!(self, PlaceContext::NonMutatingUse(..)) } + /// Returns `true` if `self` describes a move out of the place. + pub fn is_move(&self) -> bool { + match *self { + PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true, + _ => false, + } + } + /// Returns `true` if this place context represents a use. pub fn is_use(&self) -> bool { !matches!(self, PlaceContext::NonUse(..)) diff --git a/compiler/rustc_mir/src/transform/bbcp.rs b/compiler/rustc_mir/src/transform/bbcp.rs new file mode 100644 index 0000000000000..a28dcb23feb59 --- /dev/null +++ b/compiler/rustc_mir/src/transform/bbcp.rs @@ -0,0 +1,165 @@ +use rustc_index::vec::IndexVec; +use rustc_middle::{ + mir::traversal, mir::visit::MutVisitor, mir::visit::PlaceContext, mir::Body, mir::Local, + mir::Location, mir::Operand, mir::Place, mir::ProjectionElem, mir::Rvalue, mir::Statement, + mir::StatementKind, ty::TyCtxt, +}; +use smallvec::SmallVec; + +use super::{MirPass, MirSource}; + +pub struct Bbcp; + +impl<'tcx> MirPass<'tcx> for Bbcp { + fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) { + debug!("processing {:?}", source.def_id()); + + let mut visitor = BbcpVisitor { + tcx, + local_values: IndexVec::from_elem_n(None, body.local_decls.len()), + invalidation_map: IndexVec::from_elem_n(SmallVec::new(), body.local_decls.len()), + can_replace: true, + }; + + let reachable = traversal::reachable_as_bitset(body); + + for bb in reachable.iter() { + visitor.visit_basic_block_data(bb, &mut body.basic_blocks_mut()[bb]); + + for opt in visitor.local_values.iter_mut() { + *opt = None; + } + + for inv in visitor.invalidation_map.iter_mut() { + inv.clear(); + } + } + } +} + +struct BbcpVisitor<'tcx> { + tcx: TyCtxt<'tcx>, + + /// Tracks the (symbolic) values of local variables in the visited block. + local_values: IndexVec>>, + + /// Maps source locals to a list of destination locals to invalidate when the source is + /// deallocated or modified. + invalidation_map: IndexVec>, + + /// Whether we're allowed to apply replacements. This is temporarily set to `false` to avoid + /// replacing locals whose address is taken. + can_replace: bool, +} + +impl<'tcx> MutVisitor<'tcx> for BbcpVisitor<'tcx> { + fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { + self.tcx + } + + fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { + if let StatementKind::Assign(box (dest, Rvalue::Use(Operand::Copy(place)))) = + &statement.kind + { + if let Some(dest) = dest.as_local() { + if place_eligible(place) { + debug!("recording value at {:?}: {:?} = {:?}", location, dest, place); + self.local_values[dest] = Some(*place); + self.invalidation_map[place.local].push(dest); + return; + } + } + } + + self.super_statement(statement, location); + } + + fn visit_local(&mut self, local: &mut Local, context: PlaceContext, location: Location) { + // We invalidate a local `l`, and any other locals whose assigned values contain `l`, if: + // - `l` is mutated (via assignment or other stores, by taking a mutable ref/ptr, etc.) + // - `l` is reallocated by storage statements (which deinitialized its storage) + // - `l` is moved from (to avoid use-after-moves) + + if context.is_mutating_use() || context.is_storage_marker() || context.is_move() { + debug!("invalidation of {:?} at {:?}: {:?} -> clearing", local, location, context); + self.local_values[*local] = None; + for inv in &self.invalidation_map[*local] { + self.local_values[*inv] = None; + } + self.invalidation_map[*local].clear(); + } + } + + fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) { + // Prevent replacing anything an address is taken from. + // Doing that would cause code like: + // _1 = ...; + // _2 = _1; + // _3 = &_1; + // _4 = &_2; + // to assign the same address to _3 and _4, which we don't want to do. + + let takes_ref = match rvalue { + Rvalue::Use(..) + | Rvalue::Repeat(..) + | Rvalue::ThreadLocalRef(..) + | Rvalue::Len(..) + | Rvalue::Cast(..) + | Rvalue::BinaryOp(..) + | Rvalue::CheckedBinaryOp(..) + | Rvalue::NullaryOp(..) + | Rvalue::UnaryOp(..) + | Rvalue::Discriminant(..) + | Rvalue::Aggregate(..) => false, + Rvalue::AddressOf(..) | Rvalue::Ref(..) => true, + }; + + if takes_ref { + let old_can_replace = self.can_replace; + self.can_replace = false; + self.super_rvalue(rvalue, location); + self.can_replace = old_can_replace; + } else { + self.super_rvalue(rvalue, location); + } + } + + fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) { + // We can *not* do: + // _1 = ...; + // _2 = move _1; + // use(move _2); <- can not replace with `use(_1)` + // Because `_1` was already moved out of. This is handled when recording values of locals + // though, so we won't end up here in that situation. When we see a `move` *here*, it must + // be fine to instead make a *copy* of the original: + // _1 = ...; + // _2 = _1; + // use(move _2); <- can replace with `use(_2)` + + // NB: All `operand`s are non-mutating uses of the contained place. + if let Operand::Copy(place) | Operand::Move(place) = operand { + if self.can_replace { + if let Some(local) = place.as_local() { + if let Some(known_place) = self.local_values[local] { + debug!( + "{:?}: replacing use of {:?} with {:?}", + location, place, known_place + ); + *operand = Operand::Copy(known_place); + } + } + } + } + } +} + +fn place_eligible(place: &Place<'_>) -> bool { + place.projection.iter().all(|elem| match elem { + ProjectionElem::Deref | ProjectionElem::Index(_) => false, + + ProjectionElem::Field(..) + | ProjectionElem::ConstantIndex { .. } + | ProjectionElem::Subslice { .. } + | ProjectionElem::Downcast(..) => true, + }) +} diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs index 20b8c90a9dcad..e6c9cc9d2061a 100644 --- a/compiler/rustc_mir/src/transform/mod.rs +++ b/compiler/rustc_mir/src/transform/mod.rs @@ -16,6 +16,7 @@ use std::borrow::Cow; pub mod add_call_guards; pub mod add_moves_for_packed_drops; pub mod add_retag; +pub mod bbcp; pub mod check_const_item_mutation; pub mod check_consts; pub mod check_packed_ref; @@ -399,6 +400,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &simplify_comparison_integral::SimplifyComparisonIntegral, &simplify_try::SimplifyArmIdentity, &simplify_try::SimplifyBranchSame, + &bbcp::Bbcp, &dest_prop::DestinationPropagation, &simplify_branches::SimplifyBranches::new("final"), &remove_noop_landing_pads::RemoveNoopLandingPads, From bfb363d2044f105521e0b4b2b7ce7ec8a1ed3011 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 15 Sep 2020 23:05:31 +0200 Subject: [PATCH 02/10] Ensure linear time complexity --- compiler/rustc_mir/src/transform/bbcp.rs | 244 ++++++++++++++++------- 1 file changed, 169 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_mir/src/transform/bbcp.rs b/compiler/rustc_mir/src/transform/bbcp.rs index a28dcb23feb59..5b30904af46c8 100644 --- a/compiler/rustc_mir/src/transform/bbcp.rs +++ b/compiler/rustc_mir/src/transform/bbcp.rs @@ -1,8 +1,9 @@ -use rustc_index::vec::IndexVec; +use rustc_index::{bit_set::BitSet, vec::IndexVec}; use rustc_middle::{ - mir::traversal, mir::visit::MutVisitor, mir::visit::PlaceContext, mir::Body, mir::Local, - mir::Location, mir::Operand, mir::Place, mir::ProjectionElem, mir::Rvalue, mir::Statement, - mir::StatementKind, ty::TyCtxt, + mir::traversal, mir::visit::MutVisitor, mir::visit::PlaceContext, mir::visit::Visitor, + mir::Body, mir::Local, mir::Location, mir::Operand, mir::Place, mir::ProjectionElem, + mir::Rvalue, mir::Statement, mir::StatementKind, mir::Terminator, mir::TerminatorKind, + ty::TyCtxt, }; use smallvec::SmallVec; @@ -14,42 +15,121 @@ impl<'tcx> MirPass<'tcx> for Bbcp { fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) { debug!("processing {:?}", source.def_id()); + let mut borrows = BorrowCollector { locals: BitSet::new_empty(body.local_decls.len()) }; + borrows.visit_body(body); + let mut visitor = BbcpVisitor { tcx, - local_values: IndexVec::from_elem_n(None, body.local_decls.len()), - invalidation_map: IndexVec::from_elem_n(SmallVec::new(), body.local_decls.len()), - can_replace: true, + referenced_locals: borrows.locals, + local_values: LocalValues::new(body), }; let reachable = traversal::reachable_as_bitset(body); for bb in reachable.iter() { visitor.visit_basic_block_data(bb, &mut body.basic_blocks_mut()[bb]); + visitor.local_values.clear(); + } + } +} - for opt in visitor.local_values.iter_mut() { - *opt = None; - } +/// Symbolic value of a local variable. +#[derive(Copy, Clone)] +enum LocalValue<'tcx> { + Unknown, + + /// The local is definitely assigned to `place`. + Place { + place: Place<'tcx>, + generation: u32, + }, +} + +/// Stores the locals that need to be invalidated when this local is modified or deallocated. +#[derive(Default, Clone)] +struct Invalidation { + locals: SmallVec<[Local; 4]>, + generation: u32, +} + +struct LocalValues<'tcx> { + /// Tracks the values that were assigned to local variables in the current basic block. + map: IndexVec>, + + /// Maps source locals to a list of destination locals to invalidate when the source is + /// deallocated or modified. + invalidation_map: IndexVec, + + /// Data generation in this map. + /// + /// This is bumped when entering a new block. When looking data up, we ensure it was stored in + /// the same generation. This allows clearing the map by simply incrementing the generation + /// instead of having to clear the data (which can perform poorly). + generation: u32, +} + +impl<'tcx> LocalValues<'tcx> { + fn new(body: &Body<'_>) -> Self { + Self { + map: IndexVec::from_elem_n(LocalValue::Unknown, body.local_decls.len()), + invalidation_map: IndexVec::from_elem_n( + Invalidation::default(), + body.local_decls.len(), + ), + generation: 0, + } + } - for inv in visitor.invalidation_map.iter_mut() { - inv.clear(); + fn get(&self, local: Local) -> Option> { + match self.map[local] { + LocalValue::Place { place, generation } if generation == self.generation => Some(place), + _ => None, + } + } + + /// Records an assignment of `place` to `local`. + fn insert(&mut self, local: Local, place: Place<'tcx>) { + self.map[local] = LocalValue::Place { place, generation: self.generation }; + + let inval = &mut self.invalidation_map[place.local]; + if inval.generation != self.generation { + inval.locals.clear(); + inval.generation = self.generation; + } + + inval.locals.push(local); + } + + /// Resets `local`'s state to `Unknown` and invalidates all locals that have been assigned to + /// `local` in the past. + fn invalidate(&mut self, local: Local) { + self.map[local] = LocalValue::Unknown; + + let inval = &mut self.invalidation_map[local]; + if inval.generation == self.generation { + for local in &inval.locals { + self.map[*local] = LocalValue::Unknown; } + + inval.locals.clear(); } } + + /// Marks the data in the map as dirty, effectively clearing it. + fn clear(&mut self) { + self.generation += 1; + } } struct BbcpVisitor<'tcx> { tcx: TyCtxt<'tcx>, - /// Tracks the (symbolic) values of local variables in the visited block. - local_values: IndexVec>>, + /// Locals that have their address taken. We will not replace those, since that may change their + /// observed address. + referenced_locals: BitSet, - /// Maps source locals to a list of destination locals to invalidate when the source is - /// deallocated or modified. - invalidation_map: IndexVec>, - - /// Whether we're allowed to apply replacements. This is temporarily set to `false` to avoid - /// replacing locals whose address is taken. - can_replace: bool, + /// Tracks the (symbolic) values of local variables in the visited block. + local_values: LocalValues<'tcx>, } impl<'tcx> MutVisitor<'tcx> for BbcpVisitor<'tcx> { @@ -62,10 +142,12 @@ impl<'tcx> MutVisitor<'tcx> for BbcpVisitor<'tcx> { &statement.kind { if let Some(dest) = dest.as_local() { - if place_eligible(place) { + if place_eligible(place) + && !self.referenced_locals.contains(dest) + && !self.referenced_locals.contains(place.local) + { debug!("recording value at {:?}: {:?} = {:?}", location, dest, place); - self.local_values[dest] = Some(*place); - self.invalidation_map[place.local].push(dest); + self.local_values.insert(dest, *place); return; } } @@ -77,50 +159,12 @@ impl<'tcx> MutVisitor<'tcx> for BbcpVisitor<'tcx> { fn visit_local(&mut self, local: &mut Local, context: PlaceContext, location: Location) { // We invalidate a local `l`, and any other locals whose assigned values contain `l`, if: // - `l` is mutated (via assignment or other stores, by taking a mutable ref/ptr, etc.) - // - `l` is reallocated by storage statements (which deinitialized its storage) + // - `l` is reallocated by storage statements (which deinitializes its storage) // - `l` is moved from (to avoid use-after-moves) if context.is_mutating_use() || context.is_storage_marker() || context.is_move() { debug!("invalidation of {:?} at {:?}: {:?} -> clearing", local, location, context); - self.local_values[*local] = None; - for inv in &self.invalidation_map[*local] { - self.local_values[*inv] = None; - } - self.invalidation_map[*local].clear(); - } - } - - fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) { - // Prevent replacing anything an address is taken from. - // Doing that would cause code like: - // _1 = ...; - // _2 = _1; - // _3 = &_1; - // _4 = &_2; - // to assign the same address to _3 and _4, which we don't want to do. - - let takes_ref = match rvalue { - Rvalue::Use(..) - | Rvalue::Repeat(..) - | Rvalue::ThreadLocalRef(..) - | Rvalue::Len(..) - | Rvalue::Cast(..) - | Rvalue::BinaryOp(..) - | Rvalue::CheckedBinaryOp(..) - | Rvalue::NullaryOp(..) - | Rvalue::UnaryOp(..) - | Rvalue::Discriminant(..) - | Rvalue::Aggregate(..) => false, - Rvalue::AddressOf(..) | Rvalue::Ref(..) => true, - }; - - if takes_ref { - let old_can_replace = self.can_replace; - self.can_replace = false; - self.super_rvalue(rvalue, location); - self.can_replace = old_can_replace; - } else { - self.super_rvalue(rvalue, location); + self.local_values.invalidate(*local); } } @@ -128,25 +172,20 @@ impl<'tcx> MutVisitor<'tcx> for BbcpVisitor<'tcx> { // We can *not* do: // _1 = ...; // _2 = move _1; - // use(move _2); <- can not replace with `use(_1)` + // use(move _2); <- can not replace with `use(move _1)` or `use(_1)` // Because `_1` was already moved out of. This is handled when recording values of locals // though, so we won't end up here in that situation. When we see a `move` *here*, it must // be fine to instead make a *copy* of the original: // _1 = ...; // _2 = _1; - // use(move _2); <- can replace with `use(_2)` + // use(move _2); <- can replace with `use(_1)` // NB: All `operand`s are non-mutating uses of the contained place. if let Operand::Copy(place) | Operand::Move(place) = operand { - if self.can_replace { - if let Some(local) = place.as_local() { - if let Some(known_place) = self.local_values[local] { - debug!( - "{:?}: replacing use of {:?} with {:?}", - location, place, known_place - ); - *operand = Operand::Copy(known_place); - } + if let Some(local) = place.as_local() { + if let Some(known_place) = self.local_values.get(local) { + debug!("{:?}: replacing use of {:?} with {:?}", location, place, known_place); + *operand = Operand::Copy(known_place); } } } @@ -163,3 +202,58 @@ fn place_eligible(place: &Place<'_>) -> bool { | ProjectionElem::Downcast(..) => true, }) } + +struct BorrowCollector { + locals: BitSet, +} + +impl<'tcx> Visitor<'tcx> for BorrowCollector { + fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { + self.super_rvalue(rvalue, location); + + match rvalue { + Rvalue::AddressOf(_, borrowed_place) | Rvalue::Ref(_, _, borrowed_place) => { + if !borrowed_place.is_indirect() { + self.locals.insert(borrowed_place.local); + } + } + + Rvalue::Cast(..) + | Rvalue::Use(..) + | Rvalue::Repeat(..) + | Rvalue::Len(..) + | Rvalue::BinaryOp(..) + | Rvalue::CheckedBinaryOp(..) + | Rvalue::NullaryOp(..) + | Rvalue::UnaryOp(..) + | Rvalue::Discriminant(..) + | Rvalue::Aggregate(..) + | Rvalue::ThreadLocalRef(..) => {} + } + } + + fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { + self.super_terminator(terminator, location); + + match terminator.kind { + TerminatorKind::Drop { place: dropped_place, .. } + | TerminatorKind::DropAndReplace { place: dropped_place, .. } => { + self.locals.insert(dropped_place.local); + } + + TerminatorKind::Abort + | TerminatorKind::Assert { .. } + | TerminatorKind::Call { .. } + | TerminatorKind::FalseEdge { .. } + | TerminatorKind::FalseUnwind { .. } + | TerminatorKind::GeneratorDrop + | TerminatorKind::Goto { .. } + | TerminatorKind::Resume + | TerminatorKind::Return + | TerminatorKind::SwitchInt { .. } + | TerminatorKind::Unreachable + | TerminatorKind::Yield { .. } + | TerminatorKind::InlineAsm { .. } => {} + } + } +} From 91131e5eaff7ed6a9a9e3c045ed0694fcf0d5d9c Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 16 Sep 2020 02:15:24 +0200 Subject: [PATCH 03/10] Clean up and document --- .../{bbcp.rs => basic_block_copy_prop.rs} | 101 +++++++++++++----- compiler/rustc_mir/src/transform/mod.rs | 4 +- 2 files changed, 74 insertions(+), 31 deletions(-) rename compiler/rustc_mir/src/transform/{bbcp.rs => basic_block_copy_prop.rs} (64%) diff --git a/compiler/rustc_mir/src/transform/bbcp.rs b/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs similarity index 64% rename from compiler/rustc_mir/src/transform/bbcp.rs rename to compiler/rustc_mir/src/transform/basic_block_copy_prop.rs index 5b30904af46c8..7db6af1bfcb44 100644 --- a/compiler/rustc_mir/src/transform/bbcp.rs +++ b/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs @@ -1,33 +1,61 @@ +//! A simple intra-block copy propagation pass. +//! +//! This pass performs simple forwards-propagation of locals that were assigned within the same MIR +//! block. This is a common pattern introduced by MIR building. +//! +//! The pass is fairly simple: It walks every MIR block from top to bottom and looks for assignments +//! we can track. At the same time, it looks for uses of locals whose value we have previously +//! recorded, and replaces them with their value. +//! +//! "Value" in this case means `LocalValue`, not an actual concrete value (that would be constant +//! propagation). `LocalValue` is either `Unknown`, which means that a local has no value we can +//! substitute it for, or `Place`, which means that the local was previously assigned to a copy of +//! some `Place` and can be replaced by it. +//! +//! Removal of the left-over assignments and locals (if possible) is performed by the +//! `SimplifyLocals` pass that runs later. +//! +//! The pass has one interesting optimization to ensure that it runs in linear time: Recorded values +//! are tagged by a "generation", which indicates in which basic block the value was recorded. +//! `LocalValues` will only return values that were recorded in the current generation (so in the +//! current block). Once we move on to a different block, we bump the generation counter, which will +//! result in all old values becoming inaccessible. This is logically equivalent to simply +//! overwriting all of them with `Unknown`, but is much cheaper: Just an increment instead of an +//! `O(n)` clear (where `n` is the number of locals declared in the body). This `O(n)` runtime would +//! otherwise make the total runtime of this pass `O(n * m)`, where `n` is the number of locals and +//! `m` is the number of basic blocks, which is prohibitively expensive. + use rustc_index::{bit_set::BitSet, vec::IndexVec}; use rustc_middle::{ - mir::traversal, mir::visit::MutVisitor, mir::visit::PlaceContext, mir::visit::Visitor, - mir::Body, mir::Local, mir::Location, mir::Operand, mir::Place, mir::ProjectionElem, - mir::Rvalue, mir::Statement, mir::StatementKind, mir::Terminator, mir::TerminatorKind, - ty::TyCtxt, + mir::visit::MutVisitor, mir::visit::PlaceContext, mir::visit::Visitor, mir::Body, mir::Local, + mir::Location, mir::Operand, mir::Place, mir::ProjectionElem, mir::Rvalue, mir::Statement, + mir::StatementKind, mir::Terminator, mir::TerminatorKind, ty::TyCtxt, }; use smallvec::SmallVec; use super::{MirPass, MirSource}; -pub struct Bbcp; +pub struct BasicBlockCopyProp; -impl<'tcx> MirPass<'tcx> for Bbcp { +impl<'tcx> MirPass<'tcx> for BasicBlockCopyProp { fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) { + if tcx.sess.opts.debugging_opts.mir_opt_level == 0 { + return; + } + debug!("processing {:?}", source.def_id()); let mut borrows = BorrowCollector { locals: BitSet::new_empty(body.local_decls.len()) }; borrows.visit_body(body); - let mut visitor = BbcpVisitor { + let mut visitor = CopyPropVisitor { tcx, referenced_locals: borrows.locals, local_values: LocalValues::new(body), }; - let reachable = traversal::reachable_as_bitset(body); - - for bb in reachable.iter() { - visitor.visit_basic_block_data(bb, &mut body.basic_blocks_mut()[bb]); + for (bb, data) in body.basic_blocks_mut().iter_enumerated_mut() { + visitor.visit_basic_block_data(bb, data); visitor.local_values.clear(); } } @@ -36,13 +64,15 @@ impl<'tcx> MirPass<'tcx> for Bbcp { /// Symbolic value of a local variable. #[derive(Copy, Clone)] enum LocalValue<'tcx> { + /// Locals start out with unknown values, and are assigned an unknown value when they are + /// mutated in an incompatible way. Unknown, - /// The local is definitely assigned to `place`. - Place { - place: Place<'tcx>, - generation: u32, - }, + /// The local was last assigned to a copy of `place`. + /// + /// If a local is in this state, and we see a use of that local, we can substitute `place` + /// instead, potentially eliminating the local and its assignment. + Place { place: Place<'tcx>, generation: u32 }, } /// Stores the locals that need to be invalidated when this local is modified or deallocated. @@ -121,23 +151,27 @@ impl<'tcx> LocalValues<'tcx> { } } -struct BbcpVisitor<'tcx> { +struct CopyPropVisitor<'tcx> { tcx: TyCtxt<'tcx>, - /// Locals that have their address taken. We will not replace those, since that may change their - /// observed address. + /// Locals that have their address taken. referenced_locals: BitSet, /// Tracks the (symbolic) values of local variables in the visited block. local_values: LocalValues<'tcx>, } -impl<'tcx> MutVisitor<'tcx> for BbcpVisitor<'tcx> { +impl<'tcx> MutVisitor<'tcx> for CopyPropVisitor<'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { self.tcx } fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { + // We are only looking for *copies* of a place, not moves, since moving out of the place + // *again* later on would be a use-after-move. For example: + // _1 = ...; + // _2 = move _1; + // use(move _2); <- can *not* replace with `use(move _1)` or `use(_1)` if let StatementKind::Assign(box (dest, Rvalue::Use(Operand::Copy(place)))) = &statement.kind { @@ -153,6 +187,8 @@ impl<'tcx> MutVisitor<'tcx> for BbcpVisitor<'tcx> { } } + // If this is not an eligible assignment to be recorded, visit it. This will keep track of + // any mutations of locals via `visit_local` and assign an `Unknown` value to them. self.super_statement(statement, location); } @@ -169,18 +205,15 @@ impl<'tcx> MutVisitor<'tcx> for BbcpVisitor<'tcx> { } fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) { - // We can *not* do: - // _1 = ...; - // _2 = move _1; - // use(move _2); <- can not replace with `use(move _1)` or `use(_1)` - // Because `_1` was already moved out of. This is handled when recording values of locals - // though, so we won't end up here in that situation. When we see a `move` *here*, it must - // be fine to instead make a *copy* of the original: + // NB: All `operand`s are non-mutating uses of the contained place, so we don't have to call + // `super_operand` here. + + // We *can* replace a `move` by a copy from the recorded place, because we only record + // places that are *copied* from in the first place (so the place type must be `Copy` by + // virtue of the input MIR). For example, this is a common pattern: // _1 = ...; // _2 = _1; // use(move _2); <- can replace with `use(_1)` - - // NB: All `operand`s are non-mutating uses of the contained place. if let Operand::Copy(place) | Operand::Move(place) = operand { if let Some(local) = place.as_local() { if let Some(known_place) = self.local_values.get(local) { @@ -192,6 +225,12 @@ impl<'tcx> MutVisitor<'tcx> for BbcpVisitor<'tcx> { } } +/// Determines whether `place` is an assignment source that may later be used instead of the local +/// it is assigned to. +/// +/// This is the case only for places that don't dereference pointers (since the dereference +/// operation may not be valid anymore after this point), and don't index a slice (since that uses +/// another local besides the base local, which would need additional tracking). fn place_eligible(place: &Place<'_>) -> bool { place.projection.iter().all(|elem| match elem { ProjectionElem::Deref | ProjectionElem::Index(_) => false, @@ -203,6 +242,10 @@ fn place_eligible(place: &Place<'_>) -> bool { }) } +/// Collects locals that have their address taken. +/// +/// We do not optimize such locals since they can be modified through operations that do not mention +/// the local. Doing so might also change the local's address, which is observable. struct BorrowCollector { locals: BitSet, } diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs index e6c9cc9d2061a..7385fe9d0b0de 100644 --- a/compiler/rustc_mir/src/transform/mod.rs +++ b/compiler/rustc_mir/src/transform/mod.rs @@ -16,7 +16,7 @@ use std::borrow::Cow; pub mod add_call_guards; pub mod add_moves_for_packed_drops; pub mod add_retag; -pub mod bbcp; +pub mod basic_block_copy_prop; pub mod check_const_item_mutation; pub mod check_consts; pub mod check_packed_ref; @@ -400,7 +400,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &simplify_comparison_integral::SimplifyComparisonIntegral, &simplify_try::SimplifyArmIdentity, &simplify_try::SimplifyBranchSame, - &bbcp::Bbcp, + &basic_block_copy_prop::BasicBlockCopyProp, &dest_prop::DestinationPropagation, &simplify_branches::SimplifyBranches::new("final"), &remove_noop_landing_pads::RemoveNoopLandingPads, From 63c046475e5ea535d7b97cf7e77217cc80a6f383 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 16 Sep 2020 23:05:52 +0200 Subject: [PATCH 04/10] Don't MIR-optimize the codegen tests --- .../simd-intrinsic-generic-arithmetic-saturating.rs | 2 +- .../codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs index 267c995e0704f..3d3c00e159622 100644 --- a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs +++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs @@ -1,4 +1,4 @@ -// compile-flags: -C no-prepopulate-passes +// compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 // ignore-tidy-linelength #![crate_type = "lib"] diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs index 87c8b0d87d8bb..6624656d1ab06 100644 --- a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs +++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs @@ -1,4 +1,4 @@ -// compile-flags: -C no-prepopulate-passes +// compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 // ignore-tidy-linelength #![crate_type = "lib"] From 187a7c0be70284dda9d049fda50a4ab92ec4a74b Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 17 Sep 2020 21:31:47 +0200 Subject: [PATCH 05/10] Clean up imports Auto-import made a bit of a mess here --- .../rustc_mir/src/transform/basic_block_copy_prop.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs b/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs index 7db6af1bfcb44..3768eb25447b2 100644 --- a/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs +++ b/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs @@ -25,12 +25,14 @@ //! otherwise make the total runtime of this pass `O(n * m)`, where `n` is the number of locals and //! `m` is the number of basic blocks, which is prohibitively expensive. -use rustc_index::{bit_set::BitSet, vec::IndexVec}; -use rustc_middle::{ - mir::visit::MutVisitor, mir::visit::PlaceContext, mir::visit::Visitor, mir::Body, mir::Local, - mir::Location, mir::Operand, mir::Place, mir::ProjectionElem, mir::Rvalue, mir::Statement, - mir::StatementKind, mir::Terminator, mir::TerminatorKind, ty::TyCtxt, +use rustc_index::bit_set::BitSet; +use rustc_index::vec::IndexVec; +use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; +use rustc_middle::mir::{ + Body, Local, Location, Operand, Place, ProjectionElem, Rvalue, Statement, StatementKind, + Terminator, TerminatorKind, }; +use rustc_middle::ty::TyCtxt; use smallvec::SmallVec; use super::{MirPass, MirSource}; From f189785c8338cb7b0838a7e0ef72ffd297decdcd Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 19 Sep 2020 18:58:57 +0200 Subject: [PATCH 06/10] Reorder invalidation and replacement steps --- .../src/transform/basic_block_copy_prop.rs | 63 ++++++++++++++++++- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs b/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs index 3768eb25447b2..a8f8b70a00b91 100644 --- a/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs +++ b/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs @@ -164,7 +164,7 @@ struct CopyPropVisitor<'tcx> { } impl<'tcx> MutVisitor<'tcx> for CopyPropVisitor<'tcx> { - fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -192,18 +192,53 @@ impl<'tcx> MutVisitor<'tcx> for CopyPropVisitor<'tcx> { // If this is not an eligible assignment to be recorded, visit it. This will keep track of // any mutations of locals via `visit_local` and assign an `Unknown` value to them. self.super_statement(statement, location); + + // Now that we've invalidated locals mutated by the statement, replace any known locals that + // *aren't* mutated with the place they were assigned to. + ReplaceUseVisitor { tcx: self.tcx, local_values: &self.local_values } + .visit_statement(statement, location); + + InvalidateMovedLocals { tcx: self.tcx, local_values: &mut self.local_values } + .visit_statement(statement, location); + } + + fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) { + self.super_terminator(terminator, location); + + // Now that we've invalidated locals mutated by the terminator, replace any known locals + // that *aren't* mutated with the place they were assigned to. + ReplaceUseVisitor { tcx: self.tcx, local_values: &mut self.local_values } + .visit_terminator(terminator, location); + + InvalidateMovedLocals { tcx: self.tcx, local_values: &mut self.local_values } + .visit_terminator(terminator, location); } fn visit_local(&mut self, local: &mut Local, context: PlaceContext, location: Location) { // We invalidate a local `l`, and any other locals whose assigned values contain `l`, if: // - `l` is mutated (via assignment or other stores, by taking a mutable ref/ptr, etc.) // - `l` is reallocated by storage statements (which deinitializes its storage) - // - `l` is moved from (to avoid use-after-moves) - if context.is_mutating_use() || context.is_storage_marker() || context.is_move() { + if context.is_mutating_use() || context.is_storage_marker() { debug!("invalidation of {:?} at {:?}: {:?} -> clearing", local, location, context); self.local_values.invalidate(*local); } + + // Note that we do not yet do anything when `l` is moved out of. The reason for that is that + // it is fine to replace that local (see reasoning below). We just have to make sure we + // invalidate the moved-out-of local *after* we finished processing the statement/terminator + // performing the move. + } +} + +struct ReplaceUseVisitor<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + local_values: &'a LocalValues<'tcx>, +} + +impl<'a, 'tcx> MutVisitor<'tcx> for ReplaceUseVisitor<'a, 'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx } fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) { @@ -216,6 +251,8 @@ impl<'tcx> MutVisitor<'tcx> for CopyPropVisitor<'tcx> { // _1 = ...; // _2 = _1; // use(move _2); <- can replace with `use(_1)` + // Or: + // use(move _2, move _1); <- can replace with `use(_1, _1)` if let Operand::Copy(place) | Operand::Move(place) = operand { if let Some(local) = place.as_local() { if let Some(known_place) = self.local_values.get(local) { @@ -227,6 +264,26 @@ impl<'tcx> MutVisitor<'tcx> for CopyPropVisitor<'tcx> { } } +struct InvalidateMovedLocals<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + local_values: &'a mut LocalValues<'tcx>, +} + +impl<'a, 'tcx> MutVisitor<'tcx> for InvalidateMovedLocals<'a, 'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn visit_local(&mut self, local: &mut Local, context: PlaceContext, location: Location) { + // If the statement/terminator moves out of a local, invalidate the local. + + if context.is_move() { + debug!("move out of {:?} at {:?}: {:?} -> clearing", local, location, context); + self.local_values.invalidate(*local); + } + } +} + /// Determines whether `place` is an assignment source that may later be used instead of the local /// it is assigned to. /// From ed37dbfe4bacb9e2338352372e3be149f7a1dd9b Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 17 Oct 2020 00:09:46 +0200 Subject: [PATCH 07/10] Fix rebase fallout --- compiler/rustc_mir/src/transform/basic_block_copy_prop.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs b/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs index a8f8b70a00b91..950f7255e6b1d 100644 --- a/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs +++ b/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs @@ -35,17 +35,17 @@ use rustc_middle::mir::{ use rustc_middle::ty::TyCtxt; use smallvec::SmallVec; -use super::{MirPass, MirSource}; +use super::MirPass; pub struct BasicBlockCopyProp; impl<'tcx> MirPass<'tcx> for BasicBlockCopyProp { - fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { if tcx.sess.opts.debugging_opts.mir_opt_level == 0 { return; } - debug!("processing {:?}", source.def_id()); + debug!("processing {:?}", body.source.def_id()); let mut borrows = BorrowCollector { locals: BitSet::new_empty(body.local_decls.len()) }; borrows.visit_body(body); From 91b4c554cb50c76b45b2e8e0a85d732fa7bdc266 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 17 Oct 2020 16:31:50 +0200 Subject: [PATCH 08/10] Update compiler/rustc_middle/src/mir/visit.rs Co-authored-by: LingMan --- compiler/rustc_middle/src/mir/visit.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 2031d2cff92be..a366df2dbb7a0 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -1198,10 +1198,7 @@ impl PlaceContext { /// Returns `true` if `self` describes a move out of the place. pub fn is_move(&self) -> bool { - match *self { - PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true, - _ => false, - } + matches!(self, PlaceContext::NonMutatingUse(NonMutatingUseContext::Move)) } /// Returns `true` if this place context represents a use. From cd01d1696a3a09427429b62cb56701c03baf593b Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 17 Oct 2020 22:22:04 +0200 Subject: [PATCH 09/10] Bless mir-opt tests --- ...gation_arg.bar.DestinationPropagation.diff | 2 +- ...gation_arg.foo.DestinationPropagation.diff | 12 +- .../cycle.main.DestinationPropagation.diff | 2 +- .../simple.nrvo.DestinationPropagation.diff | 2 +- ...h.before-SimplifyBranches-final.after.diff | 50 ++++--- .../inline_any_operand.bar.Inline.after.mir | 30 ++-- ...line_trait_method_2.test2.Inline.after.mir | 6 +- .../issue_73223.main.PreCodegen.32bit.diff | 130 ++++++++++-------- .../issue_73223.main.PreCodegen.64bit.diff | 130 ++++++++++-------- ..._73223.main.SimplifyArmIdentity.32bit.diff | 70 ++++------ ..._73223.main.SimplifyArmIdentity.64bit.diff | 70 ++++------ ...nators.test.MultipleReturnTerminators.diff | 20 ++- .../nrvo_simple.nrvo.RenameReturnPlace.diff | 2 +- ..._locals_fixedpoint.foo.SimplifyLocals.diff | 10 +- ...y.try_identity.DestinationPropagation.diff | 18 +-- ..._try.try_identity.SimplifyLocals.after.mir | 8 +- ...le_storage.while_loop.PreCodegen.after.mir | 22 +-- 17 files changed, 261 insertions(+), 323 deletions(-) diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff index dce8800e986c9..ca6b059241b73 100644 --- a/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff +++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff @@ -11,7 +11,7 @@ StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:16:5: 16:13 StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:16:11: 16:12 _3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:16:11: 16:12 - _2 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:16:5: 16:13 + _2 = dummy(_1) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:16:5: 16:13 // mir::Constant // + span: $DIR/copy_propagation_arg.rs:16:5: 16:10 // + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value(Scalar()) } diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff index 2dea530db3d20..0c0fa22800dbd 100644 --- a/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff +++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff @@ -8,12 +8,10 @@ let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:11:15: 11:16 bb0: { -- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:11:9: 11:17 -+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:11:9: 11:17 + StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:11:9: 11:17 StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:11:15: 11:16 _3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:11:15: 11:16 -- _2 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:11:9: 11:17 -+ _1 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:11:9: 11:17 + _2 = dummy(_1) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:11:9: 11:17 // mir::Constant // + span: $DIR/copy_propagation_arg.rs:11:9: 11:14 // + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value(Scalar()) } @@ -21,10 +19,8 @@ bb1: { StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:11:16: 11:17 -- _1 = move _2; // scope 0 at $DIR/copy_propagation_arg.rs:11:5: 11:17 -- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:11:16: 11:17 -+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:11:5: 11:17 -+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:11:16: 11:17 + _1 = move _2; // scope 0 at $DIR/copy_propagation_arg.rs:11:5: 11:17 + StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:11:16: 11:17 _0 = const (); // scope 0 at $DIR/copy_propagation_arg.rs:9:19: 12:2 return; // scope 0 at $DIR/copy_propagation_arg.rs:12:2: 12:2 } diff --git a/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff index 881c296cee77a..4ec2c47981bc7 100644 --- a/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff +++ b/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff @@ -42,7 +42,7 @@ - _3 = _2; // scope 2 at $DIR/cycle.rs:11:13: 11:14 - StorageLive(_4); // scope 3 at $DIR/cycle.rs:12:9: 12:10 - _4 = _3; // scope 3 at $DIR/cycle.rs:12:9: 12:10 -- _1 = move _4; // scope 3 at $DIR/cycle.rs:12:5: 12:10 +- _1 = _3; // scope 3 at $DIR/cycle.rs:12:5: 12:10 - StorageDead(_4); // scope 3 at $DIR/cycle.rs:12:9: 12:10 + nop; // scope 1 at $DIR/cycle.rs:10:9: 10:10 + nop; // scope 1 at $DIR/cycle.rs:10:13: 10:14 diff --git a/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff index 3475d41b50fbd..209b7cd11dcf0 100644 --- a/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff +++ b/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff @@ -23,7 +23,7 @@ StorageLive(_6); // scope 1 at $DIR/simple.rs:6:10: 6:18 _6 = &mut _2; // scope 1 at $DIR/simple.rs:6:10: 6:18 _5 = &mut (*_6); // scope 1 at $DIR/simple.rs:6:10: 6:18 - _3 = move _4(move _5) -> bb1; // scope 1 at $DIR/simple.rs:6:5: 6:19 + _3 = _1(move _5) -> bb1; // scope 1 at $DIR/simple.rs:6:5: 6:19 } bb1: { diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-final.after.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-final.after.diff index f51a08ed73068..b56a898c825d1 100644 --- a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-final.after.diff +++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-final.after.diff @@ -65,21 +65,18 @@ bb0: { - StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 -- StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 -- StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 -- _5 = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 -+ (_4.0: &ViewportPercentageLength) = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 + StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 + StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 + _5 = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 StorageLive(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:18: 22:23 _6 = _2; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:18: 22:23 - (_4.0: &ViewportPercentageLength) = move _5; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 - (_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 +- (_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 ++ (_4.0: &ViewportPercentageLength) = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 ++ (_4.1: &ViewportPercentageLength) = _2; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:23: 22:24 -- StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:23: 22:24 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:23: 22:24 + StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:23: 22:24 _11 = discriminant((*(_4.0: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 - switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 + StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 @@ -102,9 +99,8 @@ discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:21: 27:28 StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:27: 27:28 - StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7 -- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2 + StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2 return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2 } @@ -118,7 +114,7 @@ + nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 + nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 + nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 -+ ((((_0 as Ok).0: ViewportPercentageLength) as Vw).0: f32) = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vw).0: f32) = Add(_15, _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 + nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 + nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 + nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 @@ -141,7 +137,7 @@ + nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:41 + nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:49 + nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:49 -+ ((((_0 as Ok).0: ViewportPercentageLength) as Vh).0: f32) = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:49 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vh).0: f32) = Add(_20, _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:38: 24:49 + nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:48: 24:49 + nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:48: 24:49 + nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:35: 24:50 @@ -164,7 +160,7 @@ + nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 + nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 + nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 -+ ((((_0 as Ok).0: ViewportPercentageLength) as Vmin).0: f32) = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vmin).0: f32) = Add(_25, _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 + nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 + nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 + nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 @@ -187,7 +183,7 @@ + nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:47 + nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:50: 26:55 + nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:50: 26:55 -+ ((((_0 as Ok).0: ViewportPercentageLength) as Vmax).0: f32) = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:55 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vmax).0: f32) = Add(_30, _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:44: 26:55 + nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:54: 26:55 + nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:54: 26:55 + nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:39: 26:56 @@ -217,14 +213,9 @@ - StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 - StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 - goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7 -+ discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2 -+ return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2 - } - - bb7: { +- } +- +- bb7: { - StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:14: 24:17 - _17 = (((*(_4.0: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:14: 24:17 - StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:24: 24:29 @@ -289,10 +280,15 @@ - - bb10: { - ((_0 as Ok).0: ViewportPercentageLength) = move _3; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7 -- discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7 + discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7 - StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7 -- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2 -- return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7 + StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2 + return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2 ++ } ++ ++ bb7: { + StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 + switchInt(_11) -> [0_isize: bb2, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30 } diff --git a/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir index 4d623297f8d68..45df2f288fe1e 100644 --- a/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir @@ -4,15 +4,13 @@ fn bar() -> bool { let mut _0: bool; // return place in scope 0 at $DIR/inline-any-operand.rs:10:13: 10:17 let _1: fn(i32, i32) -> bool {foo}; // in scope 0 at $DIR/inline-any-operand.rs:11:9: 11:10 let mut _2: fn(i32, i32) -> bool {foo}; // in scope 0 at $DIR/inline-any-operand.rs:12:5: 12:6 - let mut _5: i32; // in scope 0 at $DIR/inline-any-operand.rs:12:5: 12:13 - let mut _6: i32; // in scope 0 at $DIR/inline-any-operand.rs:12:5: 12:13 + let mut _3: i32; // in scope 0 at $DIR/inline-any-operand.rs:12:5: 12:13 + let mut _4: i32; // in scope 0 at $DIR/inline-any-operand.rs:12:5: 12:13 scope 1 { debug f => _1; // in scope 1 at $DIR/inline-any-operand.rs:11:9: 11:10 scope 2 { - debug x => _5; // in scope 2 at $DIR/inline-any-operand.rs:16:8: 16:9 - debug y => _6; // in scope 2 at $DIR/inline-any-operand.rs:16:16: 16:17 - let mut _3: i32; // in scope 2 at $DIR/inline-any-operand.rs:12:5: 12:13 - let mut _4: i32; // in scope 2 at $DIR/inline-any-operand.rs:12:5: 12:13 + debug x => _3; // in scope 2 at $DIR/inline-any-operand.rs:16:8: 16:9 + debug y => _4; // in scope 2 at $DIR/inline-any-operand.rs:16:16: 16:17 } } @@ -24,19 +22,13 @@ fn bar() -> bool { // + literal: Const { ty: fn(i32, i32) -> bool {foo}, val: Value(Scalar()) } StorageLive(_2); // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:6 _2 = _1; // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:6 - StorageLive(_5); // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 - _5 = const 1_i32; // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 - StorageLive(_6); // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 - _6 = const -1_i32; // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 - StorageLive(_3); // scope 2 at $DIR/inline-any-operand.rs:17:5: 17:6 - _3 = _5; // scope 2 at $DIR/inline-any-operand.rs:17:5: 17:6 - StorageLive(_4); // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11 - _4 = _6; // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11 - _0 = Eq(move _3, move _4); // scope 2 at $DIR/inline-any-operand.rs:17:5: 17:11 - StorageDead(_4); // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11 - StorageDead(_3); // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11 - StorageDead(_6); // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 - StorageDead(_5); // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 + StorageLive(_3); // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 + _3 = const 1_i32; // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 + StorageLive(_4); // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 + _4 = const -1_i32; // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 + _0 = Eq(_3, _4); // scope 2 at $DIR/inline-any-operand.rs:17:5: 17:11 + StorageDead(_4); // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 + StorageDead(_3); // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 StorageDead(_2); // scope 1 at $DIR/inline-any-operand.rs:12:12: 12:13 StorageDead(_1); // scope 0 at $DIR/inline-any-operand.rs:13:1: 13:2 return; // scope 0 at $DIR/inline-any-operand.rs:13:2: 13:2 diff --git a/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir index 09546205962a4..938fa243e42f8 100644 --- a/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir @@ -7,7 +7,6 @@ fn test2(_1: &dyn X) -> bool { let mut _3: &dyn X; // in scope 0 at $DIR/inline-trait-method_2.rs:5:10: 5:11 scope 1 { debug x => _2; // in scope 1 at $DIR/inline-trait-method_2.rs:9:9: 9:10 - let mut _4: &dyn X; // in scope 1 at $DIR/inline-trait-method_2.rs:5:5: 5:12 } bb0: { @@ -16,16 +15,13 @@ fn test2(_1: &dyn X) -> bool { _3 = &(*_1); // scope 0 at $DIR/inline-trait-method_2.rs:5:10: 5:11 _2 = move _3 as &dyn X (Pointer(Unsize)); // scope 0 at $DIR/inline-trait-method_2.rs:5:10: 5:11 StorageDead(_3); // scope 0 at $DIR/inline-trait-method_2.rs:5:10: 5:11 - StorageLive(_4); // scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:6 - _4 = _2; // scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:6 - _0 = ::y(move _4) -> bb1; // scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:10 + _0 = ::y(_2) -> bb1; // scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:10 // mir::Constant // + span: $DIR/inline-trait-method_2.rs:10:7: 10:8 // + literal: Const { ty: for<'r> fn(&'r dyn X) -> bool {::y}, val: Value(Scalar()) } } bb1: { - StorageDead(_4); // scope 1 at $DIR/inline-trait-method_2.rs:10:9: 10:10 StorageDead(_2); // scope 0 at $DIR/inline-trait-method_2.rs:5:11: 5:12 return; // scope 0 at $DIR/inline-trait-method_2.rs:6:2: 6:2 } diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff index ef7c73068faf6..eaf893bb0b50e 100644 --- a/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff +++ b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff @@ -13,15 +13,21 @@ let mut _11: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _12: &std::fmt::Arguments; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL let _13: std::fmt::Arguments; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _14: &[&str; 3]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _15: &[std::fmt::ArgumentV1; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let _16: [std::fmt::ArgumentV1; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _17: (&&i32, &&i32); // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let _18: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _19: &&i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _14: &[&str]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _15: &[&str; 3]; // 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; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let _18: [std::fmt::ArgumentV1; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _19: (&&i32, &&i32); // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL let _20: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _21: std::fmt::ArgumentV1; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _22: std::fmt::ArgumentV1; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _21: &&i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _22: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _23: std::fmt::ArgumentV1; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _24: &&i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _25: for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _26: std::fmt::ArgumentV1; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _27: &&i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _28: for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 1 { debug split => _1; // in scope 1 at $DIR/issue-73223.rs:2:9: 2:14 let _4: std::option::Option; // in scope 1 at $DIR/issue-73223.rs:7:9: 7:14 @@ -33,29 +39,23 @@ debug left_val => _7; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL debug right_val => _8; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 5 { - debug arg0 => _25; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - debug arg1 => _28; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug arg0 => _24; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug arg1 => _27; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 6 { - debug x => _25; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - debug f => _24; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _23: 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 _24: 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 _25: &&i32; // in scope 6 at $SRC_DIR/std/src/macros.rs:LL:COL + debug x => _24; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + debug f => _25; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + let mut _29: 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 } scope 8 { - debug x => _28; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - debug f => _27; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _26: 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 _27: 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 _28: &&i32; // in scope 8 at $SRC_DIR/std/src/macros.rs:LL:COL + debug x => _27; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + debug f => _28; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + let mut _30: 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 } } scope 10 { - debug pieces => _29; // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - debug args => _31; // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _29: &[&str]; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _30: std::option::Option<&[std::fmt::rt::v1::Argument]>; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _31: &[std::fmt::ArgumentV1]; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL + debug pieces => _14; // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + debug args => _16; // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + let mut _31: std::option::Option<&[std::fmt::rt::v1::Argument]>; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL } } } @@ -75,7 +75,7 @@ discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:2:23: 2:30 StorageLive(_3); // scope 0 at $DIR/issue-73223.rs:3:14: 3:15 _3 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:3:14: 3:15 - _1 = _3; // scope 2 at $DIR/issue-73223.rs:3:20: 3:21 + _1 = ((_2 as Some).0: i32); // scope 2 at $DIR/issue-73223.rs:3:20: 3:21 StorageDead(_3); // scope 0 at $DIR/issue-73223.rs:3:20: 3:21 StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:5:6: 5:7 ((_4 as Some).0: i32) = _1; // scope 1 at $DIR/issue-73223.rs:7:22: 7:27 @@ -88,7 +88,7 @@ // 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), const_param_did: None }, [], Some(promoted[1])) } - (_5.1: &i32) = move _6; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_5.1: &i32) = _6; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _7 = (_5.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -115,79 +115,87 @@ bb2: { StorageLive(_13); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - _14 = const main::promoted[0]; // 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 + _15 = const main::promoted[0]; // 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), 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), const_param_did: None }, [], Some(promoted[0])) } - _29 = move _14 as &[&str] (Pointer(Unsize)); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _14 = _15 as &[&str] (Pointer(Unsize)); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_16); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageLive(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _18 = _7; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - (_17.0: &&i32) = &_18; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_19); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_18); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageLive(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _20 = _8; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _19 = &_20; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - (_17.1: &&i32) = move _19; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageDead(_19); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - _25 = (_17.0: &&i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _28 = (_17.1: &&i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _24 = <&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 + _20 = _7; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_19.0: &&i32) = &_20; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_21); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_22); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _22 = _8; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _21 = &_22; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_19.1: &&i32) = move _21; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageDead(_21); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + _24 = (_19.0: &&i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _27 = (_19.1: &&i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_25); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _25 = <&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(_23); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _23 = 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 _24) -> bb3; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_29); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _29 = 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>>(_25) -> 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: { - (_21.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(move _25) -> bb4; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_23.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(_24) -> 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: { - (_21.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _23; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_23); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _27 = <&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 + (_23.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _29; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_29); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_25); // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageLive(_28); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _28 = <&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(_26); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _26 = 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 _27) -> bb5; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_30); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _30 = 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>>(_28) -> 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: { - (_22.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(move _28) -> bb6; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_26.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(_27) -> 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: { - (_22.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _26; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_26); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _16 = [move _21, move _22]; // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL - _15 = &_16; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - _31 = move _15 as &[std::fmt::ArgumentV1] (Pointer(Unsize)); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageLive(_30); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - discriminant(_30) = 0; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_13.0: &[&str]) = move _29; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_13.1: std::option::Option<&[std::fmt::rt::v1::Argument]>) = move _30; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_13.2: &[std::fmt::ArgumentV1]) = move _31; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_30); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_26.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _30; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_30); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_28); // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL + _18 = [move _23, move _26]; // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL + _17 = &_18; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + _16 = _17 as &[std::fmt::ArgumentV1] (Pointer(Unsize)); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageLive(_31); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + discriminant(_31) = 0; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_13.0: &[&str]) = _14; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_13.1: std::option::Option<&[std::fmt::rt::v1::Argument]>) = move _31; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_13.2: &[std::fmt::ArgumentV1]) = _16; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_31); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_16); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageDead(_14); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL _12 = &_13; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - begin_panic_fmt(move _12); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + begin_panic_fmt(_12); // 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.PreCodegen.64bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff index ef7c73068faf6..eaf893bb0b50e 100644 --- a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff +++ b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff @@ -13,15 +13,21 @@ let mut _11: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _12: &std::fmt::Arguments; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL let _13: std::fmt::Arguments; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _14: &[&str; 3]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _15: &[std::fmt::ArgumentV1; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let _16: [std::fmt::ArgumentV1; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _17: (&&i32, &&i32); // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let _18: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _19: &&i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _14: &[&str]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _15: &[&str; 3]; // 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; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let _18: [std::fmt::ArgumentV1; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _19: (&&i32, &&i32); // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL let _20: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _21: std::fmt::ArgumentV1; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _22: std::fmt::ArgumentV1; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _21: &&i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _22: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _23: std::fmt::ArgumentV1; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _24: &&i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _25: for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _26: std::fmt::ArgumentV1; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _27: &&i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _28: for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 1 { debug split => _1; // in scope 1 at $DIR/issue-73223.rs:2:9: 2:14 let _4: std::option::Option; // in scope 1 at $DIR/issue-73223.rs:7:9: 7:14 @@ -33,29 +39,23 @@ debug left_val => _7; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL debug right_val => _8; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 5 { - debug arg0 => _25; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - debug arg1 => _28; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug arg0 => _24; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug arg1 => _27; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 6 { - debug x => _25; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - debug f => _24; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _23: 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 _24: 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 _25: &&i32; // in scope 6 at $SRC_DIR/std/src/macros.rs:LL:COL + debug x => _24; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + debug f => _25; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + let mut _29: 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 } scope 8 { - debug x => _28; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - debug f => _27; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _26: 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 _27: 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 _28: &&i32; // in scope 8 at $SRC_DIR/std/src/macros.rs:LL:COL + debug x => _27; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + debug f => _28; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + let mut _30: 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 } } scope 10 { - debug pieces => _29; // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - debug args => _31; // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _29: &[&str]; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _30: std::option::Option<&[std::fmt::rt::v1::Argument]>; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _31: &[std::fmt::ArgumentV1]; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL + debug pieces => _14; // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + debug args => _16; // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + let mut _31: std::option::Option<&[std::fmt::rt::v1::Argument]>; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL } } } @@ -75,7 +75,7 @@ discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:2:23: 2:30 StorageLive(_3); // scope 0 at $DIR/issue-73223.rs:3:14: 3:15 _3 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:3:14: 3:15 - _1 = _3; // scope 2 at $DIR/issue-73223.rs:3:20: 3:21 + _1 = ((_2 as Some).0: i32); // scope 2 at $DIR/issue-73223.rs:3:20: 3:21 StorageDead(_3); // scope 0 at $DIR/issue-73223.rs:3:20: 3:21 StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:5:6: 5:7 ((_4 as Some).0: i32) = _1; // scope 1 at $DIR/issue-73223.rs:7:22: 7:27 @@ -88,7 +88,7 @@ // 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), const_param_did: None }, [], Some(promoted[1])) } - (_5.1: &i32) = move _6; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_5.1: &i32) = _6; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _7 = (_5.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -115,79 +115,87 @@ bb2: { StorageLive(_13); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - _14 = const main::promoted[0]; // 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 + _15 = const main::promoted[0]; // 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), 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), const_param_did: None }, [], Some(promoted[0])) } - _29 = move _14 as &[&str] (Pointer(Unsize)); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _14 = _15 as &[&str] (Pointer(Unsize)); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_16); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageLive(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _18 = _7; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - (_17.0: &&i32) = &_18; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_19); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_18); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageLive(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _20 = _8; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _19 = &_20; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - (_17.1: &&i32) = move _19; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageDead(_19); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - _25 = (_17.0: &&i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _28 = (_17.1: &&i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _24 = <&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 + _20 = _7; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_19.0: &&i32) = &_20; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_21); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_22); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _22 = _8; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _21 = &_22; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_19.1: &&i32) = move _21; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageDead(_21); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + _24 = (_19.0: &&i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _27 = (_19.1: &&i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_25); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _25 = <&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(_23); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _23 = 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 _24) -> bb3; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_29); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _29 = 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>>(_25) -> 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: { - (_21.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(move _25) -> bb4; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_23.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(_24) -> 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: { - (_21.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _23; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_23); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _27 = <&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 + (_23.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _29; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_29); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_25); // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageLive(_28); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _28 = <&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(_26); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _26 = 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 _27) -> bb5; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_30); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _30 = 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>>(_28) -> 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: { - (_22.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(move _28) -> bb6; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_26.0: &core::fmt::Opaque) = transmute::<&&i32, &core::fmt::Opaque>(_27) -> 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: { - (_22.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _26; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_26); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _16 = [move _21, move _22]; // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL - _15 = &_16; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - _31 = move _15 as &[std::fmt::ArgumentV1] (Pointer(Unsize)); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageLive(_30); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - discriminant(_30) = 0; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_13.0: &[&str]) = move _29; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_13.1: std::option::Option<&[std::fmt::rt::v1::Argument]>) = move _30; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_13.2: &[std::fmt::ArgumentV1]) = move _31; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_30); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_26.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _30; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_30); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_28); // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL + _18 = [move _23, move _26]; // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL + _17 = &_18; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + _16 = _17 as &[std::fmt::ArgumentV1] (Pointer(Unsize)); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageLive(_31); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + discriminant(_31) = 0; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_13.0: &[&str]) = _14; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_13.1: std::option::Option<&[std::fmt::rt::v1::Argument]>) = move _31; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_13.2: &[std::fmt::ArgumentV1]) = _16; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_31); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_16); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageDead(_14); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL _12 = &_13; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - begin_panic_fmt(move _12); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + begin_panic_fmt(_12); // 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.32bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff index 9039735f6ba38..8e1fefe8a5d0c 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff @@ -62,25 +62,19 @@ debug x => _39; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL debug f => _40; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL let mut _46: 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 _47: 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 _48: &core::fmt::Opaque; // in scope 6 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _49: &&i32; // in scope 6 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _47: &core::fmt::Opaque; // in scope 6 at $SRC_DIR/std/src/macros.rs:LL:COL } scope 8 { debug x => _42; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL debug f => _43; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _50: 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 _51: 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 _52: &core::fmt::Opaque; // in scope 8 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _53: &&i32; // in scope 8 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _48: 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 _49: &core::fmt::Opaque; // in scope 8 at $SRC_DIR/std/src/macros.rs:LL:COL } } scope 10 { debug pieces => _23; // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL debug args => _27; // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _54: &[&str]; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _55: std::option::Option<&[std::fmt::rt::v1::Argument]>; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _56: &[std::fmt::ArgumentV1]; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _50: std::option::Option<&[std::fmt::rt::v1::Argument]>; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL } } } @@ -218,30 +212,24 @@ // + 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(_46); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_47); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _47 = _40; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _46 = 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 _47) -> bb5; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _46 = 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>>(_40) -> bb5; // 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()) } } bb5: { - StorageDead(_47); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_48); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_49); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _49 = _39; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _48 = transmute::<&&i32, &core::fmt::Opaque>(move _49) -> bb6; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_47); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _47 = transmute::<&&i32, &core::fmt::Opaque>(_39) -> bb6; // 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()) } } bb6: { - StorageDead(_49); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_38.0: &core::fmt::Opaque) = move _48; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_38.0: &core::fmt::Opaque) = move _47; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL (_38.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _46; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_48); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_47); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL StorageDead(_46); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL StorageDead(_40); // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL StorageDead(_39); // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL @@ -253,32 +241,26 @@ // 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(_50); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_51); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _51 = _43; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _50 = 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 _51) -> bb7; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_48); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _48 = 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>>(_43) -> bb7; // 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()) } } bb7: { - StorageDead(_51); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_52); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_53); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _53 = _42; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _52 = transmute::<&&i32, &core::fmt::Opaque>(move _53) -> bb8; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_49); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _49 = transmute::<&&i32, &core::fmt::Opaque>(_42) -> bb8; // 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()) } } bb8: { - StorageDead(_53); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_41.0: &core::fmt::Opaque) = move _52; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_41.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _50; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_52); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_50); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_41.0: &core::fmt::Opaque) = move _49; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_41.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _48; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_49); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_48); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL StorageDead(_43); // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL StorageDead(_42); // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL _30 = [move _38, move _41]; // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL @@ -290,18 +272,12 @@ _28 = _29; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL _27 = move _28 as &[std::fmt::ArgumentV1] (Pointer(Unsize)); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageDead(_28); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageLive(_54); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _54 = _23; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_55); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - discriminant(_55) = 0; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_56); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _56 = _27; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_22.0: &[&str]) = move _54; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_22.1: std::option::Option<&[std::fmt::rt::v1::Argument]>) = move _55; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_22.2: &[std::fmt::ArgumentV1]) = move _56; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_56); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_55); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_54); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_50); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + discriminant(_50) = 0; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_22.0: &[&str]) = _23; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_22.1: std::option::Option<&[std::fmt::rt::v1::Argument]>) = move _50; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_22.2: &[std::fmt::ArgumentV1]) = _27; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_50); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL StorageDead(_27); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageDead(_23); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL _21 = &_22; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL 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 9039735f6ba38..8e1fefe8a5d0c 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff @@ -62,25 +62,19 @@ debug x => _39; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL debug f => _40; // in scope 6 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL let mut _46: 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 _47: 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 _48: &core::fmt::Opaque; // in scope 6 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _49: &&i32; // in scope 6 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _47: &core::fmt::Opaque; // in scope 6 at $SRC_DIR/std/src/macros.rs:LL:COL } scope 8 { debug x => _42; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL debug f => _43; // in scope 8 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _50: 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 _51: 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 _52: &core::fmt::Opaque; // in scope 8 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _53: &&i32; // in scope 8 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _48: 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 _49: &core::fmt::Opaque; // in scope 8 at $SRC_DIR/std/src/macros.rs:LL:COL } } scope 10 { debug pieces => _23; // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL debug args => _27; // in scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _54: &[&str]; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _55: std::option::Option<&[std::fmt::rt::v1::Argument]>; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _56: &[std::fmt::ArgumentV1]; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _50: std::option::Option<&[std::fmt::rt::v1::Argument]>; // in scope 10 at $SRC_DIR/std/src/macros.rs:LL:COL } } } @@ -218,30 +212,24 @@ // + 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(_46); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_47); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _47 = _40; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _46 = 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 _47) -> bb5; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _46 = 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>>(_40) -> bb5; // 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()) } } bb5: { - StorageDead(_47); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_48); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_49); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _49 = _39; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _48 = transmute::<&&i32, &core::fmt::Opaque>(move _49) -> bb6; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_47); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _47 = transmute::<&&i32, &core::fmt::Opaque>(_39) -> bb6; // 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()) } } bb6: { - StorageDead(_49); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_38.0: &core::fmt::Opaque) = move _48; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_38.0: &core::fmt::Opaque) = move _47; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL (_38.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _46; // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_48); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_47); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL StorageDead(_46); // scope 7 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL StorageDead(_40); // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL StorageDead(_39); // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL @@ -253,32 +241,26 @@ // 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(_50); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_51); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _51 = _43; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _50 = 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 _51) -> bb7; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_48); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _48 = 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>>(_43) -> bb7; // 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()) } } bb7: { - StorageDead(_51); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_52); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_53); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _53 = _42; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _52 = transmute::<&&i32, &core::fmt::Opaque>(move _53) -> bb8; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_49); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _49 = transmute::<&&i32, &core::fmt::Opaque>(_42) -> bb8; // 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()) } } bb8: { - StorageDead(_53); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_41.0: &core::fmt::Opaque) = move _52; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_41.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _50; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_52); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_50); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_41.0: &core::fmt::Opaque) = move _49; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_41.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _48; // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_49); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_48); // scope 9 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL StorageDead(_43); // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL StorageDead(_42); // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL _30 = [move _38, move _41]; // scope 5 at $SRC_DIR/std/src/macros.rs:LL:COL @@ -290,18 +272,12 @@ _28 = _29; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL _27 = move _28 as &[std::fmt::ArgumentV1] (Pointer(Unsize)); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageDead(_28); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageLive(_54); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _54 = _23; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_55); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - discriminant(_55) = 0; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_56); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _56 = _27; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_22.0: &[&str]) = move _54; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_22.1: std::option::Option<&[std::fmt::rt::v1::Argument]>) = move _55; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_22.2: &[std::fmt::ArgumentV1]) = move _56; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_56); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_55); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_54); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_50); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + discriminant(_50) = 0; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_22.0: &[&str]) = _23; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_22.1: std::option::Option<&[std::fmt::rt::v1::Argument]>) = move _50; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_22.2: &[std::fmt::ArgumentV1]) = _27; // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_50); // scope 10 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL StorageDead(_27); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageDead(_23); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL _21 = &_22; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL diff --git a/src/test/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff b/src/test/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff index 997c021d2ef21..eaf2ba3265653 100644 --- a/src/test/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff +++ b/src/test/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff @@ -4,27 +4,25 @@ fn test(_1: bool) -> () { debug x => _1; // in scope 0 at $DIR/multiple_return_terminators.rs:4:9: 4:10 let mut _0: (); // return place in scope 0 at $DIR/multiple_return_terminators.rs:4:18: 4:18 - let mut _2: bool; // in scope 0 at $DIR/multiple_return_terminators.rs:5:8: 5:9 bb0: { - StorageLive(_2); // scope 0 at $DIR/multiple_return_terminators.rs:5:8: 5:9 - _2 = _1; // scope 0 at $DIR/multiple_return_terminators.rs:5:8: 5:9 - switchInt(_2) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/multiple_return_terminators.rs:5:5: 9:6 + switchInt(_1) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/multiple_return_terminators.rs:5:5: 9:6 } bb1: { _0 = const (); // scope 0 at $DIR/multiple_return_terminators.rs:7:12: 9:6 - goto -> bb3; // scope 0 at $DIR/multiple_return_terminators.rs:5:5: 9:6 +- goto -> bb3; // scope 0 at $DIR/multiple_return_terminators.rs:5:5: 9:6 ++ return; // scope 0 at $DIR/multiple_return_terminators.rs:5:5: 9:6 } bb2: { _0 = const (); // scope 0 at $DIR/multiple_return_terminators.rs:5:10: 7:6 - goto -> bb3; // scope 0 at $DIR/multiple_return_terminators.rs:5:5: 9:6 - } - - bb3: { - StorageDead(_2); // scope 0 at $DIR/multiple_return_terminators.rs:10:1: 10:2 - return; // scope 0 at $DIR/multiple_return_terminators.rs:10:2: 10:2 +- goto -> bb3; // scope 0 at $DIR/multiple_return_terminators.rs:5:5: 9:6 +- } +- +- bb3: { +- return; // scope 0 at $DIR/multiple_return_terminators.rs:10:2: 10:2 ++ return; // scope 0 at $DIR/multiple_return_terminators.rs:5:5: 9:6 } } diff --git a/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff b/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff index f438eaa002780..d8520077ceb40 100644 --- a/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff +++ b/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff @@ -27,7 +27,7 @@ - _6 = &mut _2; // scope 1 at $DIR/nrvo-simple.rs:6:10: 6:18 + _6 = &mut _0; // scope 1 at $DIR/nrvo-simple.rs:6:10: 6:18 _5 = &mut (*_6); // scope 1 at $DIR/nrvo-simple.rs:6:10: 6:18 - _3 = move _4(move _5) -> bb1; // scope 1 at $DIR/nrvo-simple.rs:6:5: 6:19 + _3 = _1(move _5) -> bb1; // scope 1 at $DIR/nrvo-simple.rs:6:5: 6:19 } bb1: { diff --git a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff index 45808962bb564..528d205b7411c 100644 --- a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff @@ -10,7 +10,7 @@ let mut _5: isize; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:13: 4:20 let _6: u8; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19 let mut _7: bool; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20 - let mut _8: u8; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13 +- let mut _8: u8; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13 scope 1 { debug a => _6; // in scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19 } @@ -43,10 +43,10 @@ StorageLive(_6); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19 _6 = (((_1.0: std::option::Option) as Some).0: u8); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19 StorageLive(_7); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20 - StorageLive(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13 - _8 = _6; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13 - _7 = Gt(move _8, const 42_u8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20 - StorageDead(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:19: 5:20 +- StorageLive(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13 +- _8 = _6; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13 + _7 = Gt(_6, const 42_u8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20 +- StorageDead(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:19: 5:20 switchInt(_7) -> [false: bb4, otherwise: bb5]; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:9: 7:10 } diff --git a/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff b/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff index 12a6617cc5a27..fa13e7cce8880 100644 --- a/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff +++ b/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff @@ -35,23 +35,19 @@ } } scope 6 { -- debug self => _4; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL -+ debug self => _0; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + debug self => _4; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL } bb0: { StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:8:9: 8:10 - StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:8:13: 8:15 -- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:8:13: 8:14 -- _4 = _1; // scope 0 at $DIR/simplify_try.rs:8:13: 8:14 -- _3 = move _4; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL -- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:8:14: 8:15 -- _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:8:14: 8:15 + nop; // scope 0 at $DIR/simplify_try.rs:8:13: 8:15 -+ nop; // scope 0 at $DIR/simplify_try.rs:8:13: 8:14 -+ _0 = _1; // scope 0 at $DIR/simplify_try.rs:8:13: 8:14 -+ nop; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL -+ nop; // scope 0 at $DIR/simplify_try.rs:8:14: 8:15 + StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:8:13: 8:14 + _4 = _1; // scope 0 at $DIR/simplify_try.rs:8:13: 8:14 +- _3 = _1; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL ++ _0 = _1; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:8:14: 8:15 +- _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:8:14: 8:15 + _5 = discriminant(_0); // scope 0 at $DIR/simplify_try.rs:8:14: 8:15 goto -> bb1; // scope 0 at $DIR/simplify_try.rs:8:14: 8:15 } diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir index 508f2705d0701..93e3f1a3799d1 100644 --- a/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir +++ b/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir @@ -3,6 +3,7 @@ fn try_identity(_1: std::result::Result) -> std::result::Result { debug x => _1; // in scope 0 at $DIR/simplify_try.rs:7:17: 7:18 let mut _0: std::result::Result; // return place in scope 0 at $DIR/simplify_try.rs:7:41: 7:57 + let mut _2: std::result::Result; // in scope 0 at $DIR/simplify_try.rs:8:13: 8:14 scope 1 { debug y => ((_0 as Ok).0: u32); // in scope 1 at $DIR/simplify_try.rs:8:9: 8:10 } @@ -23,11 +24,14 @@ fn try_identity(_1: std::result::Result) -> std::result::Result _0; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + debug self => _2; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL } bb0: { - _0 = _1; // scope 0 at $DIR/simplify_try.rs:8:13: 8:14 + StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:8:13: 8:14 + _2 = _1; // scope 0 at $DIR/simplify_try.rs:8:13: 8:14 + _0 = _1; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:8:14: 8:15 return; // scope 0 at $DIR/simplify_try.rs:10:2: 10:2 } } diff --git a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir index c27c68d870247..37ed8688c9fbc 100644 --- a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir +++ b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir @@ -4,22 +4,17 @@ fn while_loop(_1: bool) -> () { debug c => _1; // in scope 0 at $DIR/while-storage.rs:9:15: 9:16 let mut _0: (); // return place in scope 0 at $DIR/while-storage.rs:9:24: 9:24 let mut _2: bool; // in scope 0 at $DIR/while-storage.rs:10:11: 10:22 - let mut _3: bool; // in scope 0 at $DIR/while-storage.rs:10:20: 10:21 - let mut _4: bool; // in scope 0 at $DIR/while-storage.rs:11:12: 11:23 - let mut _5: bool; // in scope 0 at $DIR/while-storage.rs:11:21: 11:22 + let mut _3: bool; // in scope 0 at $DIR/while-storage.rs:11:12: 11:23 bb0: { StorageLive(_2); // scope 0 at $DIR/while-storage.rs:10:11: 10:22 - StorageLive(_3); // scope 0 at $DIR/while-storage.rs:10:20: 10:21 - _3 = _1; // scope 0 at $DIR/while-storage.rs:10:20: 10:21 - _2 = get_bool(move _3) -> bb1; // scope 0 at $DIR/while-storage.rs:10:11: 10:22 + _2 = get_bool(_1) -> bb1; // scope 0 at $DIR/while-storage.rs:10:11: 10:22 // mir::Constant // + span: $DIR/while-storage.rs:10:11: 10:19 // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value(Scalar()) } } bb1: { - StorageDead(_3); // scope 0 at $DIR/while-storage.rs:10:21: 10:22 switchInt(_2) -> [false: bb2, otherwise: bb3]; // scope 0 at $DIR/while-storage.rs:10:5: 14:6 } @@ -29,29 +24,26 @@ fn while_loop(_1: bool) -> () { } bb3: { - StorageLive(_4); // scope 0 at $DIR/while-storage.rs:11:12: 11:23 - StorageLive(_5); // scope 0 at $DIR/while-storage.rs:11:21: 11:22 - _5 = _1; // scope 0 at $DIR/while-storage.rs:11:21: 11:22 - _4 = get_bool(move _5) -> bb4; // scope 0 at $DIR/while-storage.rs:11:12: 11:23 + StorageLive(_3); // scope 0 at $DIR/while-storage.rs:11:12: 11:23 + _3 = get_bool(_1) -> bb4; // scope 0 at $DIR/while-storage.rs:11:12: 11:23 // mir::Constant // + span: $DIR/while-storage.rs:11:12: 11:20 // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value(Scalar()) } } bb4: { - StorageDead(_5); // scope 0 at $DIR/while-storage.rs:11:22: 11:23 - switchInt(_4) -> [false: bb5, otherwise: bb6]; // scope 0 at $DIR/while-storage.rs:11:9: 13:10 + switchInt(_3) -> [false: bb5, otherwise: bb6]; // scope 0 at $DIR/while-storage.rs:11:9: 13:10 } bb5: { - StorageDead(_4); // scope 0 at $DIR/while-storage.rs:14:5: 14:6 + StorageDead(_3); // scope 0 at $DIR/while-storage.rs:14:5: 14:6 StorageDead(_2); // scope 0 at $DIR/while-storage.rs:14:5: 14:6 goto -> bb0; // scope 0 at $DIR/while-storage.rs:10:5: 14:6 } bb6: { _0 = const (); // scope 0 at $DIR/while-storage.rs:12:13: 12:18 - StorageDead(_4); // scope 0 at $DIR/while-storage.rs:14:5: 14:6 + StorageDead(_3); // scope 0 at $DIR/while-storage.rs:14:5: 14:6 goto -> bb7; // scope 0 at $DIR/while-storage.rs:1:1: 1:1 } From cf5013849bfb2e07be3f15359c814694f8299f91 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sun, 18 Oct 2020 17:53:25 +0200 Subject: [PATCH 10/10] Extend comment --- compiler/rustc_mir/src/transform/basic_block_copy_prop.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs b/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs index 950f7255e6b1d..83290356e933d 100644 --- a/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs +++ b/compiler/rustc_mir/src/transform/basic_block_copy_prop.rs @@ -252,7 +252,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for ReplaceUseVisitor<'a, 'tcx> { // _2 = _1; // use(move _2); <- can replace with `use(_1)` // Or: - // use(move _2, move _1); <- can replace with `use(_1, _1)` + // use(move _2, move _1); <- can replace with `use(_1, _1)`, if the inputs may alias (*) if let Operand::Copy(place) | Operand::Move(place) = operand { if let Some(local) = place.as_local() { if let Some(known_place) = self.local_values.get(local) { @@ -261,6 +261,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for ReplaceUseVisitor<'a, 'tcx> { } } } + + // (*) Some MIR statements and terminators may forbid aliasing between some of the places + // they access. This only happens between output and input places, never between multiple + // input places, so what this pass is safe: Any local that is mutated will invalidate all + // affected locals and so won't be replaced or used as a replacement. } }