diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index 5eba474a60c7a..5dadfba081aad 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -1,7 +1,9 @@ use rustc_index::bit_set::DenseBitSet; -use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; +use rustc_middle::mir::visit::{ + MutatingUseContext, NonMutatingUseContext, PlaceContext, VisitPlacesWith, Visitor, +}; use rustc_middle::mir::{ - self, CallReturnPlaces, Local, Location, Place, StatementKind, TerminatorEdges, + self, CallReturnPlaces, Local, Location, Place, StatementKind, TerminatorEdges, TerminatorKind, }; use crate::{Analysis, Backward, GenKill}; @@ -23,9 +25,13 @@ use crate::{Analysis, Backward, GenKill}; /// [`MaybeBorrowedLocals`]: super::MaybeBorrowedLocals /// [flow-test]: https://github.com/rust-lang/rust/blob/a08c47310c7d49cbdc5d7afb38408ba519967ecd/src/test/ui/mir-dataflow/liveness-ptr.rs /// [liveness]: https://en.wikipedia.org/wiki/Live_variable_analysis -pub struct MaybeLiveLocals; +pub struct MaybeLiveLocals(pub F); -impl<'tcx> Analysis<'tcx> for MaybeLiveLocals { +impl<'tcx, F, I> Analysis<'tcx> for MaybeLiveLocals +where + F: Fn(Location) -> I, + I: Iterator, +{ type Domain = DenseBitSet; type Direction = Backward; @@ -40,6 +46,26 @@ impl<'tcx> Analysis<'tcx> for MaybeLiveLocals { // No variables are live until we observe a use } + fn apply_early_statement_effect( + &mut self, + state: &mut Self::Domain, + statement: &mir::Statement<'tcx>, + location: Location, + ) { + let mut accesses_indirect = false; + VisitPlacesWith(|place: Place<'tcx>, _: PlaceContext| { + accesses_indirect |= place.is_indirect(); + }) + .visit_statement(statement, location); + if accesses_indirect { + // We do not track what happens to the addresses of borrowed locals. This means + // that this indirect read/write may be to any borrowed local. + for local in (self.0)(location) { + state.gen_(local); + } + } + } + fn apply_primary_statement_effect( &mut self, state: &mut Self::Domain, @@ -49,6 +75,44 @@ impl<'tcx> Analysis<'tcx> for MaybeLiveLocals { TransferFunction(state).visit_statement(statement, location); } + fn apply_early_terminator_effect<'mir>( + &mut self, + state: &mut Self::Domain, + terminator: &'mir mir::Terminator<'tcx>, + location: Location, + ) { + let may_access_borrowed_locals = match terminator.kind { + TerminatorKind::CoroutineDrop + | TerminatorKind::FalseEdge { .. } + | TerminatorKind::FalseUnwind { .. } + | TerminatorKind::Goto { .. } + | TerminatorKind::Return + | TerminatorKind::Unreachable + | TerminatorKind::UnwindResume + | TerminatorKind::UnwindTerminate(_) => false, + + TerminatorKind::Assert { cond: ref operand, .. } + | TerminatorKind::SwitchInt { discr: ref operand, .. } => { + operand.place().is_some_and(|place| place.is_indirect()) + } + + // Those terminators may call arbitrary code. + TerminatorKind::Call { .. } + | TerminatorKind::Drop { .. } + | TerminatorKind::InlineAsm { .. } + | TerminatorKind::TailCall { .. } + | TerminatorKind::Yield { .. } => true, + }; + if may_access_borrowed_locals { + // We do not track what happens to the addresses of borrowed locals. This means that this + // terminator may know the address of any borrowed local. And it may do anything with it + // including reading and writing to it. + for local in (self.0)(location) { + state.gen_(local); + } + } + } + fn apply_primary_terminator_effect<'mir>( &mut self, state: &mut Self::Domain, @@ -155,6 +219,9 @@ impl DefUse { match context { PlaceContext::NonUse(_) => DefUse::NonUse, + // Treat derefs as a use of the base local. `*p = 4` is not a def of `p` but a use. + _ if place.is_indirect() => DefUse::Use, + PlaceContext::MutatingUse( MutatingUseContext::Call | MutatingUseContext::Yield @@ -162,10 +229,7 @@ impl DefUse { | MutatingUseContext::Store | MutatingUseContext::Deinit, ) => { - // Treat derefs as a use of the base local. `*p = 4` is not a def of `p` but a use. - if place.is_indirect() { - DefUse::Use - } else if place.projection.is_empty() { + if place.projection.is_empty() { DefUse::Def } else { DefUse::PartialWrite @@ -174,9 +238,7 @@ impl DefUse { // Setting the discriminant is not a use because it does no reading, but it is also not // a def because it does not overwrite the whole place - PlaceContext::MutatingUse(MutatingUseContext::SetDiscriminant) => { - if place.is_indirect() { DefUse::Use } else { DefUse::PartialWrite } - } + PlaceContext::MutatingUse(MutatingUseContext::SetDiscriminant) => DefUse::PartialWrite, // All other contexts are uses... PlaceContext::MutatingUse( diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index a899ec1fa8846..763a0f94fabb5 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -53,8 +53,9 @@ pub fn sanity_check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { } if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_liveness).is_some() { - let flow_liveness = - MaybeLiveLocals.iterate_to_fixpoint(tcx, body, None).into_results_cursor(body); + let flow_liveness = MaybeLiveLocals(|_| std::iter::empty()) + .iterate_to_fixpoint(tcx, body, None) + .into_results_cursor(body); sanity_check_via_rustc_peek(tcx, flow_liveness); } @@ -245,7 +246,11 @@ where } } -impl<'tcx> RustcPeekAt<'tcx> for MaybeLiveLocals { +impl<'tcx, F, I> RustcPeekAt<'tcx> for MaybeLiveLocals +where + F: Fn(Location) -> I, + I: Iterator, +{ fn peek_at( &self, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index c1cd2788348a6..5b0a4d662ea51 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -708,8 +708,9 @@ fn locals_live_across_suspend_points<'tcx>( ); // Calculate the liveness of MIR locals ignoring borrows. - let mut liveness = - MaybeLiveLocals.iterate_to_fixpoint(tcx, body, Some("coroutine")).into_results_cursor(body); + let mut liveness = MaybeLiveLocals(|_| std::iter::empty()) + .iterate_to_fixpoint(tcx, body, Some("coroutine")) + .into_results_cursor(body); let mut storage_liveness_map = IndexVec::from_elem(None, &body.basic_blocks); let mut live_locals_at_suspension_points = Vec::new(); diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 74c22ff10c198..70d31310de014 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -52,13 +52,13 @@ //! does not currently care about what the value in `q` is (and vice versa). We formalize the //! notion of "does not care what the value in `q` is" by checking the *liveness* of `q`. //! -//! Because of the difficulty of computing liveness of places that have their address taken, we do -//! not even attempt to do it. Any places that are in a local that has its address taken is -//! excluded from the optimization. -//! //! The first two conditions are simple structural requirements on the `Assign` statements that can //! be trivially checked. The third requirement however is more difficult and costly to check. //! +//! If a local has its address taken, we consider that any indirect write may write to it, and any +//! indirect read reads it. Since terminators may do anything, we conservatively consider them to +//! both read and write to all borrowed locals. +//! //! ## Current implementation //! //! The current implementation relies on live range computation to check for conflicts. We only @@ -144,9 +144,9 @@ use rustc_index::{IndexVec, newtype_index}; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, VisitPlacesWith, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; -use rustc_mir_dataflow::impls::{DefUse, MaybeLiveLocals}; -use rustc_mir_dataflow::points::DenseLocationMap; -use rustc_mir_dataflow::{Analysis, Results}; +use rustc_mir_dataflow::Analysis; +use rustc_mir_dataflow::impls::{DefUse, MaybeBorrowedLocals, MaybeLiveLocals}; +use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex}; use tracing::{debug, trace}; pub(super) struct DestinationPropagation; @@ -161,21 +161,18 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation { let def_id = body.source.def_id(); trace!(?def_id); - let borrowed = rustc_mir_dataflow::impls::borrowed_locals(body); - - let candidates = Candidates::find(body, &borrowed); + let candidates = Candidates::find(body); trace!(?candidates); if candidates.c.is_empty() { return; } - let live = MaybeLiveLocals.iterate_to_fixpoint(tcx, body, Some("MaybeLiveLocals-DestProp")); - let points = DenseLocationMap::new(body); let mut relevant = RelevantLocals::compute(&candidates, body.local_decls.len()); - let mut live = save_as_intervals(&points, body, &relevant, live.results); + let borrowed = save_borrowed_locals(tcx, &points, body, &relevant); + let mut live = save_value_liveness(tcx, &points, body, &relevant, &borrowed); - dest_prop_mir_dump(tcx, body, &points, &live, &relevant); + dest_prop_mir_dump(tcx, body, &points, &borrowed, &live, &relevant); let mut merged_locals = DenseBitSet::new_empty(body.local_decls.len()); @@ -382,8 +379,8 @@ impl Candidates { /// Collects the candidates for merging. /// /// This is responsible for enforcing the first and third bullet point. - fn find(body: &Body<'_>, borrowed: &DenseBitSet) -> Candidates { - let mut visitor = FindAssignments { body, candidates: Default::default(), borrowed }; + fn find(body: &Body<'_>) -> Candidates { + let mut visitor = FindAssignments { body, candidates: Default::default() }; visitor.visit_body(body); Candidates { c: visitor.candidates } @@ -393,7 +390,6 @@ impl Candidates { struct FindAssignments<'a, 'tcx> { body: &'a Body<'tcx>, candidates: Vec<(Local, Local)>, - borrowed: &'a DenseBitSet, } impl<'tcx> Visitor<'tcx> for FindAssignments<'_, 'tcx> { @@ -405,12 +401,6 @@ impl<'tcx> Visitor<'tcx> for FindAssignments<'_, 'tcx> { && let Some(src) = lhs.as_local() && let Some(dest) = rhs.as_local() { - // As described at the top of the file, we do not go near things that have - // their address taken. - if self.borrowed.contains(src) || self.borrowed.contains(dest) { - return; - } - // As described at the top of this file, we do not touch locals which have // different types. let src_ty = self.body.local_decls()[src].ty; @@ -445,10 +435,18 @@ fn dest_prop_mir_dump<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, points: &DenseLocationMap, + borrowed: &SparseIntervalMatrix, live: &SparseIntervalMatrix, relevant: &RelevantLocals, ) { - let locals_live_at = |location| { + let borrowed_at = |location| { + borrowed + .rows() + .filter(|&r| borrowed.contains(r, location)) + .map(|rl| relevant.original[rl]) + .collect::>() + }; + let live_at = |location| { live.rows() .filter(|&r| live.contains(r, location)) .map(|rl| relevant.original[rl]) @@ -458,13 +456,15 @@ fn dest_prop_mir_dump<'tcx>( if let Some(dumper) = MirDumper::new(tcx, "DestinationPropagation-dataflow", body) { let extra_data = &|pass_where, w: &mut dyn std::io::Write| { if let PassWhere::BeforeLocation(loc) = pass_where { + let borrowed = borrowed_at(points.point_from_location(loc)); + writeln!(w, " // borrowed: {:?}", borrowed)?; let location = TwoStepIndex::new(points, loc, Effect::Before); - let live = locals_live_at(location); + let live = live_at(location); writeln!(w, " // before: {:?} => {:?}", location, live)?; } if let PassWhere::AfterLocation(loc) = pass_where { let location = TwoStepIndex::new(points, loc, Effect::After); - let live = locals_live_at(location); + let live = live_at(location); writeln!(w, " // after: {:?} => {:?}", location, live)?; } Ok(()) @@ -503,15 +503,90 @@ impl TwoStepIndex { } } -/// Add points depending on the result of the given dataflow analysis. -fn save_as_intervals<'tcx>( +fn save_borrowed_locals<'tcx>( + tcx: TyCtxt<'tcx>, + elements: &DenseLocationMap, + body: &Body<'tcx>, + relevant: &RelevantLocals, +) -> SparseIntervalMatrix { + let live = + MaybeBorrowedLocals.iterate_to_fixpoint(tcx, body, Some("MaybeBorrowedLocals-DestProp")); + let mut analysis = live.analysis; + let results = live.results; + + let mut values = SparseIntervalMatrix::new(elements.num_points()); + let mut state = analysis.bottom_value(body); + let reachable_blocks = traversal::reachable_as_bitset(body); + + let append_at = |values: &mut SparseIntervalMatrix<_, _>, state: &DenseBitSet, point| { + for (relevant, &original) in relevant.original.iter_enumerated() { + if state.contains(original) { + values.append(relevant, point); + } + } + }; + + // Iterate blocks in increasing order, to visit locations in increasing order. This + // allows to use the more efficient `append` method to interval sets. + for block in body.basic_blocks.indices() { + if !reachable_blocks.contains(block) { + continue; + } + + state.clone_from(&results[block]); + let block_data = &body.basic_blocks[block]; + let mut point = elements.entry_point(block); + + for (statement_index, stmt) in block_data.statements.iter().enumerate() { + let loc = Location { block, statement_index }; + analysis.apply_early_statement_effect(&mut state, stmt, loc); + analysis.apply_primary_statement_effect(&mut state, stmt, loc); + + debug_assert_eq!(point, elements.point_from_location(loc)); + append_at(&mut values, &state, point); + + point = PointIndex::from_u32(point.as_u32() + 1); + } + + let loc = Location { block, statement_index: block_data.statements.len() }; + let term = block_data.terminator(); + analysis.apply_early_terminator_effect(&mut state, term, loc); + analysis.apply_primary_terminator_effect(&mut state, term, loc); + + debug_assert_eq!(point, elements.point_from_location(loc)); + append_at(&mut values, &state, point); + } + + values +} + +fn save_value_liveness<'tcx>( + tcx: TyCtxt<'tcx>, elements: &DenseLocationMap, body: &Body<'tcx>, relevant: &RelevantLocals, - results: Results>, + borrowed: &SparseIntervalMatrix, ) -> SparseIntervalMatrix { + // Return the set of borrowed locals at the given location. Those will be marked as live if the + // statement contains an indirect read or write, or if the terminator may read/write to it. + let borrowed_locals_at = |location| { + let borrowed_ref = &borrowed; // Trick `move` closure. + let location = elements.point_from_location(location); + borrowed + .rows() + .filter(move |&r| borrowed_ref.contains(r, location)) + .map(|rl| relevant.original[rl]) + }; + let live = MaybeLiveLocals(borrowed_locals_at).iterate_to_fixpoint( + tcx, + body, + Some("MaybeLiveLocals-DestProp"), + ); + let mut analysis = live.analysis; + let results = live.results; + let mut values = SparseIntervalMatrix::new(2 * elements.num_points()); - let mut state = MaybeLiveLocals.bottom_value(body); + let mut state = analysis.bottom_value(body); let reachable_blocks = traversal::reachable_as_bitset(body); let two_step_loc = |location, effect| TwoStepIndex::new(elements, location, effect); @@ -537,7 +612,9 @@ fn save_as_intervals<'tcx>( let loc = Location { block, statement_index: block_data.statements.len() }; let term = block_data.terminator(); + let mut twostep = two_step_loc(loc, Effect::After); + analysis.apply_early_terminator_effect(&mut state, term, loc); append_at(&mut values, &state, twostep); // Ensure we have a non-zero live range even for dead stores. This is done by marking all // the written-to locals as live in the second half of the statement. @@ -557,14 +634,14 @@ fn save_as_intervals<'tcx>( twostep = TwoStepIndex::from_u32(twostep.as_u32() + 1); debug_assert_eq!(twostep, two_step_loc(loc, Effect::Before)); - MaybeLiveLocals.apply_early_terminator_effect(&mut state, term, loc); - MaybeLiveLocals.apply_primary_terminator_effect(&mut state, term, loc); + analysis.apply_primary_terminator_effect(&mut state, term, loc); append_at(&mut values, &state, twostep); for (statement_index, stmt) in block_data.statements.iter().enumerate().rev() { let loc = Location { block, statement_index }; twostep = TwoStepIndex::from_u32(twostep.as_u32() + 1); debug_assert_eq!(twostep, two_step_loc(loc, Effect::After)); + analysis.apply_early_statement_effect(&mut state, stmt, loc); append_at(&mut values, &state, twostep); // Like terminators, ensure we have a non-zero live range even for dead stores. // Some rvalues interleave reads and writes, for instance `Rvalue::Aggregate`, see @@ -597,8 +674,7 @@ fn save_as_intervals<'tcx>( twostep = TwoStepIndex::from_u32(twostep.as_u32() + 1); debug_assert_eq!(twostep, two_step_loc(loc, Effect::Before)); - MaybeLiveLocals.apply_early_statement_effect(&mut state, stmt, loc); - MaybeLiveLocals.apply_primary_statement_effect(&mut state, stmt, loc); + analysis.apply_primary_statement_effect(&mut state, stmt, loc); // ... but reads from operands are marked as live here so they do not conflict with // the all the writes we manually marked as live in the second half of the statement. append_at(&mut values, &state, twostep); diff --git a/tests/codegen-llvm/function-arguments.rs b/tests/codegen-llvm/function-arguments.rs index a0744e44c61ec..0355a587ea973 100644 --- a/tests/codegen-llvm/function-arguments.rs +++ b/tests/codegen-llvm/function-arguments.rs @@ -185,7 +185,7 @@ pub fn _box(x: Box) -> Box { // With a custom allocator, it should *not* have `noalias`. (See // for why.) The second argument is the allocator, // which is a reference here that still carries `noalias` as usual. -// CHECK: @_box_custom(ptr noundef nonnull align 4 %x.0, ptr noalias noundef nonnull readonly align 1{{( captures\(address, read_provenance\))?}} %x.1) +// CHECK: @_box_custom(ptr noundef nonnull align 4 %0, ptr noalias noundef nonnull readonly align 1{{( captures\(address, read_provenance\))?}} %1) #[no_mangle] pub fn _box_custom(x: Box) { drop(x) diff --git a/tests/codegen-llvm/noalias-box-off.rs b/tests/codegen-llvm/noalias-box-off.rs index 664c79502804e..e3a9eaa654772 100644 --- a/tests/codegen-llvm/noalias-box-off.rs +++ b/tests/codegen-llvm/noalias-box-off.rs @@ -4,7 +4,7 @@ // CHECK-LABEL: @box_should_not_have_noalias_if_disabled( // CHECK-NOT: noalias -// CHECK-SAME: %foo) +// CHECK-SAME: %0) #[no_mangle] pub fn box_should_not_have_noalias_if_disabled(foo: Box) { drop(foo); diff --git a/tests/codegen-llvm/zip.rs b/tests/codegen-llvm/zip.rs index 38ecf7c15c675..cd8d6463d8a2b 100644 --- a/tests/codegen-llvm/zip.rs +++ b/tests/codegen-llvm/zip.rs @@ -1,7 +1,9 @@ -//@ compile-flags: -Cno-prepopulate-passes -Copt-level=3 +//@ compile-flags: -Copt-level=3 #![crate_type = "lib"] +// CHECK-LABEL: @zip_copy_mapped = unnamed_addr alias void (ptr, i64, ptr, i64), ptr @zip_copy + // CHECK-LABEL: @zip_copy #[no_mangle] pub fn zip_copy(xs: &[u8], ys: &mut [u8]) { @@ -11,10 +13,8 @@ pub fn zip_copy(xs: &[u8], ys: &mut [u8]) { } } -// CHECK-LABEL: @zip_copy_mapped #[no_mangle] pub fn zip_copy_mapped(xs: &[u8], ys: &mut [u8]) { - // CHECK: memcpy for (x, y) in xs.iter().map(|&x| x).zip(ys) { *y = x; } diff --git a/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-abort.diff index e9fbcf20a7228..bafe0fda04bb0 100644 --- a/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-abort.diff +++ b/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-abort.diff @@ -10,12 +10,15 @@ let mut _5: &mut [u8; 1024]; let mut _6: &mut [u8; 1024]; scope 1 { - debug buf => _2; +- debug buf => _2; ++ debug buf => _0; } bb0: { - StorageLive(_2); - _2 = [const 0_u8; 1024]; +- StorageLive(_2); +- _2 = [const 0_u8; 1024]; ++ nop; ++ _0 = [const 0_u8; 1024]; StorageLive(_3); - StorageLive(_4); - _4 = copy _1; @@ -23,7 +26,8 @@ + nop; StorageLive(_5); StorageLive(_6); - _6 = &mut _2; +- _6 = &mut _2; ++ _6 = &mut _0; _5 = &mut (*_6); - _3 = move _4(move _5) -> [return: bb1, unwind unreachable]; + _3 = move _1(move _5) -> [return: bb1, unwind unreachable]; @@ -35,8 +39,10 @@ + nop; StorageDead(_6); StorageDead(_3); - _0 = copy _2; - StorageDead(_2); +- _0 = copy _2; +- StorageDead(_2); ++ nop; ++ nop; return; } } diff --git a/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-unwind.diff index 95d5fe1b9304b..0a040d0cdcefe 100644 --- a/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-unwind.diff +++ b/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-unwind.diff @@ -10,12 +10,15 @@ let mut _5: &mut [u8; 1024]; let mut _6: &mut [u8; 1024]; scope 1 { - debug buf => _2; +- debug buf => _2; ++ debug buf => _0; } bb0: { - StorageLive(_2); - _2 = [const 0_u8; 1024]; +- StorageLive(_2); +- _2 = [const 0_u8; 1024]; ++ nop; ++ _0 = [const 0_u8; 1024]; StorageLive(_3); - StorageLive(_4); - _4 = copy _1; @@ -23,7 +26,8 @@ + nop; StorageLive(_5); StorageLive(_6); - _6 = &mut _2; +- _6 = &mut _2; ++ _6 = &mut _0; _5 = &mut (*_6); - _3 = move _4(move _5) -> [return: bb1, unwind continue]; + _3 = move _1(move _5) -> [return: bb1, unwind continue]; @@ -35,8 +39,10 @@ + nop; StorageDead(_6); StorageDead(_3); - _0 = copy _2; - StorageDead(_2); +- _0 = copy _2; +- StorageDead(_2); ++ nop; ++ nop; return; } } diff --git a/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-abort.diff index e9fbcf20a7228..bafe0fda04bb0 100644 --- a/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-abort.diff +++ b/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-abort.diff @@ -10,12 +10,15 @@ let mut _5: &mut [u8; 1024]; let mut _6: &mut [u8; 1024]; scope 1 { - debug buf => _2; +- debug buf => _2; ++ debug buf => _0; } bb0: { - StorageLive(_2); - _2 = [const 0_u8; 1024]; +- StorageLive(_2); +- _2 = [const 0_u8; 1024]; ++ nop; ++ _0 = [const 0_u8; 1024]; StorageLive(_3); - StorageLive(_4); - _4 = copy _1; @@ -23,7 +26,8 @@ + nop; StorageLive(_5); StorageLive(_6); - _6 = &mut _2; +- _6 = &mut _2; ++ _6 = &mut _0; _5 = &mut (*_6); - _3 = move _4(move _5) -> [return: bb1, unwind unreachable]; + _3 = move _1(move _5) -> [return: bb1, unwind unreachable]; @@ -35,8 +39,10 @@ + nop; StorageDead(_6); StorageDead(_3); - _0 = copy _2; - StorageDead(_2); +- _0 = copy _2; +- StorageDead(_2); ++ nop; ++ nop; return; } } diff --git a/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-unwind.diff index 95d5fe1b9304b..0a040d0cdcefe 100644 --- a/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-unwind.diff +++ b/tests/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.panic-unwind.diff @@ -10,12 +10,15 @@ let mut _5: &mut [u8; 1024]; let mut _6: &mut [u8; 1024]; scope 1 { - debug buf => _2; +- debug buf => _2; ++ debug buf => _0; } bb0: { - StorageLive(_2); - _2 = [const 0_u8; 1024]; +- StorageLive(_2); +- _2 = [const 0_u8; 1024]; ++ nop; ++ _0 = [const 0_u8; 1024]; StorageLive(_3); - StorageLive(_4); - _4 = copy _1; @@ -23,7 +26,8 @@ + nop; StorageLive(_5); StorageLive(_6); - _6 = &mut _2; +- _6 = &mut _2; ++ _6 = &mut _0; _5 = &mut (*_6); - _3 = move _4(move _5) -> [return: bb1, unwind continue]; + _3 = move _1(move _5) -> [return: bb1, unwind continue]; @@ -35,8 +39,10 @@ + nop; StorageDead(_6); StorageDead(_3); - _0 = copy _2; - StorageDead(_2); +- _0 = copy _2; +- StorageDead(_2); ++ nop; ++ nop; return; } } diff --git a/tests/mir-opt/dest-prop/simple.rs b/tests/mir-opt/dest-prop/simple.rs index 927a9c5b24cdb..473ab550165af 100644 --- a/tests/mir-opt/dest-prop/simple.rs +++ b/tests/mir-opt/dest-prop/simple.rs @@ -5,11 +5,11 @@ fn nrvo(init: fn(&mut [u8; 1024])) -> [u8; 1024] { // CHECK-LABEL: fn nrvo( // CHECK: debug init => [[init:_.*]]; - // CHECK: debug buf => [[buf:_.*]]; - // CHECK: [[buf]] = [const 0_u8; 1024]; + // CHECK: debug buf => _0; + // CHECK: _0 = [const 0_u8; 1024]; // CHECK-NOT: {{_.*}} = copy [[init]]; + // CHECK: {{_.*}} = &mut _0; // CHECK: move [[init]](move {{_.*}}) - // CHECK: {{_.*}} = copy [[buf]] let mut buf = [0; 1024]; init(&mut buf); buf diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff index c33e0810739f2..b37236944320b 100644 --- a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff @@ -5,14 +5,13 @@ let mut _0: (); let _1: (!, !); + let mut _2: fn() -> ! {sleep}; ++ let mut _7: (); + let mut _8: (); -+ let mut _9: (); + scope 1 (inlined call_twice:: ! {sleep}>) { + debug f => _2; + let mut _3: &fn() -> ! {sleep}; + let _4: !; + let mut _5: &fn() -> ! {sleep}; -+ let mut _7: !; + scope 2 { + debug a => _4; + let _6: !; @@ -35,12 +34,12 @@ - _1 = call_twice:: ! {sleep}>(sleep) -> unwind continue; + StorageLive(_2); + _2 = sleep; -+ StorageLive(_6); + StorageLive(_4); ++ StorageLive(_6); + StorageLive(_3); + _3 = &_2; -+ StorageLive(_8); -+ _8 = const (); ++ StorageLive(_7); ++ _7 = const (); + goto -> bb1; + } + diff --git a/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir index 75e8cb1d8618c..02fd78ce98bcb 100644 --- a/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir @@ -5,21 +5,20 @@ fn filter_mapped(_1: impl Iterator, _2: impl Fn(T) -> Option) -> () debug f => _2; let mut _0: (); let mut _3: std::iter::FilterMap, impl Fn(T) -> Option>; - let mut _4: std::iter::FilterMap, impl Fn(T) -> Option>; - let mut _5: &mut std::iter::FilterMap, impl Fn(T) -> Option>; - let mut _8: std::option::Option; - let mut _9: isize; - let _11: (); + let mut _4: &mut std::iter::FilterMap, impl Fn(T) -> Option>; + let mut _7: std::option::Option; + let mut _8: isize; + let _10: (); scope 1 { - debug iter => _4; - let _10: U; + debug iter => _3; + let _9: U; scope 2 { - debug x => _10; + debug x => _9; } scope 4 (inlined , impl Fn(T) -> Option> as Iterator>::next) { - debug self => _5; - let mut _6: &mut impl Iterator; - let mut _7: &mut impl Fn(T) -> Option; + debug self => _4; + let mut _5: &mut impl Iterator; + let mut _6: &mut impl Fn(T) -> Option; } } scope 3 (inlined , impl Fn(T) -> Option> as IntoIterator>::into_iter) { @@ -31,45 +30,42 @@ fn filter_mapped(_1: impl Iterator, _2: impl Fn(T) -> Option) -> () } bb1: { - StorageLive(_4); - _4 = copy _3; goto -> bb2; } bb2: { - StorageLive(_8); - _5 = &mut _4; - StorageLive(_6); - _6 = &mut (_4.0: impl Iterator); StorageLive(_7); - _7 = &mut (_4.1: impl Fn(T) -> Option); - _8 = as Iterator>::find_map:: Option>(move _6, move _7) -> [return: bb3, unwind: bb9]; + _4 = &mut _3; + StorageLive(_5); + _5 = &mut (_3.0: impl Iterator); + StorageLive(_6); + _6 = &mut (_3.1: impl Fn(T) -> Option); + _7 = as Iterator>::find_map:: Option>(move _5, move _6) -> [return: bb3, unwind: bb9]; } bb3: { - StorageDead(_7); StorageDead(_6); - _9 = discriminant(_8); - switchInt(move _9) -> [0: bb4, 1: bb6, otherwise: bb8]; + StorageDead(_5); + _8 = discriminant(_7); + switchInt(move _8) -> [0: bb4, 1: bb6, otherwise: bb8]; } bb4: { - StorageDead(_8); - drop(_4) -> [return: bb5, unwind continue]; + StorageDead(_7); + drop(_3) -> [return: bb5, unwind continue]; } bb5: { - StorageDead(_4); return; } bb6: { - _10 = move ((_8 as Some).0: U); - _11 = opaque::(move _10) -> [return: bb7, unwind: bb9]; + _9 = move ((_7 as Some).0: U); + _10 = opaque::(move _9) -> [return: bb7, unwind: bb9]; } bb7: { - StorageDead(_8); + StorageDead(_7); goto -> bb2; } @@ -78,7 +74,7 @@ fn filter_mapped(_1: impl Iterator, _2: impl Fn(T) -> Option) -> () } bb9 (cleanup): { - drop(_4) -> [return: bb10, unwind terminate(cleanup)]; + drop(_3) -> [return: bb10, unwind terminate(cleanup)]; } bb10 (cleanup): { diff --git a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir index 154cbd3791cbd..04d0793f56235 100644 --- a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir @@ -5,32 +5,31 @@ fn int_range(_1: usize, _2: usize) -> () { debug end => _2; let mut _0: (); let mut _3: std::ops::Range; - let mut _4: std::ops::Range; - let mut _5: &mut std::ops::Range; - let mut _13: std::option::Option; - let _15: (); + let mut _4: &mut std::ops::Range; + let mut _12: std::option::Option; + let _14: (); scope 1 { - debug iter => _4; - let _14: usize; + debug iter => _3; + let _13: usize; scope 2 { - debug i => _14; + debug i => _13; } scope 4 (inlined iter::range::>::next) { - debug self => _5; + debug self => _4; scope 5 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - debug self => _5; + debug self => _4; + let mut _5: &usize; let mut _6: &usize; - let mut _7: &usize; - let mut _10: bool; - let _11: usize; - let mut _12: usize; + let mut _9: bool; + let _10: usize; + let mut _11: usize; scope 6 { - debug old => _11; + debug old => _10; scope 8 (inlined ::forward_unchecked) { - debug start => _11; + debug start => _10; debug n => const 1_usize; scope 9 (inlined #[track_caller] core::num::::unchecked_add) { - debug self => _11; + debug self => _10; debug rhs => const 1_usize; scope 10 (inlined core::ub_checks::check_language_ub) { scope 11 (inlined core::ub_checks::check_language_ub::runtime) { @@ -40,10 +39,10 @@ fn int_range(_1: usize, _2: usize) -> () { } } scope 7 (inlined std::cmp::impls::::lt) { - debug self => _6; - debug other => _7; + debug self => _5; + debug other => _6; + let mut _7: usize; let mut _8: usize; - let mut _9: usize; } } } @@ -54,54 +53,51 @@ fn int_range(_1: usize, _2: usize) -> () { bb0: { _3 = std::ops::Range:: { start: copy _1, end: copy _2 }; - StorageLive(_4); - _4 = copy _3; goto -> bb1; } bb1: { - StorageLive(_13); - _5 = &mut _4; - StorageLive(_10); + StorageLive(_12); + _4 = &mut _3; + StorageLive(_9); + StorageLive(_5); + _5 = &(_3.0: usize); StorageLive(_6); - _6 = &(_4.0: usize); + _6 = &(_3.1: usize); StorageLive(_7); - _7 = &(_4.1: usize); + _7 = copy (_3.0: usize); StorageLive(_8); - _8 = copy (_4.0: usize); - StorageLive(_9); - _9 = copy (_4.1: usize); - _10 = Lt(move _8, move _9); - StorageDead(_9); + _8 = copy (_3.1: usize); + _9 = Lt(move _7, move _8); StorageDead(_8); - switchInt(move _10) -> [0: bb2, otherwise: bb3]; + StorageDead(_7); + switchInt(move _9) -> [0: bb2, otherwise: bb3]; } bb2: { - StorageDead(_7); StorageDead(_6); - StorageDead(_10); - StorageDead(_13); - StorageDead(_4); + StorageDead(_5); + StorageDead(_9); + StorageDead(_12); return; } bb3: { - StorageDead(_7); StorageDead(_6); - _11 = copy (_4.0: usize); - StorageLive(_12); - _12 = AddUnchecked(copy _11, const 1_usize); - (_4.0: usize) = move _12; - StorageDead(_12); - _13 = Option::::Some(copy _11); - StorageDead(_10); - _14 = copy ((_13 as Some).0: usize); - _15 = opaque::(move _14) -> [return: bb4, unwind continue]; + StorageDead(_5); + _10 = copy (_3.0: usize); + StorageLive(_11); + _11 = AddUnchecked(copy _10, const 1_usize); + (_3.0: usize) = move _11; + StorageDead(_11); + _12 = Option::::Some(copy _10); + StorageDead(_9); + _13 = copy ((_12 as Some).0: usize); + _14 = opaque::(move _13) -> [return: bb4, unwind continue]; } bb4: { - StorageDead(_13); + StorageDead(_12); goto -> bb1; } } diff --git a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir index d22ea54004c91..fa29adb6b15b5 100644 --- a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir @@ -5,33 +5,32 @@ fn mapped(_1: impl Iterator, _2: impl Fn(T) -> U) -> () { debug f => _2; let mut _0: (); let mut _3: std::iter::Map, impl Fn(T) -> U>; - let mut _4: std::iter::Map, impl Fn(T) -> U>; - let mut _5: &mut std::iter::Map, impl Fn(T) -> U>; - let mut _13: std::option::Option; - let _15: (); + let mut _4: &mut std::iter::Map, impl Fn(T) -> U>; + let mut _12: std::option::Option; + let _14: (); scope 1 { - debug iter => _4; - let _14: U; + debug iter => _3; + let _13: U; scope 2 { - debug x => _14; + debug x => _13; } scope 4 (inlined , impl Fn(T) -> U> as Iterator>::next) { - debug self => _5; - let mut _6: &mut impl Iterator; - let mut _7: std::option::Option; - let mut _8: &mut impl Fn(T) -> U; + debug self => _4; + let mut _5: &mut impl Iterator; + let mut _6: std::option::Option; + let mut _7: &mut impl Fn(T) -> U; scope 5 (inlined Option::::map:: U>) { - debug self => _7; - debug f => _8; - let mut _9: isize; - let _10: T; - let mut _11: (T,); - let mut _12: U; + debug self => _6; + debug f => _7; + let mut _8: isize; + let _9: T; + let mut _10: (T,); + let mut _11: U; scope 6 { - debug x => _10; + debug x => _9; scope 7 (inlined ops::function::impls:: for &mut impl Fn(T) -> U>::call_once) { - debug self => _8; - debug args => _11; + debug self => _7; + debug args => _10; } } } @@ -46,66 +45,63 @@ fn mapped(_1: impl Iterator, _2: impl Fn(T) -> U) -> () { } bb1: { - StorageLive(_4); - _4 = copy _3; goto -> bb2; } bb2: { - StorageLive(_13); - _5 = &mut _4; - StorageLive(_8); - StorageLive(_7); + StorageLive(_12); + _4 = &mut _3; StorageLive(_6); - _6 = &mut (_4.0: impl Iterator); - _7 = as Iterator>::next(move _6) -> [return: bb3, unwind: bb10]; + StorageLive(_5); + _5 = &mut (_3.0: impl Iterator); + _6 = as Iterator>::next(move _5) -> [return: bb3, unwind: bb10]; } bb3: { - StorageDead(_6); - _8 = &mut (_4.1: impl Fn(T) -> U); + StorageDead(_5); + StorageLive(_7); + _7 = &mut (_3.1: impl Fn(T) -> U); + StorageLive(_8); StorageLive(_9); - StorageLive(_10); - _9 = discriminant(_7); - switchInt(move _9) -> [0: bb4, 1: bb6, otherwise: bb9]; + _8 = discriminant(_6); + switchInt(move _8) -> [0: bb4, 1: bb6, otherwise: bb9]; } bb4: { - StorageDead(_10); StorageDead(_9); - StorageDead(_7); StorageDead(_8); - StorageDead(_13); - drop(_4) -> [return: bb5, unwind continue]; + StorageDead(_7); + StorageDead(_6); + StorageDead(_12); + drop(_3) -> [return: bb5, unwind continue]; } bb5: { - StorageDead(_4); return; } bb6: { - _10 = move ((_7 as Some).0: T); - StorageLive(_12); + _9 = move ((_6 as Some).0: T); StorageLive(_11); - _11 = (copy _10,); - _12 = U as FnMut<(T,)>>::call_mut(move _8, move _11) -> [return: bb7, unwind: bb10]; + StorageLive(_10); + _10 = (copy _9,); + _11 = U as FnMut<(T,)>>::call_mut(move _7, move _10) -> [return: bb7, unwind: bb10]; } bb7: { - StorageDead(_11); - _13 = Option::::Some(move _12); - StorageDead(_12); StorageDead(_10); + _12 = Option::::Some(move _11); + StorageDead(_11); StorageDead(_9); - StorageDead(_7); StorageDead(_8); - _14 = move ((_13 as Some).0: U); - _15 = opaque::(move _14) -> [return: bb8, unwind: bb10]; + StorageDead(_7); + StorageDead(_6); + _13 = move ((_12 as Some).0: U); + _14 = opaque::(move _13) -> [return: bb8, unwind: bb10]; } bb8: { - StorageDead(_13); + StorageDead(_12); goto -> bb2; } @@ -114,7 +110,7 @@ fn mapped(_1: impl Iterator, _2: impl Fn(T) -> U) -> () { } bb10 (cleanup): { - drop(_4) -> [return: bb11, unwind terminate(cleanup)]; + drop(_3) -> [return: bb11, unwind terminate(cleanup)]; } bb11 (cleanup): { diff --git a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir index e537dd6a28ef8..533971546d4e8 100644 --- a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir @@ -4,59 +4,53 @@ fn vec_move(_1: Vec) -> () { debug v => _1; let mut _0: (); let mut _2: std::vec::IntoIter; - let mut _3: std::vec::IntoIter; - let mut _4: &mut std::vec::IntoIter; - let mut _5: std::option::Option; - let mut _6: isize; - let _8: (); + let mut _3: &mut std::vec::IntoIter; + let mut _4: std::option::Option; + let mut _5: isize; + let _7: (); scope 1 { - debug iter => _3; - let _7: impl Sized; + debug iter => _2; + let _6: impl Sized; scope 2 { - debug x => _7; + debug x => _6; } } bb0: { - StorageLive(_2); _2 = as IntoIterator>::into_iter(move _1) -> [return: bb1, unwind continue]; } bb1: { - StorageLive(_3); - _3 = move _2; goto -> bb2; } bb2: { - StorageLive(_5); - _4 = &mut _3; - _5 = as Iterator>::next(move _4) -> [return: bb3, unwind: bb9]; + StorageLive(_4); + _3 = &mut _2; + _4 = as Iterator>::next(move _3) -> [return: bb3, unwind: bb9]; } bb3: { - _6 = discriminant(_5); - switchInt(move _6) -> [0: bb4, 1: bb6, otherwise: bb8]; + _5 = discriminant(_4); + switchInt(move _5) -> [0: bb4, 1: bb6, otherwise: bb8]; } bb4: { - StorageDead(_5); - drop(_3) -> [return: bb5, unwind continue]; + StorageDead(_4); + drop(_2) -> [return: bb5, unwind continue]; } bb5: { - StorageDead(_3); - StorageDead(_2); return; } bb6: { - _7 = move ((_5 as Some).0: impl Sized); - _8 = opaque::(move _7) -> [return: bb7, unwind: bb9]; + _6 = move ((_4 as Some).0: impl Sized); + _7 = opaque::(move _6) -> [return: bb7, unwind: bb9]; } bb7: { - StorageDead(_5); + StorageDead(_4); goto -> bb2; } @@ -65,7 +59,7 @@ fn vec_move(_1: Vec) -> () { } bb9 (cleanup): { - drop(_3) -> [return: bb10, unwind terminate(cleanup)]; + drop(_2) -> [return: bb10, unwind terminate(cleanup)]; } bb10 (cleanup): { diff --git a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-abort.mir index 3f000dcafb035..da1e3a9ccfc61 100644 --- a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-abort.mir @@ -6,18 +6,17 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { debug f => _3; let mut _0: (); let mut _4: std::ops::RangeInclusive; - let mut _5: std::ops::RangeInclusive; - let mut _6: &mut std::ops::RangeInclusive; - let mut _7: std::option::Option; - let mut _8: isize; - let mut _10: &impl Fn(u32); - let mut _11: (u32,); - let _12: (); + let mut _5: &mut std::ops::RangeInclusive; + let mut _6: std::option::Option; + let mut _7: isize; + let mut _9: &impl Fn(u32); + let mut _10: (u32,); + let _11: (); scope 1 { - debug iter => _5; - let _9: u32; + debug iter => _4; + let _8: u32; scope 2 { - debug x => _9; + debug x => _8; } scope 5 (inlined iter::range::>::next) { } @@ -29,25 +28,22 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { bb0: { _4 = std::ops::RangeInclusive:: { start: copy _1, end: copy _2, exhausted: const false }; - StorageLive(_5); - _5 = copy _4; goto -> bb1; } bb1: { - StorageLive(_7); - _6 = &mut _5; - _7 = as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind unreachable]; + StorageLive(_6); + _5 = &mut _4; + _6 = as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _5) -> [return: bb2, unwind unreachable]; } bb2: { - _8 = discriminant(_7); - switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb7]; + _7 = discriminant(_6); + switchInt(move _7) -> [0: bb3, 1: bb5, otherwise: bb7]; } bb3: { - StorageDead(_7); - StorageDead(_5); + StorageDead(_6); drop(_3) -> [return: bb4, unwind unreachable]; } @@ -56,18 +52,18 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb5: { - _9 = copy ((_7 as Some).0: u32); + _8 = copy ((_6 as Some).0: u32); + StorageLive(_9); + _9 = &_3; StorageLive(_10); - _10 = &_3; - StorageLive(_11); - _11 = (copy _9,); - _12 = >::call(move _10, move _11) -> [return: bb6, unwind unreachable]; + _10 = (copy _8,); + _11 = >::call(move _9, move _10) -> [return: bb6, unwind unreachable]; } bb6: { - StorageDead(_11); StorageDead(_10); - StorageDead(_7); + StorageDead(_9); + StorageDead(_6); goto -> bb1; } diff --git a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir index 2353717362711..96b8bfe66606c 100644 --- a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir @@ -6,18 +6,17 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { debug f => _3; let mut _0: (); let mut _4: std::ops::RangeInclusive; - let mut _5: std::ops::RangeInclusive; - let mut _6: &mut std::ops::RangeInclusive; - let mut _7: std::option::Option; - let mut _8: isize; - let mut _10: &impl Fn(u32); - let mut _11: (u32,); - let _12: (); + let mut _5: &mut std::ops::RangeInclusive; + let mut _6: std::option::Option; + let mut _7: isize; + let mut _9: &impl Fn(u32); + let mut _10: (u32,); + let _11: (); scope 1 { - debug iter => _5; - let _9: u32; + debug iter => _4; + let _8: u32; scope 2 { - debug x => _9; + debug x => _8; } scope 5 (inlined iter::range::>::next) { } @@ -29,25 +28,22 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { bb0: { _4 = std::ops::RangeInclusive:: { start: copy _1, end: copy _2, exhausted: const false }; - StorageLive(_5); - _5 = copy _4; goto -> bb1; } bb1: { - StorageLive(_7); - _6 = &mut _5; - _7 = as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind: bb8]; + StorageLive(_6); + _5 = &mut _4; + _6 = as iter::range::RangeInclusiveIteratorImpl>::spec_next(move _5) -> [return: bb2, unwind: bb8]; } bb2: { - _8 = discriminant(_7); - switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb7]; + _7 = discriminant(_6); + switchInt(move _7) -> [0: bb3, 1: bb5, otherwise: bb7]; } bb3: { - StorageDead(_7); - StorageDead(_5); + StorageDead(_6); drop(_3) -> [return: bb4, unwind continue]; } @@ -56,18 +52,18 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb5: { - _9 = copy ((_7 as Some).0: u32); + _8 = copy ((_6 as Some).0: u32); + StorageLive(_9); + _9 = &_3; StorageLive(_10); - _10 = &_3; - StorageLive(_11); - _11 = (copy _9,); - _12 = >::call(move _10, move _11) -> [return: bb6, unwind: bb8]; + _10 = (copy _8,); + _11 = >::call(move _9, move _10) -> [return: bb6, unwind: bb8]; } bb6: { - StorageDead(_11); StorageDead(_10); - StorageDead(_7); + StorageDead(_9); + StorageDead(_6); goto -> bb1; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir index 28b12cdf36755..c8e58a08a2a62 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir @@ -6,20 +6,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _0: (); let mut _10: std::slice::Iter<'_, T>; let mut _11: std::iter::Enumerate>; - let mut _12: std::iter::Enumerate>; - let mut _13: &mut std::iter::Enumerate>; - let mut _14: std::option::Option<(usize, &T)>; - let mut _15: isize; - let mut _18: &impl Fn(usize, &T); - let mut _19: (usize, &T); - let _20: (); + let mut _12: &mut std::iter::Enumerate>; + let mut _13: std::option::Option<(usize, &T)>; + let mut _14: isize; + let mut _17: &impl Fn(usize, &T); + let mut _18: (usize, &T); + let _19: (); scope 1 { - debug iter => _12; - let _16: usize; - let _17: &T; + debug iter => _11; + let _15: usize; + let _16: &T; scope 2 { - debug i => _16; - debug x => _17; + debug i => _15; + debug x => _16; } } scope 3 (inlined core::slice::::iter) { @@ -99,23 +98,20 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { StorageDead(_3); _11 = Enumerate::> { iter: copy _10, count: const 0_usize }; StorageDead(_10); - StorageLive(_12); - _12 = copy _11; goto -> bb4; } bb4: { - _13 = &mut _12; - _14 = > as Iterator>::next(move _13) -> [return: bb5, unwind: bb11]; + _12 = &mut _11; + _13 = > as Iterator>::next(move _12) -> [return: bb5, unwind: bb11]; } bb5: { - _15 = discriminant(_14); - switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; + _14 = discriminant(_13); + switchInt(move _14) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_12); drop(_2) -> [return: bb7, unwind continue]; } @@ -124,18 +120,18 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb8: { - _16 = copy (((_14 as Some).0: (usize, &T)).0: usize); - _17 = copy (((_14 as Some).0: (usize, &T)).1: &T); + _15 = copy (((_13 as Some).0: (usize, &T)).0: usize); + _16 = copy (((_13 as Some).0: (usize, &T)).1: &T); + StorageLive(_17); + _17 = &_2; StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = copy ((_14 as Some).0: (usize, &T)); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; + _18 = copy ((_13 as Some).0: (usize, &T)); + _19 = >::call(move _17, move _18) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_19); StorageDead(_18); + StorageDead(_17); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir index 0adf268d766dd..b630edd8b4ba3 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -6,20 +6,19 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _0: (); let mut _10: std::slice::Iter<'_, T>; let mut _11: std::iter::Rev>; - let mut _12: std::iter::Rev>; - let mut _14: std::option::Option<&T>; - let mut _15: isize; - let mut _17: &impl Fn(&T); - let mut _18: (&T,); - let _19: (); + let mut _13: std::option::Option<&T>; + let mut _14: isize; + let mut _16: &impl Fn(&T); + let mut _17: (&T,); + let _18: (); scope 1 { - debug iter => _12; - let _16: &T; + debug iter => _11; + let _15: &T; scope 2 { - debug x => _16; + debug x => _15; } scope 18 (inlined > as Iterator>::next) { - let mut _13: &mut std::slice::Iter<'_, T>; + let mut _12: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { @@ -99,27 +98,24 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { StorageDead(_3); _11 = Rev::> { iter: copy _10 }; StorageDead(_10); - StorageLive(_12); - _12 = copy _11; goto -> bb4; } bb4: { - StorageLive(_14); StorageLive(_13); - _13 = &mut (_12.0: std::slice::Iter<'_, T>); - _14 = as DoubleEndedIterator>::next_back(move _13) -> [return: bb5, unwind unreachable]; + StorageLive(_12); + _12 = &mut (_11.0: std::slice::Iter<'_, T>); + _13 = as DoubleEndedIterator>::next_back(move _12) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_13); - _15 = discriminant(_14); - switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_12); + _14 = discriminant(_13); + switchInt(move _14) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_14); - StorageDead(_12); + StorageDead(_13); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -128,18 +124,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _16 = copy ((_14 as Some).0: &T); + _15 = copy ((_13 as Some).0: &T); + StorageLive(_16); + _16 = &_2; StorageLive(_17); - _17 = &_2; - StorageLive(_18); - _18 = (copy _16,); - _19 = >::call(move _17, move _18) -> [return: bb9, unwind unreachable]; + _17 = (copy _15,); + _18 = >::call(move _16, move _17) -> [return: bb9, unwind unreachable]; } bb9: { - StorageDead(_18); StorageDead(_17); - StorageDead(_14); + StorageDead(_16); + StorageDead(_13); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index cb0d640d445bb..abf3bcc90e71e 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -6,20 +6,19 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _0: (); let mut _10: std::slice::Iter<'_, T>; let mut _11: std::iter::Rev>; - let mut _12: std::iter::Rev>; - let mut _14: std::option::Option<&T>; - let mut _15: isize; - let mut _17: &impl Fn(&T); - let mut _18: (&T,); - let _19: (); + let mut _13: std::option::Option<&T>; + let mut _14: isize; + let mut _16: &impl Fn(&T); + let mut _17: (&T,); + let _18: (); scope 1 { - debug iter => _12; - let _16: &T; + debug iter => _11; + let _15: &T; scope 2 { - debug x => _16; + debug x => _15; } scope 18 (inlined > as Iterator>::next) { - let mut _13: &mut std::slice::Iter<'_, T>; + let mut _12: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { @@ -99,27 +98,24 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { StorageDead(_3); _11 = Rev::> { iter: copy _10 }; StorageDead(_10); - StorageLive(_12); - _12 = copy _11; goto -> bb4; } bb4: { - StorageLive(_14); StorageLive(_13); - _13 = &mut (_12.0: std::slice::Iter<'_, T>); - _14 = as DoubleEndedIterator>::next_back(move _13) -> [return: bb5, unwind: bb11]; + StorageLive(_12); + _12 = &mut (_11.0: std::slice::Iter<'_, T>); + _13 = as DoubleEndedIterator>::next_back(move _12) -> [return: bb5, unwind: bb11]; } bb5: { - StorageDead(_13); - _15 = discriminant(_14); - switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_12); + _14 = discriminant(_13); + switchInt(move _14) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_14); - StorageDead(_12); + StorageDead(_13); drop(_2) -> [return: bb7, unwind continue]; } @@ -128,18 +124,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _16 = copy ((_14 as Some).0: &T); + _15 = copy ((_13 as Some).0: &T); + StorageLive(_16); + _16 = &_2; StorageLive(_17); - _17 = &_2; - StorageLive(_18); - _18 = (copy _16,); - _19 = >::call(move _17, move _18) -> [return: bb9, unwind: bb11]; + _17 = (copy _15,); + _18 = >::call(move _16, move _17) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_18); StorageDead(_17); - StorageDead(_14); + StorageDead(_16); + StorageDead(_13); goto -> bb4; }