From e110567dcdf7b77cda5f3413af7c6fadec899a9a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 31 May 2024 00:22:40 +0000 Subject: [PATCH] Revert "Auto merge of #115105 - cjgillot:dest-prop-default, r=oli-obk" This reverts commit cfb730450f847bb622243eaaab15e77e58d91767, reversing changes made to 91c0823ee63e793d990bb9fed898dc95b5d6db51. --- compiler/rustc_mir_transform/src/dest_prop.rs | 2 +- compiler/rustc_mir_transform/src/lib.rs | 4 +- compiler/rustc_mir_transform/src/nrvo.rs | 235 ++++++++++++++++++ ...in.DestinationPropagation.panic-abort.diff | 2 +- ...n.DestinationPropagation.panic-unwind.diff | 2 +- .../{dest-prop => }/nrvo_miscompile_111005.rs | 4 +- ...mpile_111005.wrong.RenameReturnPlace.diff} | 7 +- ...e.nrvo.RenameReturnPlace.panic-abort.diff} | 31 ++- ....nrvo.RenameReturnPlace.panic-unwind.diff} | 31 ++- .../nrvo_borrowed.rs => nrvo_simple.rs} | 4 +- ....{impl#0}-partial_cmp.PreCodegen.after.mir | 32 +-- ...ward_loop.PreCodegen.after.panic-abort.mir | 64 ++--- ...ard_loop.PreCodegen.after.panic-unwind.mir | 64 ++--- ...ated_loop.PreCodegen.after.panic-abort.mir | 80 +++--- ...ted_loop.PreCodegen.after.panic-unwind.mir | 80 +++--- ...ward_loop.PreCodegen.after.panic-abort.mir | 66 ++--- ...ard_loop.PreCodegen.after.panic-unwind.mir | 66 ++--- ...ange_loop.PreCodegen.after.panic-abort.mir | 56 +++-- ...nge_loop.PreCodegen.after.panic-unwind.mir | 56 +++-- ...erse_loop.PreCodegen.after.panic-abort.mir | 74 +++--- ...rse_loop.PreCodegen.after.panic-unwind.mir | 74 +++--- 21 files changed, 661 insertions(+), 373 deletions(-) create mode 100644 compiler/rustc_mir_transform/src/nrvo.rs rename tests/mir-opt/{dest-prop => }/nrvo_miscompile_111005.rs (78%) rename tests/mir-opt/{dest-prop/nrvo_miscompile_111005.wrong.DestinationPropagation.diff => nrvo_miscompile_111005.wrong.RenameReturnPlace.diff} (60%) rename tests/mir-opt/{dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-abort.diff => nrvo_simple.nrvo.RenameReturnPlace.panic-abort.diff} (53%) rename tests/mir-opt/{dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-unwind.diff => nrvo_simple.nrvo.RenameReturnPlace.panic-unwind.diff} (53%) rename tests/mir-opt/{dest-prop/nrvo_borrowed.rs => nrvo_simple.rs} (68%) diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index f0778594353..b1016c0867c 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -160,7 +160,7 @@ fn is_enabled(&self, sess: &rustc_session::Session) -> bool { // 2. Despite being an overall perf improvement, this still causes a 30% regression in // keccak. We can temporarily fix this by bounding function size, but in the long term // we should fix this by being smarter about invalidating analysis results. - sess.mir_opt_level() >= 2 + sess.mir_opt_level() >= 3 } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index b03c99654e2..a8741254ffb 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -88,6 +88,7 @@ mod mentioned_items; mod multiple_return_terminators; mod normalize_array_len; +mod nrvo; mod prettify; mod promote_consts; mod ref_prop; @@ -607,12 +608,13 @@ fn o1(x: T) -> WithMinOptLevel { &jump_threading::JumpThreading, &early_otherwise_branch::EarlyOtherwiseBranch, &simplify_comparison_integral::SimplifyComparisonIntegral, + &dest_prop::DestinationPropagation, &o1(simplify_branches::SimplifyConstCondition::Final), &o1(remove_noop_landing_pads::RemoveNoopLandingPads), &o1(simplify::SimplifyCfg::Final), ©_prop::CopyProp, &dead_store_elimination::DeadStoreElimination::Final, - &dest_prop::DestinationPropagation, + &nrvo::RenameReturnPlace, &simplify::SimplifyLocals::Final, &multiple_return_terminators::MultipleReturnTerminators, &deduplicate_blocks::DeduplicateBlocks, diff --git a/compiler/rustc_mir_transform/src/nrvo.rs b/compiler/rustc_mir_transform/src/nrvo.rs new file mode 100644 index 00000000000..885dbd5f339 --- /dev/null +++ b/compiler/rustc_mir_transform/src/nrvo.rs @@ -0,0 +1,235 @@ +//! See the docs for [`RenameReturnPlace`]. + +use rustc_hir::Mutability; +use rustc_index::bit_set::BitSet; +use rustc_middle::bug; +use rustc_middle::mir::visit::{MutVisitor, NonUseContext, PlaceContext, Visitor}; +use rustc_middle::mir::{self, BasicBlock, Local, Location}; +use rustc_middle::ty::TyCtxt; + +use crate::MirPass; + +/// This pass looks for MIR that always copies the same local into the return place and eliminates +/// the copy by renaming all uses of that local to `_0`. +/// +/// This allows LLVM to perform an optimization similar to the named return value optimization +/// (NRVO) that is guaranteed in C++. This avoids a stack allocation and `memcpy` for the +/// relatively common pattern of allocating a buffer on the stack, mutating it, and returning it by +/// value like so: +/// +/// ```rust +/// fn foo(init: fn(&mut [u8; 1024])) -> [u8; 1024] { +/// let mut buf = [0; 1024]; +/// init(&mut buf); +/// buf +/// } +/// ``` +/// +/// For now, this pass is very simple and only capable of eliminating a single copy. A more general +/// version of copy propagation, such as the one based on non-overlapping live ranges in [#47954] and +/// [#71003], could yield even more benefits. +/// +/// [#47954]: https://github.com/rust-lang/rust/pull/47954 +/// [#71003]: https://github.com/rust-lang/rust/pull/71003 +pub struct RenameReturnPlace; + +impl<'tcx> MirPass<'tcx> for RenameReturnPlace { + fn is_enabled(&self, sess: &rustc_session::Session) -> bool { + // unsound: #111005 + sess.mir_opt_level() > 0 && sess.opts.unstable_opts.unsound_mir_opts + } + + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) { + let def_id = body.source.def_id(); + let Some(returned_local) = local_eligible_for_nrvo(body) else { + debug!("`{:?}` was ineligible for NRVO", def_id); + return; + }; + + if !tcx.consider_optimizing(|| format!("RenameReturnPlace {def_id:?}")) { + return; + } + + debug!( + "`{:?}` was eligible for NRVO, making {:?} the return place", + def_id, returned_local + ); + + RenameToReturnPlace { tcx, to_rename: returned_local }.visit_body_preserves_cfg(body); + + // Clean up the `NOP`s we inserted for statements made useless by our renaming. + for block_data in body.basic_blocks.as_mut_preserves_cfg() { + block_data.statements.retain(|stmt| stmt.kind != mir::StatementKind::Nop); + } + + // Overwrite the debuginfo of `_0` with that of the renamed local. + let (renamed_decl, ret_decl) = + body.local_decls.pick2_mut(returned_local, mir::RETURN_PLACE); + + // Sometimes, the return place is assigned a local of a different but coercible type, for + // example `&mut T` instead of `&T`. Overwriting the `LocalInfo` for the return place means + // its type may no longer match the return type of its function. This doesn't cause a + // problem in codegen because these two types are layout-compatible, but may be unexpected. + debug!("_0: {:?} = {:?}: {:?}", ret_decl.ty, returned_local, renamed_decl.ty); + ret_decl.clone_from(renamed_decl); + + // The return place is always mutable. + ret_decl.mutability = Mutability::Mut; + } +} + +/// MIR that is eligible for the NRVO must fulfill two conditions: +/// 1. The return place must not be read prior to the `Return` terminator. +/// 2. A simple assignment of a whole local to the return place (e.g., `_0 = _1`) must be the +/// only definition of the return place reaching the `Return` terminator. +/// +/// If the MIR fulfills both these conditions, this function returns the `Local` that is assigned +/// to the return place along all possible paths through the control-flow graph. +fn local_eligible_for_nrvo(body: &mir::Body<'_>) -> Option { + if IsReturnPlaceRead::run(body) { + return None; + } + + let mut copied_to_return_place = None; + for block in body.basic_blocks.indices() { + // Look for blocks with a `Return` terminator. + if !matches!(body[block].terminator().kind, mir::TerminatorKind::Return) { + continue; + } + + // Look for an assignment of a single local to the return place prior to the `Return`. + let returned_local = find_local_assigned_to_return_place(block, body)?; + match body.local_kind(returned_local) { + // FIXME: Can we do this for arguments as well? + mir::LocalKind::Arg => return None, + + mir::LocalKind::ReturnPointer => bug!("Return place was assigned to itself?"), + mir::LocalKind::Temp => {} + } + + // If multiple different locals are copied to the return place. We can't pick a + // single one to rename. + if copied_to_return_place.is_some_and(|old| old != returned_local) { + return None; + } + + copied_to_return_place = Some(returned_local); + } + + copied_to_return_place +} + +fn find_local_assigned_to_return_place(start: BasicBlock, body: &mir::Body<'_>) -> Option { + let mut block = start; + let mut seen = BitSet::new_empty(body.basic_blocks.len()); + + // Iterate as long as `block` has exactly one predecessor that we have not yet visited. + while seen.insert(block) { + trace!("Looking for assignments to `_0` in {:?}", block); + + let local = body[block].statements.iter().rev().find_map(as_local_assigned_to_return_place); + if local.is_some() { + return local; + } + + match body.basic_blocks.predecessors()[block].as_slice() { + &[pred] => block = pred, + _ => return None, + } + } + + None +} + +// If this statement is an assignment of an unprojected local to the return place, +// return that local. +fn as_local_assigned_to_return_place(stmt: &mir::Statement<'_>) -> Option { + if let mir::StatementKind::Assign(box (lhs, rhs)) = &stmt.kind { + if lhs.as_local() == Some(mir::RETURN_PLACE) { + if let mir::Rvalue::Use(mir::Operand::Copy(rhs) | mir::Operand::Move(rhs)) = rhs { + return rhs.as_local(); + } + } + } + + None +} + +struct RenameToReturnPlace<'tcx> { + to_rename: Local, + tcx: TyCtxt<'tcx>, +} + +/// Replaces all uses of `self.to_rename` with `_0`. +impl<'tcx> MutVisitor<'tcx> for RenameToReturnPlace<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn visit_statement(&mut self, stmt: &mut mir::Statement<'tcx>, loc: Location) { + // Remove assignments of the local being replaced to the return place, since it is now the + // return place: + // _0 = _1 + if as_local_assigned_to_return_place(stmt) == Some(self.to_rename) { + stmt.kind = mir::StatementKind::Nop; + return; + } + + // Remove storage annotations for the local being replaced: + // StorageLive(_1) + if let mir::StatementKind::StorageLive(local) | mir::StatementKind::StorageDead(local) = + stmt.kind + { + if local == self.to_rename { + stmt.kind = mir::StatementKind::Nop; + return; + } + } + + self.super_statement(stmt, loc) + } + + fn visit_terminator(&mut self, terminator: &mut mir::Terminator<'tcx>, loc: Location) { + // Ignore the implicit "use" of the return place in a `Return` statement. + if let mir::TerminatorKind::Return = terminator.kind { + return; + } + + self.super_terminator(terminator, loc); + } + + fn visit_local(&mut self, l: &mut Local, ctxt: PlaceContext, _: Location) { + if *l == mir::RETURN_PLACE { + assert_eq!(ctxt, PlaceContext::NonUse(NonUseContext::VarDebugInfo)); + } else if *l == self.to_rename { + *l = mir::RETURN_PLACE; + } + } +} + +struct IsReturnPlaceRead(bool); + +impl IsReturnPlaceRead { + fn run(body: &mir::Body<'_>) -> bool { + let mut vis = IsReturnPlaceRead(false); + vis.visit_body(body); + vis.0 + } +} + +impl<'tcx> Visitor<'tcx> for IsReturnPlaceRead { + fn visit_local(&mut self, l: Local, ctxt: PlaceContext, _: Location) { + if l == mir::RETURN_PLACE && ctxt.is_use() && !ctxt.is_place_assignment() { + self.0 = true; + } + } + + fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, loc: Location) { + // Ignore the implicit "use" of the return place in a `Return` statement. + if let mir::TerminatorKind::Return = terminator.kind { + return; + } + + self.super_terminator(terminator, loc); + } +} diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff index b596e25ddfd..570ec129f06 100644 --- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff +++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff @@ -18,7 +18,7 @@ bb0: { StorageLive(_1); StorageLive(_2); - nop; + _2 = const 1_u32; _1 = Un { us: const 1_u32 }; StorageDead(_2); StorageLive(_3); diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff index b596e25ddfd..570ec129f06 100644 --- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff +++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff @@ -18,7 +18,7 @@ bb0: { StorageLive(_1); StorageLive(_2); - nop; + _2 = const 1_u32; _1 = Un { us: const 1_u32 }; StorageDead(_2); StorageLive(_3); diff --git a/tests/mir-opt/dest-prop/nrvo_miscompile_111005.rs b/tests/mir-opt/nrvo_miscompile_111005.rs similarity index 78% rename from tests/mir-opt/dest-prop/nrvo_miscompile_111005.rs rename to tests/mir-opt/nrvo_miscompile_111005.rs index faf30cfd1b0..18814b0678f 100644 --- a/tests/mir-opt/dest-prop/nrvo_miscompile_111005.rs +++ b/tests/mir-opt/nrvo_miscompile_111005.rs @@ -1,13 +1,13 @@ // skip-filecheck // This is a miscompilation, #111005 to track -//@ test-mir-pass: DestinationPropagation +//@ test-mir-pass: RenameReturnPlace #![feature(custom_mir, core_intrinsics)] extern crate core; use core::intrinsics::mir::*; -// EMIT_MIR nrvo_miscompile_111005.wrong.DestinationPropagation.diff +// EMIT_MIR nrvo_miscompile_111005.wrong.RenameReturnPlace.diff #[custom_mir(dialect = "runtime", phase = "initial")] pub fn wrong(arg: char) -> char { mir!({ diff --git a/tests/mir-opt/dest-prop/nrvo_miscompile_111005.wrong.DestinationPropagation.diff b/tests/mir-opt/nrvo_miscompile_111005.wrong.RenameReturnPlace.diff similarity index 60% rename from tests/mir-opt/dest-prop/nrvo_miscompile_111005.wrong.DestinationPropagation.diff rename to tests/mir-opt/nrvo_miscompile_111005.wrong.RenameReturnPlace.diff index afacf5c1496..260b472daa9 100644 --- a/tests/mir-opt/dest-prop/nrvo_miscompile_111005.wrong.DestinationPropagation.diff +++ b/tests/mir-opt/nrvo_miscompile_111005.wrong.RenameReturnPlace.diff @@ -1,5 +1,5 @@ -- // MIR for `wrong` before DestinationPropagation -+ // MIR for `wrong` after DestinationPropagation +- // MIR for `wrong` before RenameReturnPlace ++ // MIR for `wrong` after RenameReturnPlace fn wrong(_1: char) -> char { let mut _0: char; @@ -9,9 +9,8 @@ - _2 = _1; - _0 = _2; - _2 = const 'b'; -+ nop; + _0 = _1; -+ _1 = const 'b'; ++ _0 = const 'b'; return; } } diff --git a/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-abort.diff b/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-abort.diff similarity index 53% rename from tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-abort.diff rename to tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-abort.diff index 4d34f43fd5c..f7bc5559ab7 100644 --- a/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-abort.diff +++ b/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-abort.diff @@ -1,5 +1,5 @@ -- // MIR for `nrvo` before DestinationPropagation -+ // MIR for `nrvo` after DestinationPropagation +- // MIR for `nrvo` before RenameReturnPlace ++ // MIR for `nrvo` after RenameReturnPlace fn nrvo(_1: for<'a> fn(&'a mut [u8; 1024])) -> [u8; 1024] { debug init => _1; @@ -10,33 +10,32 @@ 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]; ++ _0 = [const 0_u8; 1024]; StorageLive(_3); -- StorageLive(_4); -- _4 = _1; -+ nop; -+ nop; + StorageLive(_4); + _4 = _1; 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]; + _3 = move _4(move _5) -> [return: bb1, unwind unreachable]; } bb1: { StorageDead(_5); -- StorageDead(_4); -+ nop; + StorageDead(_4); StorageDead(_6); StorageDead(_3); - _0 = _2; - StorageDead(_2); +- _0 = _2; +- StorageDead(_2); return; } } diff --git a/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-unwind.diff similarity index 53% rename from tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-unwind.diff rename to tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-unwind.diff index 9c3cbef38d6..3df8e567f1f 100644 --- a/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-unwind.diff +++ b/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-unwind.diff @@ -1,5 +1,5 @@ -- // MIR for `nrvo` before DestinationPropagation -+ // MIR for `nrvo` after DestinationPropagation +- // MIR for `nrvo` before RenameReturnPlace ++ // MIR for `nrvo` after RenameReturnPlace fn nrvo(_1: for<'a> fn(&'a mut [u8; 1024])) -> [u8; 1024] { debug init => _1; @@ -10,33 +10,32 @@ 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]; ++ _0 = [const 0_u8; 1024]; StorageLive(_3); -- StorageLive(_4); -- _4 = _1; -+ nop; -+ nop; + StorageLive(_4); + _4 = _1; 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]; + _3 = move _4(move _5) -> [return: bb1, unwind continue]; } bb1: { StorageDead(_5); -- StorageDead(_4); -+ nop; + StorageDead(_4); StorageDead(_6); StorageDead(_3); - _0 = _2; - StorageDead(_2); +- _0 = _2; +- StorageDead(_2); return; } } diff --git a/tests/mir-opt/dest-prop/nrvo_borrowed.rs b/tests/mir-opt/nrvo_simple.rs similarity index 68% rename from tests/mir-opt/dest-prop/nrvo_borrowed.rs rename to tests/mir-opt/nrvo_simple.rs index 405423f2462..5d2894a704a 100644 --- a/tests/mir-opt/dest-prop/nrvo_borrowed.rs +++ b/tests/mir-opt/nrvo_simple.rs @@ -1,8 +1,8 @@ // skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY -//@ test-mir-pass: DestinationPropagation +//@ test-mir-pass: RenameReturnPlace -// EMIT_MIR nrvo_borrowed.nrvo.DestinationPropagation.diff +// EMIT_MIR nrvo_simple.nrvo.RenameReturnPlace.diff fn nrvo(init: fn(&mut [u8; 1024])) -> [u8; 1024] { let mut buf = [0; 1024]; init(&mut buf); diff --git a/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir index b58e05f9368..47f10451b05 100644 --- a/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir @@ -4,9 +4,10 @@ fn ::partial_cmp(_1: &MultiField, _2: &M debug self => _1; debug other => _2; let mut _0: std::option::Option; - let mut _6: i8; + let mut _6: std::option::Option; + let mut _7: i8; scope 1 { - debug cmp => _0; + debug cmp => _6; } scope 2 (inlined std::cmp::impls::::partial_cmp) { let mut _3: char; @@ -14,9 +15,9 @@ fn ::partial_cmp(_1: &MultiField, _2: &M let mut _5: std::cmp::Ordering; } scope 3 (inlined std::cmp::impls::::partial_cmp) { - let mut _7: i16; let mut _8: i16; - let mut _9: std::cmp::Ordering; + let mut _9: i16; + let mut _10: std::cmp::Ordering; } bb0: { @@ -27,26 +28,27 @@ fn ::partial_cmp(_1: &MultiField, _2: &M _5 = Cmp(move _3, move _4); StorageDead(_4); StorageDead(_3); - _0 = Option::::Some(_5); - _6 = discriminant(_5); - switchInt(move _6) -> [0: bb1, otherwise: bb2]; + _6 = Option::::Some(_5); + _7 = discriminant(_5); + switchInt(move _7) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_9); - StorageLive(_7); - _7 = ((*_1).1: i16); + StorageLive(_10); StorageLive(_8); - _8 = ((*_2).1: i16); - _9 = Cmp(move _7, move _8); - StorageDead(_8); - StorageDead(_7); - _0 = Option::::Some(move _9); + _8 = ((*_1).1: i16); + StorageLive(_9); + _9 = ((*_2).1: i16); + _10 = Cmp(move _8, move _9); StorageDead(_9); + StorageDead(_8); + _0 = Option::::Some(move _10); + StorageDead(_10); goto -> bb3; } bb2: { + _0 = _6; goto -> bb3; } diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir index 163279c1c33..96b4962854d 100644 --- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -5,25 +5,27 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { debug end => _2; debug f => _3; let mut _0: (); - let mut _7: std::option::Option; - let mut _9: &impl Fn(u32); - let mut _10: (u32,); - let _11: (); + let mut _4: u32; + let mut _9: std::option::Option; + let mut _11: &impl Fn(u32); + let mut _12: (u32,); + let _13: (); scope 1 { - debug ((iter: std::ops::Range).0: u32) => _1; + debug ((iter: std::ops::Range).0: u32) => _4; debug ((iter: std::ops::Range).1: u32) => _2; - let _8: u32; + let _10: u32; scope 2 { - debug x => _8; + debug x => _10; } scope 4 (inlined iter::range::>::next) { scope 5 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - let mut _5: bool; - let _6: u32; + let mut _6: bool; + let _7: u32; + let mut _8: u32; scope 6 { } scope 7 (inlined std::cmp::impls::::lt) { - let mut _4: u32; + let mut _5: u32; } } } @@ -32,24 +34,27 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb0: { + StorageLive(_4); + _4 = _1; goto -> bb1; } bb1: { + StorageLive(_9); StorageLive(_7); StorageLive(_6); StorageLive(_5); - StorageLive(_4); - _4 = _1; - _5 = Lt(move _4, _2); - StorageDead(_4); - switchInt(move _5) -> [0: bb2, otherwise: bb4]; + _5 = _4; + _6 = Lt(move _5, _2); + StorageDead(_5); + switchInt(move _6) -> [0: bb2, otherwise: bb4]; } bb2: { - StorageDead(_5); StorageDead(_6); StorageDead(_7); + StorageDead(_9); + StorageDead(_4); drop(_3) -> [return: bb3, unwind unreachable]; } @@ -58,26 +63,29 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb4: { - _6 = _1; - _1 = ::forward_unchecked(_6, const 1_usize) -> [return: bb5, unwind unreachable]; + _7 = _4; + StorageLive(_8); + _8 = ::forward_unchecked(_7, const 1_usize) -> [return: bb5, unwind unreachable]; } bb5: { - _7 = Option::::Some(_6); - StorageDead(_5); + _4 = move _8; + StorageDead(_8); + _9 = Option::::Some(_7); StorageDead(_6); - _8 = ((_7 as Some).0: u32); - StorageLive(_9); - _9 = &_3; - StorageLive(_10); - _10 = (_8,); - _11 = >::call(move _9, move _10) -> [return: bb6, unwind unreachable]; + StorageDead(_7); + _10 = ((_9 as Some).0: u32); + StorageLive(_11); + _11 = &_3; + StorageLive(_12); + _12 = (_10,); + _13 = >::call(move _11, move _12) -> [return: bb6, unwind unreachable]; } bb6: { - StorageDead(_10); + StorageDead(_12); + StorageDead(_11); StorageDead(_9); - StorageDead(_7); goto -> bb1; } } diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir index 05f72ade924..ce8e2bd083e 100644 --- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -5,25 +5,27 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { debug end => _2; debug f => _3; let mut _0: (); - let mut _7: std::option::Option; - let mut _9: &impl Fn(u32); - let mut _10: (u32,); - let _11: (); + let mut _4: u32; + let mut _9: std::option::Option; + let mut _11: &impl Fn(u32); + let mut _12: (u32,); + let _13: (); scope 1 { - debug ((iter: std::ops::Range).0: u32) => _1; + debug ((iter: std::ops::Range).0: u32) => _4; debug ((iter: std::ops::Range).1: u32) => _2; - let _8: u32; + let _10: u32; scope 2 { - debug x => _8; + debug x => _10; } scope 4 (inlined iter::range::>::next) { scope 5 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - let mut _5: bool; - let _6: u32; + let mut _6: bool; + let _7: u32; + let mut _8: u32; scope 6 { } scope 7 (inlined std::cmp::impls::::lt) { - let mut _4: u32; + let mut _5: u32; } } } @@ -32,24 +34,27 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb0: { + StorageLive(_4); + _4 = _1; goto -> bb1; } bb1: { + StorageLive(_9); StorageLive(_7); StorageLive(_6); StorageLive(_5); - StorageLive(_4); - _4 = _1; - _5 = Lt(move _4, _2); - StorageDead(_4); - switchInt(move _5) -> [0: bb2, otherwise: bb4]; + _5 = _4; + _6 = Lt(move _5, _2); + StorageDead(_5); + switchInt(move _6) -> [0: bb2, otherwise: bb4]; } bb2: { - StorageDead(_5); StorageDead(_6); StorageDead(_7); + StorageDead(_9); + StorageDead(_4); drop(_3) -> [return: bb3, unwind continue]; } @@ -58,26 +63,29 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb4: { - _6 = _1; - _1 = ::forward_unchecked(_6, const 1_usize) -> [return: bb5, unwind: bb7]; + _7 = _4; + StorageLive(_8); + _8 = ::forward_unchecked(_7, const 1_usize) -> [return: bb5, unwind: bb7]; } bb5: { - _7 = Option::::Some(_6); - StorageDead(_5); + _4 = move _8; + StorageDead(_8); + _9 = Option::::Some(_7); StorageDead(_6); - _8 = ((_7 as Some).0: u32); - StorageLive(_9); - _9 = &_3; - StorageLive(_10); - _10 = (_8,); - _11 = >::call(move _9, move _10) -> [return: bb6, unwind: bb7]; + StorageDead(_7); + _10 = ((_9 as Some).0: u32); + StorageLive(_11); + _11 = &_3; + StorageLive(_12); + _12 = (_10,); + _13 = >::call(move _11, move _12) -> [return: bb6, unwind: bb7]; } bb6: { - StorageDead(_10); + StorageDead(_12); + StorageDead(_11); StorageDead(_9); - StorageDead(_7); goto -> bb1; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir index e761dc1e8b8..d979c5ec1d5 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir @@ -4,22 +4,22 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; - let mut _12: std::iter::Enumerate>; + let mut _12: std::slice::Iter<'_, T>; let mut _13: std::iter::Enumerate>; - let mut _14: &mut std::iter::Enumerate>; - let mut _15: std::option::Option<(usize, &T)>; - let mut _16: isize; - let mut _19: &impl Fn(usize, &T); - let mut _20: (usize, &T); - let _21: (); + let mut _14: std::iter::Enumerate>; + let mut _15: &mut std::iter::Enumerate>; + let mut _16: std::option::Option<(usize, &T)>; + let mut _17: isize; + let mut _20: &impl Fn(usize, &T); + let mut _21: (usize, &T); + let _22: (); scope 1 { - debug iter => _13; - let _17: usize; - let _18: &T; + debug iter => _14; + let _18: usize; + let _19: &T; scope 2 { - debug i => _17; - debug x => _18; + debug i => _18; + debug x => _19; } } scope 3 (inlined core::slice::::iter) { @@ -28,10 +28,11 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _7: bool; let mut _8: *mut T; let mut _9: *mut T; - let mut _10: *const T; + let mut _11: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { + let _10: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -60,16 +61,16 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb0: { - StorageLive(_11); + StorageLive(_12); StorageLive(_3); StorageLive(_6); - StorageLive(_10); StorageLive(_4); StorageLive(_5); _3 = Len((*_1)); _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; + StorageLive(_10); StorageLive(_7); _7 = const ::IS_ZST; switchInt(move _7) -> [0: bb1, otherwise: bb2]; @@ -93,35 +94,38 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb3: { StorageDead(_7); - _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; + StorageLive(_11); + _11 = _10; + _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_11); + StorageDead(_10); StorageDead(_5); StorageDead(_4); - StorageDead(_10); StorageDead(_6); StorageDead(_3); - _12 = Enumerate::> { iter: _11, count: const 0_usize }; - StorageDead(_11); - StorageLive(_13); - _13 = _12; + _13 = Enumerate::> { iter: _12, count: const 0_usize }; + StorageDead(_12); + StorageLive(_14); + _14 = _13; goto -> bb4; } bb4: { + StorageLive(_16); StorageLive(_15); - StorageLive(_14); - _14 = &mut _13; - _15 = > as Iterator>::next(move _14) -> [return: bb5, unwind unreachable]; + _15 = &mut _14; + _16 = > as Iterator>::next(move _15) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_15); + _17 = discriminant(_16); + switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_15); - StorageDead(_13); + StorageDead(_16); + StorageDead(_14); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -130,19 +134,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb8: { - _17 = (((_15 as Some).0: (usize, &T)).0: usize); - _18 = (((_15 as Some).0: (usize, &T)).1: &T); - StorageLive(_19); - _19 = &_2; + _18 = (((_16 as Some).0: (usize, &T)).0: usize); + _19 = (((_16 as Some).0: (usize, &T)).1: &T); StorageLive(_20); - _20 = (_17, _18); - _21 = >::call(move _19, move _20) -> [return: bb9, unwind unreachable]; + _20 = &_2; + StorageLive(_21); + _21 = (_18, _19); + _22 = >::call(move _20, move _21) -> [return: bb9, unwind unreachable]; } bb9: { + StorageDead(_21); StorageDead(_20); - StorageDead(_19); - StorageDead(_15); + StorageDead(_16); goto -> bb4; } 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 da293cdb5a1..8491c49f767 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 @@ -4,22 +4,22 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; - let mut _12: std::iter::Enumerate>; + let mut _12: std::slice::Iter<'_, T>; let mut _13: std::iter::Enumerate>; - let mut _14: &mut std::iter::Enumerate>; - let mut _15: std::option::Option<(usize, &T)>; - let mut _16: isize; - let mut _19: &impl Fn(usize, &T); - let mut _20: (usize, &T); - let _21: (); + let mut _14: std::iter::Enumerate>; + let mut _15: &mut std::iter::Enumerate>; + let mut _16: std::option::Option<(usize, &T)>; + let mut _17: isize; + let mut _20: &impl Fn(usize, &T); + let mut _21: (usize, &T); + let _22: (); scope 1 { - debug iter => _13; - let _17: usize; - let _18: &T; + debug iter => _14; + let _18: usize; + let _19: &T; scope 2 { - debug i => _17; - debug x => _18; + debug i => _18; + debug x => _19; } } scope 3 (inlined core::slice::::iter) { @@ -28,10 +28,11 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _7: bool; let mut _8: *mut T; let mut _9: *mut T; - let mut _10: *const T; + let mut _11: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { + let _10: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -60,16 +61,16 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb0: { - StorageLive(_11); + StorageLive(_12); StorageLive(_3); StorageLive(_6); - StorageLive(_10); StorageLive(_4); StorageLive(_5); _3 = Len((*_1)); _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; + StorageLive(_10); StorageLive(_7); _7 = const ::IS_ZST; switchInt(move _7) -> [0: bb1, otherwise: bb2]; @@ -93,35 +94,38 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb3: { StorageDead(_7); - _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; + StorageLive(_11); + _11 = _10; + _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_11); + StorageDead(_10); StorageDead(_5); StorageDead(_4); - StorageDead(_10); StorageDead(_6); StorageDead(_3); - _12 = Enumerate::> { iter: _11, count: const 0_usize }; - StorageDead(_11); - StorageLive(_13); - _13 = _12; + _13 = Enumerate::> { iter: _12, count: const 0_usize }; + StorageDead(_12); + StorageLive(_14); + _14 = _13; goto -> bb4; } bb4: { + StorageLive(_16); StorageLive(_15); - StorageLive(_14); - _14 = &mut _13; - _15 = > as Iterator>::next(move _14) -> [return: bb5, unwind: bb11]; + _15 = &mut _14; + _16 = > as Iterator>::next(move _15) -> [return: bb5, unwind: bb11]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_15); + _17 = discriminant(_16); + switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_15); - StorageDead(_13); + StorageDead(_16); + StorageDead(_14); drop(_2) -> [return: bb7, unwind continue]; } @@ -130,19 +134,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb8: { - _17 = (((_15 as Some).0: (usize, &T)).0: usize); - _18 = (((_15 as Some).0: (usize, &T)).1: &T); - StorageLive(_19); - _19 = &_2; + _18 = (((_16 as Some).0: (usize, &T)).0: usize); + _19 = (((_16 as Some).0: (usize, &T)).1: &T); StorageLive(_20); - _20 = (_17, _18); - _21 = >::call(move _19, move _20) -> [return: bb9, unwind: bb11]; + _20 = &_2; + StorageLive(_21); + _21 = (_18, _19); + _22 = >::call(move _20, move _21) -> [return: bb9, unwind: bb11]; } bb9: { + StorageDead(_21); StorageDead(_20); - StorageDead(_19); - StorageDead(_15); + StorageDead(_16); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir index d824857ac5d..67dd0c85ea1 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -4,19 +4,19 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; let mut _12: std::slice::Iter<'_, T>; - let mut _13: &mut std::slice::Iter<'_, T>; - 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::slice::Iter<'_, T>; + let mut _14: &mut std::slice::Iter<'_, T>; + let mut _15: std::option::Option<&T>; + let mut _16: isize; + let mut _18: &impl Fn(&T); + let mut _19: (&T,); + let _20: (); scope 1 { - debug iter => _12; - let _16: &T; + debug iter => _13; + let _17: &T; scope 2 { - debug x => _16; + debug x => _17; } } scope 3 (inlined core::slice::::iter) { @@ -25,10 +25,11 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _7: bool; let mut _8: *mut T; let mut _9: *mut T; - let mut _10: *const T; + let mut _11: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { + let _10: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -55,13 +56,13 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { bb0: { StorageLive(_3); StorageLive(_6); - StorageLive(_10); StorageLive(_4); StorageLive(_5); _3 = Len((*_1)); _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; + StorageLive(_10); StorageLive(_7); _7 = const ::IS_ZST; switchInt(move _7) -> [0: bb1, otherwise: bb2]; @@ -85,33 +86,36 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { bb3: { StorageDead(_7); - _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; + StorageLive(_11); + _11 = _10; + _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_11); + StorageDead(_10); StorageDead(_5); StorageDead(_4); - StorageDead(_10); StorageDead(_6); StorageDead(_3); - StorageLive(_12); - _12 = _11; + StorageLive(_13); + _13 = _12; goto -> bb4; } bb4: { + StorageLive(_15); StorageLive(_14); - StorageLive(_13); - _13 = &mut _12; - _14 = as Iterator>::next(move _13) -> [return: bb5, unwind unreachable]; + _14 = &mut _13; + _15 = as Iterator>::next(move _14) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_13); - _15 = discriminant(_14); - switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_14); + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_14); - StorageDead(_12); + StorageDead(_15); + StorageDead(_13); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -120,18 +124,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _16 = ((_14 as Some).0: &T); - StorageLive(_17); - _17 = &_2; + _17 = ((_15 as Some).0: &T); StorageLive(_18); - _18 = (_16,); - _19 = >::call(move _17, move _18) -> [return: bb9, unwind unreachable]; + _18 = &_2; + StorageLive(_19); + _19 = (_17,); + _20 = >::call(move _18, move _19) -> [return: bb9, unwind unreachable]; } bb9: { + StorageDead(_19); StorageDead(_18); - StorageDead(_17); - StorageDead(_14); + StorageDead(_15); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir index 75437119aa6..7c41e9e1f1b 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -4,19 +4,19 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; let mut _12: std::slice::Iter<'_, T>; - let mut _13: &mut std::slice::Iter<'_, T>; - 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::slice::Iter<'_, T>; + let mut _14: &mut std::slice::Iter<'_, T>; + let mut _15: std::option::Option<&T>; + let mut _16: isize; + let mut _18: &impl Fn(&T); + let mut _19: (&T,); + let _20: (); scope 1 { - debug iter => _12; - let _16: &T; + debug iter => _13; + let _17: &T; scope 2 { - debug x => _16; + debug x => _17; } } scope 3 (inlined core::slice::::iter) { @@ -25,10 +25,11 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _7: bool; let mut _8: *mut T; let mut _9: *mut T; - let mut _10: *const T; + let mut _11: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { + let _10: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -55,13 +56,13 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { bb0: { StorageLive(_3); StorageLive(_6); - StorageLive(_10); StorageLive(_4); StorageLive(_5); _3 = Len((*_1)); _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; + StorageLive(_10); StorageLive(_7); _7 = const ::IS_ZST; switchInt(move _7) -> [0: bb1, otherwise: bb2]; @@ -85,33 +86,36 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { bb3: { StorageDead(_7); - _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; + StorageLive(_11); + _11 = _10; + _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_11); + StorageDead(_10); StorageDead(_5); StorageDead(_4); - StorageDead(_10); StorageDead(_6); StorageDead(_3); - StorageLive(_12); - _12 = _11; + StorageLive(_13); + _13 = _12; goto -> bb4; } bb4: { + StorageLive(_15); StorageLive(_14); - StorageLive(_13); - _13 = &mut _12; - _14 = as Iterator>::next(move _13) -> [return: bb5, unwind: bb11]; + _14 = &mut _13; + _15 = as Iterator>::next(move _14) -> [return: bb5, unwind: bb11]; } bb5: { - StorageDead(_13); - _15 = discriminant(_14); - switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_14); + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_14); - StorageDead(_12); + StorageDead(_15); + StorageDead(_13); drop(_2) -> [return: bb7, unwind continue]; } @@ -120,18 +124,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _16 = ((_14 as Some).0: &T); - StorageLive(_17); - _17 = &_2; + _17 = ((_15 as Some).0: &T); StorageLive(_18); - _18 = (_16,); - _19 = >::call(move _17, move _18) -> [return: bb9, unwind: bb11]; + _18 = &_2; + StorageLive(_19); + _19 = (_17,); + _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; } bb9: { + StorageDead(_19); StorageDead(_18); - StorageDead(_17); - StorageDead(_14); + StorageDead(_15); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir index dc370911d8a..dbe6f39548c 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir @@ -6,27 +6,28 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _0: (); let mut _3: usize; let mut _4: usize; - let mut _8: std::option::Option; - let mut _10: usize; - let mut _11: bool; - let mut _13: &impl Fn(usize, &T); - let mut _14: (usize, &T); - let _15: (); + let mut _9: std::option::Option; + let mut _11: usize; + let mut _12: bool; + let mut _14: &impl Fn(usize, &T); + let mut _15: (usize, &T); + let _16: (); scope 1 { debug ((iter: std::ops::Range).0: usize) => _4; debug ((iter: std::ops::Range).1: usize) => _3; - let _9: usize; + let _10: usize; scope 2 { - debug i => _9; - let _12: &T; + debug i => _10; + let _13: &T; scope 3 { - debug x => _12; + debug x => _13; } } scope 5 (inlined iter::range::>::next) { scope 6 (inlined as iter::range::RangeIteratorImpl>::spec_next) { let mut _6: bool; let _7: usize; + let mut _8: usize; scope 7 { } scope 8 (inlined std::cmp::impls::::lt) { @@ -40,12 +41,13 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb0: { _3 = Len((*_1)); + StorageLive(_4); _4 = const 0_usize; goto -> bb1; } bb1: { - StorageLive(_8); + StorageLive(_9); StorageLive(_7); StorageLive(_6); StorageLive(_5); @@ -58,7 +60,8 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb2: { StorageDead(_6); StorageDead(_7); - StorageDead(_8); + StorageDead(_9); + StorageDead(_4); drop(_2) -> [return: bb3, unwind unreachable]; } @@ -68,32 +71,35 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb4: { _7 = _4; - _4 = ::forward_unchecked(_7, const 1_usize) -> [return: bb5, unwind unreachable]; + StorageLive(_8); + _8 = ::forward_unchecked(_7, const 1_usize) -> [return: bb5, unwind unreachable]; } bb5: { - _8 = Option::::Some(_7); + _4 = move _8; + StorageDead(_8); + _9 = Option::::Some(_7); StorageDead(_6); StorageDead(_7); - _9 = ((_8 as Some).0: usize); - _10 = Len((*_1)); - _11 = Lt(_9, _10); - assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, _9) -> [success: bb6, unwind unreachable]; + _10 = ((_9 as Some).0: usize); + _11 = Len((*_1)); + _12 = Lt(_10, _11); + assert(move _12, "index out of bounds: the length is {} but the index is {}", move _11, _10) -> [success: bb6, unwind unreachable]; } bb6: { - _12 = &(*_1)[_9]; - StorageLive(_13); - _13 = &_2; + _13 = &(*_1)[_10]; StorageLive(_14); - _14 = (_9, _12); - _15 = >::call(move _13, move _14) -> [return: bb7, unwind unreachable]; + _14 = &_2; + StorageLive(_15); + _15 = (_10, _13); + _16 = >::call(move _14, move _15) -> [return: bb7, unwind unreachable]; } bb7: { + StorageDead(_15); StorageDead(_14); - StorageDead(_13); - StorageDead(_8); + StorageDead(_9); goto -> bb1; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir index 751e14441d4..5b6441cfb3b 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir @@ -6,27 +6,28 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _0: (); let mut _3: usize; let mut _4: usize; - let mut _8: std::option::Option; - let mut _10: usize; - let mut _11: bool; - let mut _13: &impl Fn(usize, &T); - let mut _14: (usize, &T); - let _15: (); + let mut _9: std::option::Option; + let mut _11: usize; + let mut _12: bool; + let mut _14: &impl Fn(usize, &T); + let mut _15: (usize, &T); + let _16: (); scope 1 { debug ((iter: std::ops::Range).0: usize) => _4; debug ((iter: std::ops::Range).1: usize) => _3; - let _9: usize; + let _10: usize; scope 2 { - debug i => _9; - let _12: &T; + debug i => _10; + let _13: &T; scope 3 { - debug x => _12; + debug x => _13; } } scope 5 (inlined iter::range::>::next) { scope 6 (inlined as iter::range::RangeIteratorImpl>::spec_next) { let mut _6: bool; let _7: usize; + let mut _8: usize; scope 7 { } scope 8 (inlined std::cmp::impls::::lt) { @@ -40,12 +41,13 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb0: { _3 = Len((*_1)); + StorageLive(_4); _4 = const 0_usize; goto -> bb1; } bb1: { - StorageLive(_8); + StorageLive(_9); StorageLive(_7); StorageLive(_6); StorageLive(_5); @@ -58,7 +60,8 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb2: { StorageDead(_6); StorageDead(_7); - StorageDead(_8); + StorageDead(_9); + StorageDead(_4); drop(_2) -> [return: bb3, unwind continue]; } @@ -68,32 +71,35 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb4: { _7 = _4; - _4 = ::forward_unchecked(_7, const 1_usize) -> [return: bb5, unwind: bb8]; + StorageLive(_8); + _8 = ::forward_unchecked(_7, const 1_usize) -> [return: bb5, unwind: bb8]; } bb5: { - _8 = Option::::Some(_7); + _4 = move _8; + StorageDead(_8); + _9 = Option::::Some(_7); StorageDead(_6); StorageDead(_7); - _9 = ((_8 as Some).0: usize); - _10 = Len((*_1)); - _11 = Lt(_9, _10); - assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, _9) -> [success: bb6, unwind: bb8]; + _10 = ((_9 as Some).0: usize); + _11 = Len((*_1)); + _12 = Lt(_10, _11); + assert(move _12, "index out of bounds: the length is {} but the index is {}", move _11, _10) -> [success: bb6, unwind: bb8]; } bb6: { - _12 = &(*_1)[_9]; - StorageLive(_13); - _13 = &_2; + _13 = &(*_1)[_10]; StorageLive(_14); - _14 = (_9, _12); - _15 = >::call(move _13, move _14) -> [return: bb7, unwind: bb8]; + _14 = &_2; + StorageLive(_15); + _15 = (_10, _13); + _16 = >::call(move _14, move _15) -> [return: bb7, unwind: bb8]; } bb7: { + StorageDead(_15); StorageDead(_14); - StorageDead(_13); - StorageDead(_8); + StorageDead(_9); goto -> bb1; } 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 9200d311d6d..ffeef1e04a1 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 @@ -4,22 +4,22 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; - let mut _12: std::iter::Rev>; + let mut _12: std::slice::Iter<'_, T>; let mut _13: std::iter::Rev>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _14: std::iter::Rev>; + let mut _16: std::option::Option<&T>; + let mut _17: isize; + let mut _19: &impl Fn(&T); + let mut _20: (&T,); + let _21: (); scope 1 { - debug iter => _13; - let _17: &T; + debug iter => _14; + let _18: &T; scope 2 { - debug x => _17; + debug x => _18; } scope 17 (inlined > as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; + let mut _15: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { @@ -28,10 +28,11 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _7: bool; let mut _8: *mut T; let mut _9: *mut T; - let mut _10: *const T; + let mut _11: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { + let _10: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -60,16 +61,16 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb0: { - StorageLive(_11); + StorageLive(_12); StorageLive(_3); StorageLive(_6); - StorageLive(_10); StorageLive(_4); StorageLive(_5); _3 = Len((*_1)); _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; + StorageLive(_10); StorageLive(_7); _7 = const ::IS_ZST; switchInt(move _7) -> [0: bb1, otherwise: bb2]; @@ -93,35 +94,38 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { bb3: { StorageDead(_7); - _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; + StorageLive(_11); + _11 = _10; + _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_11); + StorageDead(_10); StorageDead(_5); StorageDead(_4); - StorageDead(_10); StorageDead(_6); StorageDead(_3); - _12 = Rev::> { iter: _11 }; - StorageDead(_11); - StorageLive(_13); - _13 = _12; + _13 = Rev::> { iter: _12 }; + StorageDead(_12); + StorageLive(_14); + _14 = _13; goto -> bb4; } bb4: { + StorageLive(_16); StorageLive(_15); - StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable]; + _15 = &mut (_14.0: std::slice::Iter<'_, T>); + _16 = as DoubleEndedIterator>::next_back(move _15) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_15); + _17 = discriminant(_16); + switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_15); - StorageDead(_13); + StorageDead(_16); + StorageDead(_14); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -130,18 +134,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _17 = ((_15 as Some).0: &T); - StorageLive(_18); - _18 = &_2; + _18 = ((_16 as Some).0: &T); StorageLive(_19); - _19 = (_17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind unreachable]; + _19 = &_2; + StorageLive(_20); + _20 = (_18,); + _21 = >::call(move _19, move _20) -> [return: bb9, unwind unreachable]; } bb9: { + StorageDead(_20); StorageDead(_19); - StorageDead(_18); - StorageDead(_15); + StorageDead(_16); 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 5a2d9d2a681..c7cd37afd86 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 @@ -4,22 +4,22 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; - let mut _12: std::iter::Rev>; + let mut _12: std::slice::Iter<'_, T>; let mut _13: std::iter::Rev>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _14: std::iter::Rev>; + let mut _16: std::option::Option<&T>; + let mut _17: isize; + let mut _19: &impl Fn(&T); + let mut _20: (&T,); + let _21: (); scope 1 { - debug iter => _13; - let _17: &T; + debug iter => _14; + let _18: &T; scope 2 { - debug x => _17; + debug x => _18; } scope 17 (inlined > as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; + let mut _15: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { @@ -28,10 +28,11 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _7: bool; let mut _8: *mut T; let mut _9: *mut T; - let mut _10: *const T; + let mut _11: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { + let _10: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -60,16 +61,16 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb0: { - StorageLive(_11); + StorageLive(_12); StorageLive(_3); StorageLive(_6); - StorageLive(_10); StorageLive(_4); StorageLive(_5); _3 = Len((*_1)); _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; + StorageLive(_10); StorageLive(_7); _7 = const ::IS_ZST; switchInt(move _7) -> [0: bb1, otherwise: bb2]; @@ -93,35 +94,38 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { bb3: { StorageDead(_7); - _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; + StorageLive(_11); + _11 = _10; + _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_11); + StorageDead(_10); StorageDead(_5); StorageDead(_4); - StorageDead(_10); StorageDead(_6); StorageDead(_3); - _12 = Rev::> { iter: _11 }; - StorageDead(_11); - StorageLive(_13); - _13 = _12; + _13 = Rev::> { iter: _12 }; + StorageDead(_12); + StorageLive(_14); + _14 = _13; goto -> bb4; } bb4: { + StorageLive(_16); StorageLive(_15); - StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11]; + _15 = &mut (_14.0: std::slice::Iter<'_, T>); + _16 = as DoubleEndedIterator>::next_back(move _15) -> [return: bb5, unwind: bb11]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_15); + _17 = discriminant(_16); + switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_15); - StorageDead(_13); + StorageDead(_16); + StorageDead(_14); drop(_2) -> [return: bb7, unwind continue]; } @@ -130,18 +134,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _17 = ((_15 as Some).0: &T); - StorageLive(_18); - _18 = &_2; + _18 = ((_16 as Some).0: &T); StorageLive(_19); - _19 = (_17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; + _19 = &_2; + StorageLive(_20); + _20 = (_18,); + _21 = >::call(move _19, move _20) -> [return: bb9, unwind: bb11]; } bb9: { + StorageDead(_20); StorageDead(_19); - StorageDead(_18); - StorageDead(_15); + StorageDead(_16); goto -> bb4; }