From 20e8d540f925c0ed3b08bfd71023288be47864e7 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Thu, 15 Feb 2024 01:20:19 +0000 Subject: [PATCH] Reverts rust-lang/rust#117206 cc @cjgillot @tmiasko This revert is based on the following report of a regression caused by this PR: https://github.com/rust-lang/rust/issues/121094 In accordance with the compiler team [revert policy], PRs that cause meaningful regressions should be reverted and re-landed once the regression has been fixed (and a regression test has been added, where appropriate). [revert policy]: https://forge.rust-lang.org/compiler/reviews.html#reverts Fear not! Regressions happen. Please rest assured that this does not represent a negative judgment of your contribution or ability to contribute positively to Rust in the future. We simply want to prioritize keeping existing use cases working, and keep the compiler more stable for everyone. r? compiler --- .../rustc_mir_transform/src/const_goto.rs | 128 +++++++ .../rustc_mir_transform/src/jump_threading.rs | 2 +- compiler/rustc_mir_transform/src/lib.rs | 7 + .../src/separate_const_switch.rs | 343 ++++++++++++++++++ tests/coverage/closure.cov-map | 36 +- tests/coverage/issue-84561.cov-map | 38 +- tests/coverage/try_error_result.cov-map | 237 ++++++------ tests/coverage/yield.cov-map | 6 +- .../const_goto.issue_77355_opt.ConstGoto.diff | 50 +++ tests/mir-opt/const_goto.rs | 19 + ...onst_goto_const_eval_fail.f.ConstGoto.diff | 51 +++ ..._goto_const_eval_fail.f.JumpThreading.diff | 47 --- tests/mir-opt/const_goto_const_eval_fail.rs | 2 +- ...oto_storage.match_nested_if.ConstGoto.diff | 102 ++++++ tests/mir-opt/const_goto_storage.rs | 22 ++ ...cked_ops.step_forward.PreCodegen.after.mir | 56 ++- .../loops.int_range.PreCodegen.after.mir | 69 ++-- ...macro.issue_77355_opt.PreCodegen.after.mir | 22 -- tests/mir-opt/pre-codegen/matches_macro.rs | 27 -- ...ward_loop.PreCodegen.after.panic-abort.mir | 89 +++-- ...ard_loop.PreCodegen.after.panic-unwind.mir | 95 +++-- ...ange_loop.PreCodegen.after.panic-abort.mir | 107 +++--- ...nge_loop.PreCodegen.after.panic-unwind.mir | 113 +++--- .../try_identity.new.PreCodegen.after.mir | 46 ++- ..._switch.identity.SeparateConstSwitch.diff} | 19 +- tests/mir-opt/separate_const_switch.rs | 4 +- ...itch.too_complex.SeparateConstSwitch.diff} | 15 +- 27 files changed, 1286 insertions(+), 466 deletions(-) create mode 100644 compiler/rustc_mir_transform/src/const_goto.rs create mode 100644 compiler/rustc_mir_transform/src/separate_const_switch.rs create mode 100644 tests/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff create mode 100644 tests/mir-opt/const_goto.rs create mode 100644 tests/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff delete mode 100644 tests/mir-opt/const_goto_const_eval_fail.f.JumpThreading.diff create mode 100644 tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff create mode 100644 tests/mir-opt/const_goto_storage.rs delete mode 100644 tests/mir-opt/pre-codegen/matches_macro.issue_77355_opt.PreCodegen.after.mir delete mode 100644 tests/mir-opt/pre-codegen/matches_macro.rs rename tests/mir-opt/{separate_const_switch.identity.JumpThreading.diff => separate_const_switch.identity.SeparateConstSwitch.diff} (87%) rename tests/mir-opt/{separate_const_switch.too_complex.JumpThreading.diff => separate_const_switch.too_complex.SeparateConstSwitch.diff} (83%) diff --git a/compiler/rustc_mir_transform/src/const_goto.rs b/compiler/rustc_mir_transform/src/const_goto.rs new file mode 100644 index 0000000000000..cb5b66b314d69 --- /dev/null +++ b/compiler/rustc_mir_transform/src/const_goto.rs @@ -0,0 +1,128 @@ +//! This pass optimizes the following sequence +//! ```rust,ignore (example) +//! bb2: { +//! _2 = const true; +//! goto -> bb3; +//! } +//! +//! bb3: { +//! switchInt(_2) -> [false: bb4, otherwise: bb5]; +//! } +//! ``` +//! into +//! ```rust,ignore (example) +//! bb2: { +//! _2 = const true; +//! goto -> bb5; +//! } +//! ``` + +use rustc_middle::mir::*; +use rustc_middle::ty::TyCtxt; +use rustc_middle::{mir::visit::Visitor, ty::ParamEnv}; + +use super::simplify::{simplify_cfg, simplify_locals}; + +pub struct ConstGoto; + +impl<'tcx> MirPass<'tcx> for ConstGoto { + fn is_enabled(&self, sess: &rustc_session::Session) -> bool { + // This pass participates in some as-of-yet untested unsoundness found + // in https://github.com/rust-lang/rust/issues/112460 + sess.mir_opt_level() >= 2 && sess.opts.unstable_opts.unsound_mir_opts + } + + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + trace!("Running ConstGoto on {:?}", body.source); + let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); + let mut opt_finder = + ConstGotoOptimizationFinder { tcx, body, optimizations: vec![], param_env }; + opt_finder.visit_body(body); + let should_simplify = !opt_finder.optimizations.is_empty(); + for opt in opt_finder.optimizations { + let block = &mut body.basic_blocks_mut()[opt.bb_with_goto]; + block.statements.extend(opt.stmts_move_up); + let terminator = block.terminator_mut(); + let new_goto = TerminatorKind::Goto { target: opt.target_to_use_in_goto }; + debug!("SUCCESS: replacing `{:?}` with `{:?}`", terminator.kind, new_goto); + terminator.kind = new_goto; + } + + // if we applied optimizations, we potentially have some cfg to cleanup to + // make it easier for further passes + if should_simplify { + simplify_cfg(body); + simplify_locals(body, tcx); + } + } +} + +impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> { + fn visit_basic_block_data(&mut self, block: BasicBlock, data: &BasicBlockData<'tcx>) { + if data.is_cleanup { + // Because of the restrictions around control flow in cleanup blocks, we don't perform + // this optimization at all in such blocks. + return; + } + self.super_basic_block_data(block, data); + } + + fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { + let _: Option<_> = try { + let target = terminator.kind.as_goto()?; + // We only apply this optimization if the last statement is a const assignment + let last_statement = self.body.basic_blocks[location.block].statements.last()?; + + if let (place, Rvalue::Use(Operand::Constant(_const))) = + last_statement.kind.as_assign()? + { + // We found a constant being assigned to `place`. + // Now check that the target of this Goto switches on this place. + let target_bb = &self.body.basic_blocks[target]; + + // The `StorageDead(..)` statement does not affect the functionality of mir. + // We can move this part of the statement up to the predecessor. + let mut stmts_move_up = Vec::new(); + for stmt in &target_bb.statements { + if let StatementKind::StorageDead(..) = stmt.kind { + stmts_move_up.push(stmt.clone()) + } else { + None?; + } + } + + let target_bb_terminator = target_bb.terminator(); + let (discr, targets) = target_bb_terminator.kind.as_switch()?; + if discr.place() == Some(*place) { + let switch_ty = place.ty(self.body.local_decls(), self.tcx).ty; + debug_assert_eq!(switch_ty, _const.ty()); + // We now know that the Switch matches on the const place, and it is statementless + // Now find which value in the Switch matches the const value. + let const_value = _const.const_.try_eval_bits(self.tcx, self.param_env)?; + let target_to_use_in_goto = targets.target_for_value(const_value); + self.optimizations.push(OptimizationToApply { + bb_with_goto: location.block, + target_to_use_in_goto, + stmts_move_up, + }); + } + } + Some(()) + }; + + self.super_terminator(terminator, location); + } +} + +struct OptimizationToApply<'tcx> { + bb_with_goto: BasicBlock, + target_to_use_in_goto: BasicBlock, + stmts_move_up: Vec>, +} + +pub struct ConstGotoOptimizationFinder<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + body: &'a Body<'tcx>, + param_env: ParamEnv<'tcx>, + optimizations: Vec>, +} diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 78ba166ba4339..7a70ed5cb7f0e 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -60,7 +60,7 @@ const MAX_PLACES: usize = 100; impl<'tcx> MirPass<'tcx> for JumpThreading { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.mir_opt_level() >= 2 + sess.mir_opt_level() >= 4 } #[instrument(skip_all level = "debug")] diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 9f30f2836f195..2b13e74c67566 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -59,6 +59,7 @@ mod remove_place_mention; mod add_subtyping_projections; pub mod cleanup_post_borrowck; mod const_debuginfo; +mod const_goto; mod const_prop; mod const_prop_lint; mod copy_prop; @@ -102,6 +103,7 @@ mod remove_unneeded_drops; mod remove_zsts; mod required_consts; mod reveal_all; +mod separate_const_switch; mod shim; mod ssa; // This pass is public to allow external drivers to perform MIR cleanup @@ -588,6 +590,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // Has to run after `slice::len` lowering &normalize_array_len::NormalizeArrayLen, + &const_goto::ConstGoto, &ref_prop::ReferencePropagation, &sroa::ScalarReplacementOfAggregates, &match_branches::MatchBranchSimplification, @@ -598,6 +601,10 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &dead_store_elimination::DeadStoreElimination::Initial, &gvn::GVN, &simplify::SimplifyLocals::AfterGVN, + // Perform `SeparateConstSwitch` after SSA-based analyses, as cloning blocks may + // destroy the SSA property. It should still happen before const-propagation, so the + // latter pass will leverage the created opportunities. + &separate_const_switch::SeparateConstSwitch, &dataflow_const_prop::DataflowConstProp, &const_debuginfo::ConstDebugInfo, &o1(simplify_branches::SimplifyConstCondition::AfterConstProp), diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs new file mode 100644 index 0000000000000..7120ef7214271 --- /dev/null +++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs @@ -0,0 +1,343 @@ +//! A pass that duplicates switch-terminated blocks +//! into a new copy for each predecessor, provided +//! the predecessor sets the value being switched +//! over to a constant. +//! +//! The purpose of this pass is to help constant +//! propagation passes to simplify the switch terminator +//! of the copied blocks into gotos when some predecessors +//! statically determine the output of switches. +//! +//! ```text +//! x = 12 --- ---> something +//! \ / 12 +//! --> switch x +//! / \ otherwise +//! x = y --- ---> something else +//! ``` +//! becomes +//! ```text +//! x = 12 ---> switch x ------> something +//! \ / 12 +//! X +//! / \ otherwise +//! x = y ---> switch x ------> something else +//! ``` +//! so it can hopefully later be turned by another pass into +//! ```text +//! x = 12 --------------------> something +//! / 12 +//! / +//! / otherwise +//! x = y ---- switch x ------> something else +//! ``` +//! +//! This optimization is meant to cover simple cases +//! like `?` desugaring. For now, it thus focuses on +//! simplicity rather than completeness (it notably +//! sometimes duplicates abusively). + +use rustc_middle::mir::*; +use rustc_middle::ty::TyCtxt; +use smallvec::SmallVec; + +pub struct SeparateConstSwitch; + +impl<'tcx> MirPass<'tcx> for SeparateConstSwitch { + fn is_enabled(&self, sess: &rustc_session::Session) -> bool { + // This pass participates in some as-of-yet untested unsoundness found + // in https://github.com/rust-lang/rust/issues/112460 + sess.mir_opt_level() >= 2 && sess.opts.unstable_opts.unsound_mir_opts + } + + fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + // If execution did something, applying a simplification layer + // helps later passes optimize the copy away. + if separate_const_switch(body) > 0 { + super::simplify::simplify_cfg(body); + } + } +} + +/// Returns the amount of blocks that were duplicated +pub fn separate_const_switch(body: &mut Body<'_>) -> usize { + let mut new_blocks: SmallVec<[(BasicBlock, BasicBlock); 6]> = SmallVec::new(); + let predecessors = body.basic_blocks.predecessors(); + 'block_iter: for (block_id, block) in body.basic_blocks.iter_enumerated() { + if let TerminatorKind::SwitchInt { + discr: Operand::Copy(switch_place) | Operand::Move(switch_place), + .. + } = block.terminator().kind + { + // If the block is on an unwind path, do not + // apply the optimization as unwind paths + // rely on a unique parent invariant + if block.is_cleanup { + continue 'block_iter; + } + + // If the block has fewer than 2 predecessors, ignore it + // we could maybe chain blocks that have exactly one + // predecessor, but for now we ignore that + if predecessors[block_id].len() < 2 { + continue 'block_iter; + } + + // First, let's find a non-const place + // that determines the result of the switch + if let Some(switch_place) = find_determining_place(switch_place, block) { + // We now have an input place for which it would + // be interesting if predecessors assigned it from a const + + let mut predecessors_left = predecessors[block_id].len(); + 'predec_iter: for predecessor_id in predecessors[block_id].iter().copied() { + let predecessor = &body.basic_blocks[predecessor_id]; + + // First we make sure the predecessor jumps + // in a reasonable way + match &predecessor.terminator().kind { + // The following terminators are + // unconditionally valid + TerminatorKind::Goto { .. } | TerminatorKind::SwitchInt { .. } => {} + + TerminatorKind::FalseEdge { real_target, .. } => { + if *real_target != block_id { + continue 'predec_iter; + } + } + + // The following terminators are not allowed + TerminatorKind::UnwindResume + | TerminatorKind::Drop { .. } + | TerminatorKind::Call { .. } + | TerminatorKind::Assert { .. } + | TerminatorKind::FalseUnwind { .. } + | TerminatorKind::Yield { .. } + | TerminatorKind::UnwindTerminate(_) + | TerminatorKind::Return + | TerminatorKind::Unreachable + | TerminatorKind::InlineAsm { .. } + | TerminatorKind::CoroutineDrop => { + continue 'predec_iter; + } + } + + if is_likely_const(switch_place, predecessor) { + new_blocks.push((predecessor_id, block_id)); + predecessors_left -= 1; + if predecessors_left < 2 { + // If the original block only has one predecessor left, + // we have nothing left to do + break 'predec_iter; + } + } + } + } + } + } + + // Once the analysis is done, perform the duplication + let body_span = body.span; + let copied_blocks = new_blocks.len(); + let blocks = body.basic_blocks_mut(); + for (pred_id, target_id) in new_blocks { + let new_block = blocks[target_id].clone(); + let new_block_id = blocks.push(new_block); + let terminator = blocks[pred_id].terminator_mut(); + + match terminator.kind { + TerminatorKind::Goto { ref mut target } => { + *target = new_block_id; + } + + TerminatorKind::FalseEdge { ref mut real_target, .. } => { + if *real_target == target_id { + *real_target = new_block_id; + } + } + + TerminatorKind::SwitchInt { ref mut targets, .. } => { + targets.all_targets_mut().iter_mut().for_each(|x| { + if *x == target_id { + *x = new_block_id; + } + }); + } + + TerminatorKind::UnwindResume + | TerminatorKind::UnwindTerminate(_) + | TerminatorKind::Return + | TerminatorKind::Unreachable + | TerminatorKind::CoroutineDrop + | TerminatorKind::Assert { .. } + | TerminatorKind::FalseUnwind { .. } + | TerminatorKind::Drop { .. } + | TerminatorKind::Call { .. } + | TerminatorKind::InlineAsm { .. } + | TerminatorKind::Yield { .. } => { + span_bug!( + body_span, + "basic block terminator had unexpected kind {:?}", + &terminator.kind + ) + } + } + } + + copied_blocks +} + +/// This function describes a rough heuristic guessing +/// whether a place is last set with a const within the block. +/// Notably, it will be overly pessimistic in cases that are already +/// not handled by `separate_const_switch`. +fn is_likely_const<'tcx>(mut tracked_place: Place<'tcx>, block: &BasicBlockData<'tcx>) -> bool { + for statement in block.statements.iter().rev() { + match &statement.kind { + StatementKind::Assign(assign) => { + if assign.0 == tracked_place { + match assign.1 { + // These rvalues are definitely constant + Rvalue::Use(Operand::Constant(_)) + | Rvalue::Ref(_, _, _) + | Rvalue::AddressOf(_, _) + | Rvalue::Cast(_, Operand::Constant(_), _) + | Rvalue::NullaryOp(_, _) + | Rvalue::ShallowInitBox(_, _) + | Rvalue::UnaryOp(_, Operand::Constant(_)) => return true, + + // These rvalues make things ambiguous + Rvalue::Repeat(_, _) + | Rvalue::ThreadLocalRef(_) + | Rvalue::Len(_) + | Rvalue::BinaryOp(_, _) + | Rvalue::CheckedBinaryOp(_, _) + | Rvalue::Aggregate(_, _) => return false, + + // These rvalues move the place to track + Rvalue::Cast(_, Operand::Copy(place) | Operand::Move(place), _) + | Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) + | Rvalue::CopyForDeref(place) + | Rvalue::UnaryOp(_, Operand::Copy(place) | Operand::Move(place)) + | Rvalue::Discriminant(place) => tracked_place = place, + } + } + } + + // If the discriminant is set, it is always set + // as a constant, so the job is done. + // As we are **ignoring projections**, if the place + // we are tracking sees its discriminant be set, + // that means we had to be tracking the discriminant + // specifically (as it is impossible to switch over + // an enum directly, and if we were switching over + // its content, we would have had to at least cast it to + // some variant first) + StatementKind::SetDiscriminant { place, .. } => { + if **place == tracked_place { + return true; + } + } + + // These statements have no influence on the place + // we are interested in + StatementKind::FakeRead(_) + | StatementKind::Deinit(_) + | StatementKind::StorageLive(_) + | StatementKind::Retag(_, _) + | StatementKind::AscribeUserType(_, _) + | StatementKind::PlaceMention(..) + | StatementKind::Coverage(_) + | StatementKind::StorageDead(_) + | StatementKind::Intrinsic(_) + | StatementKind::ConstEvalCounter + | StatementKind::Nop => {} + } + } + + // If no good reason for the place to be const is found, + // give up. We could maybe go up predecessors, but in + // most cases giving up now should be sufficient. + false +} + +/// Finds a unique place that entirely determines the value +/// of `switch_place`, if it exists. This is only a heuristic. +/// Ideally we would like to track multiple determining places +/// for some edge cases, but one is enough for a lot of situations. +fn find_determining_place<'tcx>( + mut switch_place: Place<'tcx>, + block: &BasicBlockData<'tcx>, +) -> Option> { + for statement in block.statements.iter().rev() { + match &statement.kind { + StatementKind::Assign(op) => { + if op.0 != switch_place { + continue; + } + + match op.1 { + // The following rvalues move the place + // that may be const in the predecessor + Rvalue::Use(Operand::Move(new) | Operand::Copy(new)) + | Rvalue::UnaryOp(_, Operand::Copy(new) | Operand::Move(new)) + | Rvalue::CopyForDeref(new) + | Rvalue::Cast(_, Operand::Move(new) | Operand::Copy(new), _) + | Rvalue::Repeat(Operand::Move(new) | Operand::Copy(new), _) + | Rvalue::Discriminant(new) + => switch_place = new, + + // The following rvalues might still make the block + // be valid but for now we reject them + Rvalue::Len(_) + | Rvalue::Ref(_, _, _) + | Rvalue::BinaryOp(_, _) + | Rvalue::CheckedBinaryOp(_, _) + | Rvalue::Aggregate(_, _) + + // The following rvalues definitely mean we cannot + // or should not apply this optimization + | Rvalue::Use(Operand::Constant(_)) + | Rvalue::Repeat(Operand::Constant(_), _) + | Rvalue::ThreadLocalRef(_) + | Rvalue::AddressOf(_, _) + | Rvalue::NullaryOp(_, _) + | Rvalue::ShallowInitBox(_, _) + | Rvalue::UnaryOp(_, Operand::Constant(_)) + | Rvalue::Cast(_, Operand::Constant(_), _) => return None, + } + } + + // These statements have no influence on the place + // we are interested in + StatementKind::FakeRead(_) + | StatementKind::Deinit(_) + | StatementKind::StorageLive(_) + | StatementKind::StorageDead(_) + | StatementKind::Retag(_, _) + | StatementKind::AscribeUserType(_, _) + | StatementKind::PlaceMention(..) + | StatementKind::Coverage(_) + | StatementKind::Intrinsic(_) + | StatementKind::ConstEvalCounter + | StatementKind::Nop => {} + + // If the discriminant is set, it is always set + // as a constant, so the job is already done. + // As we are **ignoring projections**, if the place + // we are tracking sees its discriminant be set, + // that means we had to be tracking the discriminant + // specifically (as it is impossible to switch over + // an enum directly, and if we were switching over + // its content, we would have had to at least cast it to + // some variant first) + StatementKind::SetDiscriminant { place, .. } => { + if **place == switch_place { + return None; + } + } + } + } + + Some(switch_place) +} diff --git a/tests/coverage/closure.cov-map b/tests/coverage/closure.cov-map index 9f0d33745bcb5..921ca6cf4e1ad 100644 --- a/tests/coverage/closure.cov-map +++ b/tests/coverage/closure.cov-map @@ -33,16 +33,20 @@ Number of file 0 mappings: 24 - Code(Expression(1, Add)) at (prev + 1, 5) to (start + 3, 2) = (c1 + (c0 - c1)) -Function name: closure::main::{closure#0} (unused) -Raw bytes (24): 0x[01, 01, 00, 04, 00, 28, 05, 02, 14, 00, 02, 15, 02, 0a, 00, 02, 0a, 00, 0b, 00, 01, 09, 01, 06] +Function name: closure::main::{closure#0} +Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 28, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 0a, 00, 0b, 07, 01, 09, 01, 06] Number of files: 1 - file 0 => global file 1 -Number of expressions: 0 +Number of expressions: 2 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 4 -- Code(Zero) at (prev + 40, 5) to (start + 2, 20) -- Code(Zero) at (prev + 2, 21) to (start + 2, 10) -- Code(Zero) at (prev + 2, 10) to (start + 0, 11) -- Code(Zero) at (prev + 1, 9) to (start + 1, 6) +- Code(Counter(0)) at (prev + 40, 5) to (start + 2, 20) +- Code(Counter(1)) at (prev + 2, 21) to (start + 2, 10) +- Code(Expression(0, Sub)) at (prev + 2, 10) to (start + 0, 11) + = (c0 - c1) +- Code(Expression(1, Add)) at (prev + 1, 9) to (start + 1, 6) + = (c1 + (c0 - c1)) Function name: closure::main::{closure#10} (unused) Raw bytes (10): 0x[01, 01, 00, 01, 00, 9b, 01, 07, 00, 21] @@ -144,16 +148,20 @@ Number of file 0 mappings: 6 - Code(Expression(0, Add)) at (prev + 2, 9) to (start + 0, 10) = (c1 + (c0 - c1)) -Function name: closure::main::{closure#18} (unused) -Raw bytes (24): 0x[01, 01, 00, 04, 00, 19, 0d, 02, 1c, 00, 02, 1d, 02, 12, 00, 02, 12, 00, 13, 00, 01, 11, 01, 0e] +Function name: closure::main::{closure#18} +Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 19, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 12, 00, 13, 07, 01, 11, 01, 0e] Number of files: 1 - file 0 => global file 1 -Number of expressions: 0 +Number of expressions: 2 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 4 -- Code(Zero) at (prev + 25, 13) to (start + 2, 28) -- Code(Zero) at (prev + 2, 29) to (start + 2, 18) -- Code(Zero) at (prev + 2, 18) to (start + 0, 19) -- Code(Zero) at (prev + 1, 17) to (start + 1, 14) +- Code(Counter(0)) at (prev + 25, 13) to (start + 2, 28) +- Code(Counter(1)) at (prev + 2, 29) to (start + 2, 18) +- Code(Expression(0, Sub)) at (prev + 2, 18) to (start + 0, 19) + = (c0 - c1) +- Code(Expression(1, Add)) at (prev + 1, 17) to (start + 1, 14) + = (c1 + (c0 - c1)) Function name: closure::main::{closure#19} Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 43, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 12, 00, 13, 07, 01, 11, 01, 0e] diff --git a/tests/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map index a81884ea942d8..88436964af0f7 100644 --- a/tests/coverage/issue-84561.cov-map +++ b/tests/coverage/issue-84561.cov-map @@ -77,7 +77,7 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 167, 9) to (start + 2, 10) Function name: issue_84561::test3 -Raw bytes (436): 0x[01, 01, 41, 05, 09, 0d, 00, 15, 19, 12, 00, 15, 19, 21, 00, 1e, 00, 21, 00, 31, 00, 3d, 41, 2e, 45, 3d, 41, 42, 49, 45, 00, 3f, 51, 42, 49, 45, 00, 5d, 8a, 01, 8f, 01, 5d, 92, 01, 55, 51, 00, 92, 01, 55, 51, 00, 8f, 01, 5d, 92, 01, 55, 51, 00, 87, 01, 61, 5d, 8a, 01, 8f, 01, 5d, 92, 01, 55, 51, 00, 82, 01, 65, 87, 01, 61, 5d, 8a, 01, 8f, 01, 5d, 92, 01, 55, 51, 00, 75, f6, 01, fb, 01, 79, 00, fe, 01, 82, 02, 00, 69, 6d, 00, fe, 01, 82, 02, 00, 69, 6d, 69, 6d, 82, 02, 00, 69, 6d, fb, 01, 79, 00, fe, 01, 82, 02, 00, 69, 6d, f3, 01, 7d, 75, f6, 01, fb, 01, 79, 00, fe, 01, 82, 02, 00, 69, 6d, ee, 01, 00, f3, 01, 7d, 75, f6, 01, fb, 01, 79, 00, fe, 01, 82, 02, 00, 69, 6d, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 02, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 06, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 12, 02, 05, 00, 1f, 0e, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 00, 03, 20, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 1e, 01, 05, 00, 0f, 00, 05, 09, 03, 10, 00, 05, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 1a, 04, 09, 05, 06, 31, 06, 05, 03, 06, 22, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 2e, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 2a, 05, 09, 03, 0a, 3f, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 3a, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 87, 01, 03, 05, 00, 0f, 8f, 01, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 8a, 01, 02, 0d, 00, 13, 82, 01, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 7e, 02, 0d, 00, 13, f3, 01, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 75, 04, 0d, 00, 13, fb, 01, 02, 0d, 00, 17, 82, 02, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, fe, 01, 02, 15, 00, 1b, f6, 01, 04, 0d, 00, 13, 7d, 03, 09, 00, 19, ee, 01, 02, 05, 00, 0f, ea, 01, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] +Raw bytes (436): 0x[01, 01, 41, 05, 09, 0d, 00, 15, 19, 12, 00, 15, 19, 21, 00, 1e, 00, 21, 00, 31, 00, 3d, 41, 2e, 45, 3d, 41, 42, 49, 45, 00, 3f, 51, 42, 49, 45, 00, 5d, 8a, 01, 8f, 01, 5d, 92, 01, 55, 51, 00, 92, 01, 55, 51, 00, 8f, 01, 5d, 92, 01, 55, 51, 00, 87, 01, 61, 5d, 8a, 01, 8f, 01, 5d, 92, 01, 55, 51, 00, 82, 01, 65, 87, 01, 61, 5d, 8a, 01, 8f, 01, 5d, 92, 01, 55, 51, 00, 75, f6, 01, fb, 01, 79, 71, fe, 01, 82, 02, 71, 69, 6d, 71, fe, 01, 82, 02, 71, 69, 6d, 69, 6d, 82, 02, 71, 69, 6d, fb, 01, 79, 71, fe, 01, 82, 02, 71, 69, 6d, f3, 01, 7d, 75, f6, 01, fb, 01, 79, 71, fe, 01, 82, 02, 71, 69, 6d, ee, 01, 00, f3, 01, 7d, 75, f6, 01, fb, 01, 79, 71, fe, 01, 82, 02, 71, 69, 6d, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 02, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 06, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 12, 02, 05, 00, 1f, 0e, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 00, 03, 20, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 1e, 01, 05, 00, 0f, 00, 05, 09, 03, 10, 00, 05, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 1a, 04, 09, 05, 06, 31, 06, 05, 03, 06, 22, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 2e, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 2a, 05, 09, 03, 0a, 3f, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 3a, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 87, 01, 03, 05, 00, 0f, 8f, 01, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 8a, 01, 02, 0d, 00, 13, 82, 01, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 7e, 02, 0d, 00, 13, f3, 01, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 75, 04, 0d, 00, 13, fb, 01, 02, 0d, 00, 17, 82, 02, 01, 14, 00, 1b, 71, 01, 15, 00, 1b, fe, 01, 02, 15, 00, 1b, f6, 01, 04, 0d, 00, 13, 7d, 03, 09, 00, 19, ee, 01, 02, 05, 00, 0f, ea, 01, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 65 @@ -120,31 +120,31 @@ Number of expressions: 65 - expression 36 operands: lhs = Counter(20), rhs = Zero - expression 37 operands: lhs = Counter(29), rhs = Expression(61, Sub) - expression 38 operands: lhs = Expression(62, Add), rhs = Counter(30) -- expression 39 operands: lhs = Zero, rhs = Expression(63, Sub) -- expression 40 operands: lhs = Expression(64, Sub), rhs = Zero +- expression 39 operands: lhs = Counter(28), rhs = Expression(63, Sub) +- expression 40 operands: lhs = Expression(64, Sub), rhs = Counter(28) - expression 41 operands: lhs = Counter(26), rhs = Counter(27) -- expression 42 operands: lhs = Zero, rhs = Expression(63, Sub) -- expression 43 operands: lhs = Expression(64, Sub), rhs = Zero +- expression 42 operands: lhs = Counter(28), rhs = Expression(63, Sub) +- expression 43 operands: lhs = Expression(64, Sub), rhs = Counter(28) - expression 44 operands: lhs = Counter(26), rhs = Counter(27) - expression 45 operands: lhs = Counter(26), rhs = Counter(27) -- expression 46 operands: lhs = Expression(64, Sub), rhs = Zero +- expression 46 operands: lhs = Expression(64, Sub), rhs = Counter(28) - expression 47 operands: lhs = Counter(26), rhs = Counter(27) - expression 48 operands: lhs = Expression(62, Add), rhs = Counter(30) -- expression 49 operands: lhs = Zero, rhs = Expression(63, Sub) -- expression 50 operands: lhs = Expression(64, Sub), rhs = Zero +- expression 49 operands: lhs = Counter(28), rhs = Expression(63, Sub) +- expression 50 operands: lhs = Expression(64, Sub), rhs = Counter(28) - expression 51 operands: lhs = Counter(26), rhs = Counter(27) - expression 52 operands: lhs = Expression(60, Add), rhs = Counter(31) - expression 53 operands: lhs = Counter(29), rhs = Expression(61, Sub) - expression 54 operands: lhs = Expression(62, Add), rhs = Counter(30) -- expression 55 operands: lhs = Zero, rhs = Expression(63, Sub) -- expression 56 operands: lhs = Expression(64, Sub), rhs = Zero +- expression 55 operands: lhs = Counter(28), rhs = Expression(63, Sub) +- expression 56 operands: lhs = Expression(64, Sub), rhs = Counter(28) - expression 57 operands: lhs = Counter(26), rhs = Counter(27) - expression 58 operands: lhs = Expression(59, Sub), rhs = Zero - expression 59 operands: lhs = Expression(60, Add), rhs = Counter(31) - expression 60 operands: lhs = Counter(29), rhs = Expression(61, Sub) - expression 61 operands: lhs = Expression(62, Add), rhs = Counter(30) -- expression 62 operands: lhs = Zero, rhs = Expression(63, Sub) -- expression 63 operands: lhs = Expression(64, Sub), rhs = Zero +- expression 62 operands: lhs = Counter(28), rhs = Expression(63, Sub) +- expression 63 operands: lhs = Expression(64, Sub), rhs = Counter(28) - expression 64 operands: lhs = Counter(26), rhs = Counter(27) Number of file 0 mappings: 51 - Code(Counter(0)) at (prev + 8, 1) to (start + 3, 28) @@ -200,24 +200,24 @@ Number of file 0 mappings: 51 - Code(Expression(31, Sub)) at (prev + 2, 13) to (start + 0, 19) = (((c23 + (((c20 - Zero) + c21) - c23)) - c24) - c25) - Code(Expression(60, Add)) at (prev + 3, 5) to (start + 0, 15) - = (c29 + ((Zero + ((c26 - c27) - Zero)) - c30)) + = (c29 + ((c28 + ((c26 - c27) - c28)) - c30)) - Code(Counter(26)) at (prev + 1, 12) to (start + 0, 19) - Code(Counter(27)) at (prev + 1, 13) to (start + 3, 14) - Code(Counter(29)) at (prev + 4, 13) to (start + 0, 19) - Code(Expression(62, Add)) at (prev + 2, 13) to (start + 0, 23) - = (Zero + ((c26 - c27) - Zero)) + = (c28 + ((c26 - c27) - c28)) - Code(Expression(64, Sub)) at (prev + 1, 20) to (start + 0, 27) = (c26 - c27) -- Code(Zero) at (prev + 1, 21) to (start + 0, 27) +- Code(Counter(28)) at (prev + 1, 21) to (start + 0, 27) - Code(Expression(63, Sub)) at (prev + 2, 21) to (start + 0, 27) - = ((c26 - c27) - Zero) + = ((c26 - c27) - c28) - Code(Expression(61, Sub)) at (prev + 4, 13) to (start + 0, 19) - = ((Zero + ((c26 - c27) - Zero)) - c30) + = ((c28 + ((c26 - c27) - c28)) - c30) - Code(Counter(31)) at (prev + 3, 9) to (start + 0, 25) - Code(Expression(59, Sub)) at (prev + 2, 5) to (start + 0, 15) - = ((c29 + ((Zero + ((c26 - c27) - Zero)) - c30)) - c31) + = ((c29 + ((c28 + ((c26 - c27) - c28)) - c30)) - c31) - Code(Expression(58, Sub)) at (prev + 3, 9) to (start + 0, 34) - = (((c29 + ((Zero + ((c26 - c27) - Zero)) - c30)) - c31) - Zero) + = (((c29 + ((c28 + ((c26 - c27) - c28)) - c30)) - c31) - Zero) - Code(Zero) at (prev + 2, 5) to (start + 0, 15) - Code(Zero) at (prev + 3, 9) to (start + 0, 44) - Code(Zero) at (prev + 2, 1) to (start + 0, 2) diff --git a/tests/coverage/try_error_result.cov-map b/tests/coverage/try_error_result.cov-map index 83f1869a31e6c..5cfb40ce52894 100644 --- a/tests/coverage/try_error_result.cov-map +++ b/tests/coverage/try_error_result.cov-map @@ -59,131 +59,162 @@ Number of file 0 mappings: 4 = (c1 + (c0 - c1)) Function name: try_error_result::test1 -Raw bytes (75): 0x[01, 01, 08, 01, 07, 00, 09, 03, 0d, 12, 1d, 03, 0d, 1b, 0d, 1f, 00, 11, 00, 0b, 01, 0d, 01, 02, 17, 03, 07, 09, 00, 0e, 12, 02, 09, 04, 1a, 1d, 06, 0d, 00, 29, 11, 00, 29, 00, 2a, 00, 01, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 0e, 04, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 0d, 03, 05, 00, 0b, 17, 01, 01, 00, 02] +Raw bytes (77): 0x[01, 01, 09, 01, 07, 05, 09, 03, 0d, 1d, 11, 16, 1d, 03, 0d, 1f, 0d, 23, 19, 11, 15, 0b, 01, 0d, 01, 02, 17, 03, 07, 09, 00, 0e, 16, 02, 09, 04, 1a, 1d, 06, 0d, 00, 29, 11, 00, 29, 00, 2a, 0e, 01, 0d, 00, 2a, 15, 00, 2a, 00, 2b, 12, 04, 0d, 00, 2a, 19, 00, 2a, 00, 2b, 0d, 03, 05, 00, 0b, 1b, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 8 +Number of expressions: 9 - expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add) -- expression 1 operands: lhs = Zero, rhs = Counter(2) +- expression 1 operands: lhs = Counter(1), rhs = Counter(2) - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 3 operands: lhs = Expression(4, Sub), rhs = Counter(7) -- expression 4 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(3) -- expression 6 operands: lhs = Expression(7, Add), rhs = Zero -- expression 7 operands: lhs = Counter(4), rhs = Zero +- expression 3 operands: lhs = Counter(7), rhs = Counter(4) +- expression 4 operands: lhs = Expression(5, Sub), rhs = Counter(7) +- expression 5 operands: lhs = Expression(0, Add), rhs = Counter(3) +- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(3) +- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(6) +- expression 8 operands: lhs = Counter(4), rhs = Counter(5) Number of file 0 mappings: 11 - Code(Counter(0)) at (prev + 13, 1) to (start + 2, 23) - Code(Expression(0, Add)) at (prev + 7, 9) to (start + 0, 14) - = (c0 + (Zero + c2)) -- Code(Expression(4, Sub)) at (prev + 2, 9) to (start + 4, 26) - = ((c0 + (Zero + c2)) - c3) + = (c0 + (c1 + c2)) +- Code(Expression(5, Sub)) at (prev + 2, 9) to (start + 4, 26) + = ((c0 + (c1 + c2)) - c3) - Code(Counter(7)) at (prev + 6, 13) to (start + 0, 41) - Code(Counter(4)) at (prev + 0, 41) to (start + 0, 42) -- Code(Zero) at (prev + 1, 13) to (start + 0, 42) -- Code(Zero) at (prev + 0, 42) to (start + 0, 43) -- Code(Expression(3, Sub)) at (prev + 4, 13) to (start + 0, 42) - = (((c0 + (Zero + c2)) - c3) - c7) -- Code(Zero) at (prev + 0, 42) to (start + 0, 43) +- Code(Expression(3, Sub)) at (prev + 1, 13) to (start + 0, 42) + = (c7 - c4) +- Code(Counter(5)) at (prev + 0, 42) to (start + 0, 43) +- Code(Expression(4, Sub)) at (prev + 4, 13) to (start + 0, 42) + = (((c0 + (c1 + c2)) - c3) - c7) +- Code(Counter(6)) at (prev + 0, 42) to (start + 0, 43) - Code(Counter(3)) at (prev + 3, 5) to (start + 0, 11) -- Code(Expression(5, Add)) at (prev + 1, 1) to (start + 0, 2) - = (((c4 + Zero) + Zero) + c3) +- Code(Expression(6, Add)) at (prev + 1, 1) to (start + 0, 2) + = (((c4 + c5) + c6) + c3) Function name: try_error_result::test2 -Raw bytes (280): 0x[01, 01, 24, 01, 07, 00, 09, 03, 0d, 41, 00, 1e, 00, 41, 00, 1e, 00, 41, 00, 4a, 00, 4e, 00, 52, 41, 03, 0d, 52, 41, 03, 0d, 4e, 00, 52, 41, 03, 0d, 4a, 00, 4e, 00, 52, 41, 03, 0d, 66, 00, 45, 00, 45, 00, 66, 00, 45, 00, 7a, 00, 4d, 00, 4d, 00, 7a, 00, 4d, 00, 83, 01, 0d, 87, 01, 00, 00, 8b, 01, 8f, 01, 00, 19, 00, 28, 01, 3e, 01, 03, 17, 03, 08, 09, 00, 0e, 52, 02, 09, 04, 1a, 41, 06, 0d, 00, 2f, 00, 00, 2f, 00, 30, 1e, 00, 31, 03, 35, 00, 04, 11, 00, 12, 1a, 02, 11, 04, 12, 00, 05, 11, 00, 14, 1a, 00, 17, 00, 41, 19, 00, 41, 00, 42, 00, 00, 43, 00, 5f, 00, 00, 5f, 00, 60, 00, 01, 0d, 00, 20, 00, 01, 11, 00, 14, 00, 00, 17, 00, 41, 00, 00, 41, 00, 42, 00, 00, 43, 00, 60, 00, 00, 60, 00, 61, 00, 01, 0d, 00, 20, 46, 04, 11, 00, 14, 4e, 00, 17, 00, 42, 00, 00, 42, 00, 43, 4a, 00, 44, 00, 61, 00, 00, 61, 00, 62, 46, 01, 0d, 00, 20, 62, 01, 11, 00, 14, 45, 00, 17, 01, 36, 00, 01, 36, 00, 37, 66, 01, 12, 00, 2f, 00, 00, 2f, 00, 30, 62, 01, 0d, 00, 20, 76, 01, 11, 00, 14, 4d, 00, 17, 01, 36, 00, 02, 11, 00, 12, 7a, 01, 12, 00, 2f, 00, 01, 11, 00, 12, 76, 02, 0d, 00, 20, 0d, 03, 05, 00, 0b, 7f, 01, 01, 00, 02] +Raw bytes (358): 0x[01, 01, 3b, 01, 07, 05, 09, 03, 0d, 41, 11, 4a, 15, 41, 11, 42, 1d, 46, 19, 4a, 15, 41, 11, 4a, 15, 41, 11, 46, 19, 4a, 15, 41, 11, 42, 1d, 46, 19, 4a, 15, 41, 11, 5e, 25, 49, 21, 49, 21, 5e, 25, 49, 21, 8a, 01, 2d, 8e, 01, 29, 92, 01, 41, 03, 0d, 92, 01, 41, 03, 0d, 8e, 01, 29, 92, 01, 41, 03, 0d, 8a, 01, 2d, 8e, 01, 29, 92, 01, 41, 03, 0d, a6, 01, 35, 45, 31, 45, 31, a6, 01, 35, 45, 31, ba, 01, 3d, 4d, 39, 4d, 39, ba, 01, 3d, 4d, 39, c3, 01, 0d, c7, 01, db, 01, cb, 01, cf, 01, 11, 15, d3, 01, d7, 01, 19, 1d, 21, 25, df, 01, e3, 01, 29, 2d, e7, 01, eb, 01, 31, 35, 39, 3d, 28, 01, 3e, 01, 03, 17, 03, 08, 09, 00, 0e, 92, 01, 02, 09, 04, 1a, 41, 06, 0d, 00, 2f, 11, 00, 2f, 00, 30, 4a, 00, 31, 03, 35, 15, 04, 11, 00, 12, 46, 02, 11, 04, 12, 3e, 05, 11, 00, 14, 46, 00, 17, 00, 41, 19, 00, 41, 00, 42, 42, 00, 43, 00, 5f, 1d, 00, 5f, 00, 60, 3e, 01, 0d, 00, 20, 5a, 01, 11, 00, 14, 49, 00, 17, 00, 41, 21, 00, 41, 00, 42, 5e, 00, 43, 00, 60, 25, 00, 60, 00, 61, 5a, 01, 0d, 00, 20, 86, 01, 04, 11, 00, 14, 8e, 01, 00, 17, 00, 42, 29, 00, 42, 00, 43, 8a, 01, 00, 44, 00, 61, 2d, 00, 61, 00, 62, 86, 01, 01, 0d, 00, 20, a2, 01, 01, 11, 00, 14, 45, 00, 17, 01, 36, 31, 01, 36, 00, 37, a6, 01, 01, 12, 00, 2f, 35, 00, 2f, 00, 30, a2, 01, 01, 0d, 00, 20, b6, 01, 01, 11, 00, 14, 4d, 00, 17, 01, 36, 39, 02, 11, 00, 12, ba, 01, 01, 12, 00, 2f, 3d, 01, 11, 00, 12, b6, 01, 02, 0d, 00, 20, 0d, 03, 05, 00, 0b, bf, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 -Number of expressions: 36 +Number of expressions: 59 - expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add) -- expression 1 operands: lhs = Zero, rhs = Counter(2) +- expression 1 operands: lhs = Counter(1), rhs = Counter(2) - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 3 operands: lhs = Counter(16), rhs = Zero -- expression 4 operands: lhs = Expression(7, Sub), rhs = Zero -- expression 5 operands: lhs = Counter(16), rhs = Zero -- expression 6 operands: lhs = Expression(7, Sub), rhs = Zero -- expression 7 operands: lhs = Counter(16), rhs = Zero -- expression 8 operands: lhs = Expression(18, Sub), rhs = Zero -- expression 9 operands: lhs = Expression(19, Sub), rhs = Zero -- expression 10 operands: lhs = Expression(20, Sub), rhs = Counter(16) -- expression 11 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 12 operands: lhs = Expression(20, Sub), rhs = Counter(16) -- expression 13 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 14 operands: lhs = Expression(19, Sub), rhs = Zero -- expression 15 operands: lhs = Expression(20, Sub), rhs = Counter(16) -- expression 16 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 17 operands: lhs = Expression(18, Sub), rhs = Zero -- expression 18 operands: lhs = Expression(19, Sub), rhs = Zero -- expression 19 operands: lhs = Expression(20, Sub), rhs = Counter(16) -- expression 20 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 21 operands: lhs = Expression(25, Sub), rhs = Zero -- expression 22 operands: lhs = Counter(17), rhs = Zero -- expression 23 operands: lhs = Counter(17), rhs = Zero -- expression 24 operands: lhs = Expression(25, Sub), rhs = Zero -- expression 25 operands: lhs = Counter(17), rhs = Zero -- expression 26 operands: lhs = Expression(30, Sub), rhs = Zero -- expression 27 operands: lhs = Counter(19), rhs = Zero -- expression 28 operands: lhs = Counter(19), rhs = Zero -- expression 29 operands: lhs = Expression(30, Sub), rhs = Zero -- expression 30 operands: lhs = Counter(19), rhs = Zero -- expression 31 operands: lhs = Expression(32, Add), rhs = Counter(3) -- expression 32 operands: lhs = Expression(33, Add), rhs = Zero -- expression 33 operands: lhs = Zero, rhs = Expression(34, Add) -- expression 34 operands: lhs = Expression(35, Add), rhs = Zero -- expression 35 operands: lhs = Counter(6), rhs = Zero +- expression 3 operands: lhs = Counter(16), rhs = Counter(4) +- expression 4 operands: lhs = Expression(18, Sub), rhs = Counter(5) +- expression 5 operands: lhs = Counter(16), rhs = Counter(4) +- expression 6 operands: lhs = Expression(16, Sub), rhs = Counter(7) +- expression 7 operands: lhs = Expression(17, Sub), rhs = Counter(6) +- expression 8 operands: lhs = Expression(18, Sub), rhs = Counter(5) +- expression 9 operands: lhs = Counter(16), rhs = Counter(4) +- expression 10 operands: lhs = Expression(18, Sub), rhs = Counter(5) +- expression 11 operands: lhs = Counter(16), rhs = Counter(4) +- expression 12 operands: lhs = Expression(17, Sub), rhs = Counter(6) +- expression 13 operands: lhs = Expression(18, Sub), rhs = Counter(5) +- expression 14 operands: lhs = Counter(16), rhs = Counter(4) +- expression 15 operands: lhs = Expression(16, Sub), rhs = Counter(7) +- expression 16 operands: lhs = Expression(17, Sub), rhs = Counter(6) +- expression 17 operands: lhs = Expression(18, Sub), rhs = Counter(5) +- expression 18 operands: lhs = Counter(16), rhs = Counter(4) +- expression 19 operands: lhs = Expression(23, Sub), rhs = Counter(9) +- expression 20 operands: lhs = Counter(18), rhs = Counter(8) +- expression 21 operands: lhs = Counter(18), rhs = Counter(8) +- expression 22 operands: lhs = Expression(23, Sub), rhs = Counter(9) +- expression 23 operands: lhs = Counter(18), rhs = Counter(8) +- expression 24 operands: lhs = Expression(34, Sub), rhs = Counter(11) +- expression 25 operands: lhs = Expression(35, Sub), rhs = Counter(10) +- expression 26 operands: lhs = Expression(36, Sub), rhs = Counter(16) +- expression 27 operands: lhs = Expression(0, Add), rhs = Counter(3) +- expression 28 operands: lhs = Expression(36, Sub), rhs = Counter(16) +- expression 29 operands: lhs = Expression(0, Add), rhs = Counter(3) +- expression 30 operands: lhs = Expression(35, Sub), rhs = Counter(10) +- expression 31 operands: lhs = Expression(36, Sub), rhs = Counter(16) +- expression 32 operands: lhs = Expression(0, Add), rhs = Counter(3) +- expression 33 operands: lhs = Expression(34, Sub), rhs = Counter(11) +- expression 34 operands: lhs = Expression(35, Sub), rhs = Counter(10) +- expression 35 operands: lhs = Expression(36, Sub), rhs = Counter(16) +- expression 36 operands: lhs = Expression(0, Add), rhs = Counter(3) +- expression 37 operands: lhs = Expression(41, Sub), rhs = Counter(13) +- expression 38 operands: lhs = Counter(17), rhs = Counter(12) +- expression 39 operands: lhs = Counter(17), rhs = Counter(12) +- expression 40 operands: lhs = Expression(41, Sub), rhs = Counter(13) +- expression 41 operands: lhs = Counter(17), rhs = Counter(12) +- expression 42 operands: lhs = Expression(46, Sub), rhs = Counter(15) +- expression 43 operands: lhs = Counter(19), rhs = Counter(14) +- expression 44 operands: lhs = Counter(19), rhs = Counter(14) +- expression 45 operands: lhs = Expression(46, Sub), rhs = Counter(15) +- expression 46 operands: lhs = Counter(19), rhs = Counter(14) +- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(3) +- expression 48 operands: lhs = Expression(49, Add), rhs = Expression(54, Add) +- expression 49 operands: lhs = Expression(50, Add), rhs = Expression(51, Add) +- expression 50 operands: lhs = Counter(4), rhs = Counter(5) +- expression 51 operands: lhs = Expression(52, Add), rhs = Expression(53, Add) +- expression 52 operands: lhs = Counter(6), rhs = Counter(7) +- expression 53 operands: lhs = Counter(8), rhs = Counter(9) +- expression 54 operands: lhs = Expression(55, Add), rhs = Expression(56, Add) +- expression 55 operands: lhs = Counter(10), rhs = Counter(11) +- expression 56 operands: lhs = Expression(57, Add), rhs = Expression(58, Add) +- expression 57 operands: lhs = Counter(12), rhs = Counter(13) +- expression 58 operands: lhs = Counter(14), rhs = Counter(15) Number of file 0 mappings: 40 - Code(Counter(0)) at (prev + 62, 1) to (start + 3, 23) - Code(Expression(0, Add)) at (prev + 8, 9) to (start + 0, 14) - = (c0 + (Zero + c2)) -- Code(Expression(20, Sub)) at (prev + 2, 9) to (start + 4, 26) - = ((c0 + (Zero + c2)) - c3) + = (c0 + (c1 + c2)) +- Code(Expression(36, Sub)) at (prev + 2, 9) to (start + 4, 26) + = ((c0 + (c1 + c2)) - c3) - Code(Counter(16)) at (prev + 6, 13) to (start + 0, 47) -- Code(Zero) at (prev + 0, 47) to (start + 0, 48) -- Code(Expression(7, Sub)) at (prev + 0, 49) to (start + 3, 53) - = (c16 - Zero) -- Code(Zero) at (prev + 4, 17) to (start + 0, 18) -- Code(Expression(6, Sub)) at (prev + 2, 17) to (start + 4, 18) - = ((c16 - Zero) - Zero) -- Code(Zero) at (prev + 5, 17) to (start + 0, 20) -- Code(Expression(6, Sub)) at (prev + 0, 23) to (start + 0, 65) - = ((c16 - Zero) - Zero) +- Code(Counter(4)) at (prev + 0, 47) to (start + 0, 48) +- Code(Expression(18, Sub)) at (prev + 0, 49) to (start + 3, 53) + = (c16 - c4) +- Code(Counter(5)) at (prev + 4, 17) to (start + 0, 18) +- Code(Expression(17, Sub)) at (prev + 2, 17) to (start + 4, 18) + = ((c16 - c4) - c5) +- Code(Expression(15, Sub)) at (prev + 5, 17) to (start + 0, 20) + = ((((c16 - c4) - c5) - c6) - c7) +- Code(Expression(17, Sub)) at (prev + 0, 23) to (start + 0, 65) + = ((c16 - c4) - c5) - Code(Counter(6)) at (prev + 0, 65) to (start + 0, 66) -- Code(Zero) at (prev + 0, 67) to (start + 0, 95) -- Code(Zero) at (prev + 0, 95) to (start + 0, 96) -- Code(Zero) at (prev + 1, 13) to (start + 0, 32) -- Code(Zero) at (prev + 1, 17) to (start + 0, 20) -- Code(Zero) at (prev + 0, 23) to (start + 0, 65) -- Code(Zero) at (prev + 0, 65) to (start + 0, 66) -- Code(Zero) at (prev + 0, 67) to (start + 0, 96) -- Code(Zero) at (prev + 0, 96) to (start + 0, 97) -- Code(Zero) at (prev + 1, 13) to (start + 0, 32) -- Code(Expression(17, Sub)) at (prev + 4, 17) to (start + 0, 20) - = (((((c0 + (Zero + c2)) - c3) - c16) - Zero) - Zero) -- Code(Expression(19, Sub)) at (prev + 0, 23) to (start + 0, 66) - = (((c0 + (Zero + c2)) - c3) - c16) -- Code(Zero) at (prev + 0, 66) to (start + 0, 67) -- Code(Expression(18, Sub)) at (prev + 0, 68) to (start + 0, 97) - = ((((c0 + (Zero + c2)) - c3) - c16) - Zero) -- Code(Zero) at (prev + 0, 97) to (start + 0, 98) -- Code(Expression(17, Sub)) at (prev + 1, 13) to (start + 0, 32) - = (((((c0 + (Zero + c2)) - c3) - c16) - Zero) - Zero) -- Code(Expression(24, Sub)) at (prev + 1, 17) to (start + 0, 20) - = ((c17 - Zero) - Zero) +- Code(Expression(16, Sub)) at (prev + 0, 67) to (start + 0, 95) + = (((c16 - c4) - c5) - c6) +- Code(Counter(7)) at (prev + 0, 95) to (start + 0, 96) +- Code(Expression(15, Sub)) at (prev + 1, 13) to (start + 0, 32) + = ((((c16 - c4) - c5) - c6) - c7) +- Code(Expression(22, Sub)) at (prev + 1, 17) to (start + 0, 20) + = ((c18 - c8) - c9) +- Code(Counter(18)) at (prev + 0, 23) to (start + 0, 65) +- Code(Counter(8)) at (prev + 0, 65) to (start + 0, 66) +- Code(Expression(23, Sub)) at (prev + 0, 67) to (start + 0, 96) + = (c18 - c8) +- Code(Counter(9)) at (prev + 0, 96) to (start + 0, 97) +- Code(Expression(22, Sub)) at (prev + 1, 13) to (start + 0, 32) + = ((c18 - c8) - c9) +- Code(Expression(33, Sub)) at (prev + 4, 17) to (start + 0, 20) + = (((((c0 + (c1 + c2)) - c3) - c16) - c10) - c11) +- Code(Expression(35, Sub)) at (prev + 0, 23) to (start + 0, 66) + = (((c0 + (c1 + c2)) - c3) - c16) +- Code(Counter(10)) at (prev + 0, 66) to (start + 0, 67) +- Code(Expression(34, Sub)) at (prev + 0, 68) to (start + 0, 97) + = ((((c0 + (c1 + c2)) - c3) - c16) - c10) +- Code(Counter(11)) at (prev + 0, 97) to (start + 0, 98) +- Code(Expression(33, Sub)) at (prev + 1, 13) to (start + 0, 32) + = (((((c0 + (c1 + c2)) - c3) - c16) - c10) - c11) +- Code(Expression(40, Sub)) at (prev + 1, 17) to (start + 0, 20) + = ((c17 - c12) - c13) - Code(Counter(17)) at (prev + 0, 23) to (start + 1, 54) -- Code(Zero) at (prev + 1, 54) to (start + 0, 55) -- Code(Expression(25, Sub)) at (prev + 1, 18) to (start + 0, 47) - = (c17 - Zero) -- Code(Zero) at (prev + 0, 47) to (start + 0, 48) -- Code(Expression(24, Sub)) at (prev + 1, 13) to (start + 0, 32) - = ((c17 - Zero) - Zero) -- Code(Expression(29, Sub)) at (prev + 1, 17) to (start + 0, 20) - = ((c19 - Zero) - Zero) +- Code(Counter(12)) at (prev + 1, 54) to (start + 0, 55) +- Code(Expression(41, Sub)) at (prev + 1, 18) to (start + 0, 47) + = (c17 - c12) +- Code(Counter(13)) at (prev + 0, 47) to (start + 0, 48) +- Code(Expression(40, Sub)) at (prev + 1, 13) to (start + 0, 32) + = ((c17 - c12) - c13) +- Code(Expression(45, Sub)) at (prev + 1, 17) to (start + 0, 20) + = ((c19 - c14) - c15) - Code(Counter(19)) at (prev + 0, 23) to (start + 1, 54) -- Code(Zero) at (prev + 2, 17) to (start + 0, 18) -- Code(Expression(30, Sub)) at (prev + 1, 18) to (start + 0, 47) - = (c19 - Zero) -- Code(Zero) at (prev + 1, 17) to (start + 0, 18) -- Code(Expression(29, Sub)) at (prev + 2, 13) to (start + 0, 32) - = ((c19 - Zero) - Zero) +- Code(Counter(14)) at (prev + 2, 17) to (start + 0, 18) +- Code(Expression(46, Sub)) at (prev + 1, 18) to (start + 0, 47) + = (c19 - c14) +- Code(Counter(15)) at (prev + 1, 17) to (start + 0, 18) +- Code(Expression(45, Sub)) at (prev + 2, 13) to (start + 0, 32) + = ((c19 - c14) - c15) - Code(Counter(3)) at (prev + 3, 5) to (start + 0, 11) -- Code(Expression(31, Add)) at (prev + 1, 1) to (start + 0, 2) - = (((Zero + ((c6 + Zero) + Zero)) + Zero) + c3) +- Code(Expression(47, Add)) at (prev + 1, 1) to (start + 0, 2) + = ((((c4 + c5) + ((c6 + c7) + (c8 + c9))) + ((c10 + c11) + ((c12 + c13) + (c14 + c15)))) + c3) diff --git a/tests/coverage/yield.cov-map b/tests/coverage/yield.cov-map index 9cc67dfe88ac4..c9c9709fa4f30 100644 --- a/tests/coverage/yield.cov-map +++ b/tests/coverage/yield.cov-map @@ -1,9 +1,9 @@ Function name: yield::main -Raw bytes (106): 0x[01, 01, 0b, 05, 00, 0d, 11, 22, 15, 0d, 11, 11, 15, 22, 15, 0d, 11, 22, 15, 0d, 11, 19, 1d, 25, 29, 10, 01, 07, 01, 01, 16, 01, 06, 0b, 00, 2e, 0d, 01, 27, 00, 29, 03, 01, 0e, 00, 34, 0d, 02, 0b, 00, 2e, 22, 01, 22, 00, 27, 1e, 00, 2c, 00, 2e, 13, 01, 0e, 00, 34, 1e, 03, 09, 00, 16, 1e, 07, 0b, 00, 2e, 21, 01, 27, 00, 29, 27, 01, 0e, 00, 34, 21, 02, 0b, 00, 2e, 2d, 01, 27, 00, 29, 2b, 01, 0e, 00, 34, 2d, 02, 01, 00, 02] +Raw bytes (106): 0x[01, 01, 0b, 05, 09, 0d, 11, 22, 15, 0d, 11, 11, 15, 22, 15, 0d, 11, 22, 15, 0d, 11, 19, 1d, 25, 29, 10, 01, 07, 01, 01, 16, 01, 06, 0b, 00, 2e, 0d, 01, 27, 00, 29, 03, 01, 0e, 00, 34, 0d, 02, 0b, 00, 2e, 22, 01, 22, 00, 27, 1e, 00, 2c, 00, 2e, 13, 01, 0e, 00, 34, 1e, 03, 09, 00, 16, 1e, 07, 0b, 00, 2e, 21, 01, 27, 00, 29, 27, 01, 0e, 00, 34, 21, 02, 0b, 00, 2e, 2d, 01, 27, 00, 29, 2b, 01, 0e, 00, 34, 2d, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 11 -- expression 0 operands: lhs = Counter(1), rhs = Zero +- expression 0 operands: lhs = Counter(1), rhs = Counter(2) - expression 1 operands: lhs = Counter(3), rhs = Counter(4) - expression 2 operands: lhs = Expression(8, Sub), rhs = Counter(5) - expression 3 operands: lhs = Counter(3), rhs = Counter(4) @@ -19,7 +19,7 @@ Number of file 0 mappings: 16 - Code(Counter(0)) at (prev + 6, 11) to (start + 0, 46) - Code(Counter(3)) at (prev + 1, 39) to (start + 0, 41) - Code(Expression(0, Add)) at (prev + 1, 14) to (start + 0, 52) - = (c1 + Zero) + = (c1 + c2) - Code(Counter(3)) at (prev + 2, 11) to (start + 0, 46) - Code(Expression(8, Sub)) at (prev + 1, 34) to (start + 0, 39) = (c3 - c4) diff --git a/tests/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff b/tests/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff new file mode 100644 index 0000000000000..43bdb431129e6 --- /dev/null +++ b/tests/mir-opt/const_goto.issue_77355_opt.ConstGoto.diff @@ -0,0 +1,50 @@ +- // MIR for `issue_77355_opt` before ConstGoto ++ // MIR for `issue_77355_opt` after ConstGoto + + fn issue_77355_opt(_1: Foo) -> u64 { + debug num => _1; + let mut _0: u64; +- let mut _2: bool; +- let mut _3: isize; ++ let mut _2: isize; + + bb0: { +- StorageLive(_2); +- _3 = discriminant(_1); +- switchInt(move _3) -> [1: bb2, 2: bb2, otherwise: bb1]; ++ _2 = discriminant(_1); ++ switchInt(move _2) -> [1: bb2, 2: bb2, otherwise: bb1]; + } + + bb1: { +- _2 = const false; ++ _0 = const 42_u64; + goto -> bb3; + } + + bb2: { +- _2 = const true; ++ _0 = const 23_u64; + goto -> bb3; + } + + bb3: { +- switchInt(move _2) -> [0: bb5, otherwise: bb4]; +- } +- +- bb4: { +- _0 = const 23_u64; +- goto -> bb6; +- } +- +- bb5: { +- _0 = const 42_u64; +- goto -> bb6; +- } +- +- bb6: { +- StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/const_goto.rs b/tests/mir-opt/const_goto.rs new file mode 100644 index 0000000000000..93cb71c3a0f82 --- /dev/null +++ b/tests/mir-opt/const_goto.rs @@ -0,0 +1,19 @@ +// skip-filecheck +// unit-test: ConstGoto + +pub enum Foo { + A, + B, + C, + D, + E, + F, +} + +// EMIT_MIR const_goto.issue_77355_opt.ConstGoto.diff +fn issue_77355_opt(num: Foo) -> u64 { + if matches!(num, Foo::B | Foo::C) { 23 } else { 42 } +} +fn main() { + issue_77355_opt(Foo::A); +} diff --git a/tests/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff b/tests/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff new file mode 100644 index 0000000000000..84a13f28a313d --- /dev/null +++ b/tests/mir-opt/const_goto_const_eval_fail.f.ConstGoto.diff @@ -0,0 +1,51 @@ +- // MIR for `f` before ConstGoto ++ // MIR for `f` after ConstGoto + + fn f() -> u64 { + let mut _0: u64; + let mut _1: bool; + let mut _2: i32; + + bb0: { + StorageLive(_1); + StorageLive(_2); + _2 = const A; + switchInt(_2) -> [1: bb2, 2: bb2, 3: bb2, otherwise: bb1]; + } + + bb1: { + _1 = const true; + goto -> bb3; + } + + bb2: { + _1 = const B; +- goto -> bb3; ++ switchInt(_1) -> [0: bb4, otherwise: bb3]; + } + + bb3: { +- switchInt(_1) -> [0: bb5, otherwise: bb4]; +- } +- +- bb4: { + _0 = const 2_u64; +- goto -> bb6; ++ goto -> bb5; + } + +- bb5: { ++ bb4: { + _0 = const 1_u64; +- goto -> bb6; ++ goto -> bb5; + } + +- bb6: { ++ bb5: { + StorageDead(_2); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/const_goto_const_eval_fail.f.JumpThreading.diff b/tests/mir-opt/const_goto_const_eval_fail.f.JumpThreading.diff deleted file mode 100644 index 4fc9254b7baed..0000000000000 --- a/tests/mir-opt/const_goto_const_eval_fail.f.JumpThreading.diff +++ /dev/null @@ -1,47 +0,0 @@ -- // MIR for `f` before JumpThreading -+ // MIR for `f` after JumpThreading - - fn f() -> u64 { - let mut _0: u64; - let mut _1: bool; - - bb0: { - StorageLive(_1); - switchInt(const A) -> [1: bb2, 2: bb2, 3: bb2, otherwise: bb1]; - } - - bb1: { - _1 = const true; -- goto -> bb3; -+ goto -> bb7; - } - - bb2: { - _1 = const B; - goto -> bb3; - } - - bb3: { - switchInt(_1) -> [0: bb5, otherwise: bb4]; - } - - bb4: { - _0 = const 2_u64; - goto -> bb6; - } - - bb5: { - _0 = const 1_u64; - goto -> bb6; - } - - bb6: { - StorageDead(_1); - return; -+ } -+ -+ bb7: { -+ goto -> bb4; - } - } - diff --git a/tests/mir-opt/const_goto_const_eval_fail.rs b/tests/mir-opt/const_goto_const_eval_fail.rs index c0e8e144b1529..869f916001cd3 100644 --- a/tests/mir-opt/const_goto_const_eval_fail.rs +++ b/tests/mir-opt/const_goto_const_eval_fail.rs @@ -5,7 +5,7 @@ // compile-flags: -Zunsound-mir-opts // If const eval fails, then don't crash -// EMIT_MIR const_goto_const_eval_fail.f.JumpThreading.diff +// EMIT_MIR const_goto_const_eval_fail.f.ConstGoto.diff pub fn f() -> u64 { match { match A { diff --git a/tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff b/tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff new file mode 100644 index 0000000000000..1768298d52181 --- /dev/null +++ b/tests/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff @@ -0,0 +1,102 @@ +- // MIR for `match_nested_if` before ConstGoto ++ // MIR for `match_nested_if` after ConstGoto + + fn match_nested_if() -> bool { + let mut _0: bool; + let _1: bool; +- let mut _2: (); +- let mut _3: bool; +- let mut _4: bool; +- let mut _5: bool; +- let mut _6: bool; ++ let mut _2: bool; + scope 1 { + debug val => _1; + } + + bb0: { + StorageLive(_1); + StorageLive(_2); +- _2 = (); +- StorageLive(_3); +- StorageLive(_4); +- StorageLive(_5); +- StorageLive(_6); +- _6 = const true; +- switchInt(move _6) -> [0: bb2, otherwise: bb1]; ++ _2 = const true; ++ switchInt(move _2) -> [0: bb2, otherwise: bb1]; + } + + bb1: { +- _5 = const true; ++ StorageDead(_2); ++ _1 = const true; + goto -> bb3; + } + + bb2: { +- _5 = const false; ++ StorageDead(_2); ++ _1 = const false; + goto -> bb3; + } + + bb3: { +- switchInt(move _5) -> [0: bb5, otherwise: bb4]; +- } +- +- bb4: { +- StorageDead(_6); +- _4 = const true; +- goto -> bb6; +- } +- +- bb5: { +- StorageDead(_6); +- _4 = const false; +- goto -> bb6; +- } +- +- bb6: { +- switchInt(move _4) -> [0: bb8, otherwise: bb7]; +- } +- +- bb7: { +- StorageDead(_5); +- _3 = const true; +- goto -> bb9; +- } +- +- bb8: { +- StorageDead(_5); +- _3 = const false; +- goto -> bb9; +- } +- +- bb9: { +- switchInt(move _3) -> [0: bb11, otherwise: bb10]; +- } +- +- bb10: { +- StorageDead(_4); +- StorageDead(_3); +- _1 = const true; +- goto -> bb12; +- } +- +- bb11: { +- StorageDead(_4); +- StorageDead(_3); +- _1 = const false; +- goto -> bb12; +- } +- +- bb12: { +- StorageDead(_2); + _0 = _1; + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/const_goto_storage.rs b/tests/mir-opt/const_goto_storage.rs new file mode 100644 index 0000000000000..9d43da23990bc --- /dev/null +++ b/tests/mir-opt/const_goto_storage.rs @@ -0,0 +1,22 @@ +// skip-filecheck +// unit-test: ConstGoto + +// EMIT_MIR const_goto_storage.match_nested_if.ConstGoto.diff +fn match_nested_if() -> bool { + let val = match () { + () if if if if true { true } else { false } { true } else { false } { + true + } else { + false + } => + { + true + } + _ => false, + }; + val +} + +fn main() { + let _ = match_nested_if(); +} diff --git a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir index f1d0da28b4ef1..cf7feef00514a 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir @@ -4,12 +4,66 @@ fn step_forward(_1: u32, _2: usize) -> u32 { debug x => _1; debug n => _2; let mut _0: u32; + scope 1 (inlined ::forward) { + debug start => _1; + debug n => _2; + let _3: std::option::Option; + let mut _4: &std::option::Option; + let mut _7: bool; + let mut _8: u32; + scope 2 { + } + scope 3 (inlined Option::::is_none) { + debug self => _4; + let mut _6: bool; + scope 4 (inlined Option::::is_some) { + debug self => _4; + let mut _5: isize; + } + } + scope 5 (inlined core::num::::wrapping_add) { + debug self => _1; + debug rhs => _8; + } + } bb0: { - _0 = ::forward(move _1, move _2) -> [return: bb1, unwind continue]; + StorageLive(_7); + StorageLive(_4); + StorageLive(_3); + _3 = ::forward_checked(_1, _2) -> [return: bb1, unwind continue]; } bb1: { + _4 = &_3; + StorageLive(_6); + StorageLive(_5); + _5 = discriminant(_3); + _6 = Eq(_5, const 1_isize); + StorageDead(_5); + _7 = Not(move _6); + StorageDead(_6); + switchInt(move _7) -> [0: bb2, otherwise: bb3]; + } + + bb2: { + StorageDead(_3); + StorageDead(_4); + goto -> bb4; + } + + bb3: { + StorageDead(_3); + StorageDead(_4); + assert(!const true, "attempt to compute `{} + {}`, which would overflow", const _, const 1_u32) -> [success: bb4, unwind continue]; + } + + bb4: { + StorageDead(_7); + StorageLive(_8); + _8 = _2 as u32 (IntToInt); + _0 = Add(_1, _8); + StorageDead(_8); return; } } 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 0b5ed6ee169eb..e27e417ed4ae6 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 @@ -7,13 +7,14 @@ fn int_range(_1: usize, _2: usize) -> () { 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 _11: std::option::Option; + let mut _14: isize; + let _16: (); scope 1 { debug iter => _4; - let _14: usize; + let _15: usize; scope 2 { - debug i => _14; + debug i => _15; } scope 4 (inlined iter::range::>::next) { debug self => _5; @@ -22,10 +23,10 @@ fn int_range(_1: usize, _2: usize) -> () { let mut _6: &usize; let mut _7: &usize; let mut _10: bool; - let _11: usize; - let mut _12: usize; + let _12: usize; + let mut _13: usize; scope 6 { - debug old => _11; + debug old => _12; scope 7 { } } @@ -50,9 +51,9 @@ fn int_range(_1: usize, _2: usize) -> () { } bb1: { - StorageLive(_13); - _5 = &mut _4; StorageLive(_11); + _5 = &mut _4; + StorageLive(_12); StorageLive(_10); StorageLive(_6); _6 = &(_4.0: usize); @@ -71,33 +72,53 @@ fn int_range(_1: usize, _2: usize) -> () { bb2: { StorageDead(_7); StorageDead(_6); - StorageDead(_10); - StorageDead(_11); - StorageDead(_13); - StorageDead(_4); - return; + _11 = const Option::::None; + goto -> bb5; } bb3: { StorageDead(_7); StorageDead(_6); - _11 = (_4.0: usize); - StorageLive(_12); - _12 = ::forward_unchecked(_11, const 1_usize) -> [return: bb4, unwind continue]; + _12 = (_4.0: usize); + StorageLive(_13); + _13 = ::forward_unchecked(_12, const 1_usize) -> [return: bb4, unwind continue]; } bb4: { - (_4.0: usize) = move _12; - StorageDead(_12); - _13 = Option::::Some(_11); + (_4.0: usize) = move _13; + StorageDead(_13); + _11 = Option::::Some(_12); + goto -> bb5; + } + + bb5: { StorageDead(_10); + StorageDead(_12); + _14 = discriminant(_11); + switchInt(move _14) -> [0: bb6, 1: bb7, otherwise: bb9]; + } + + bb6: { StorageDead(_11); - _14 = ((_13 as Some).0: usize); - _15 = opaque::(move _14) -> [return: bb5, unwind continue]; + StorageDead(_4); + return; } - bb5: { - StorageDead(_13); + bb7: { + _15 = ((_11 as Some).0: usize); + _16 = opaque::(move _15) -> [return: bb8, unwind continue]; + } + + bb8: { + StorageDead(_11); goto -> bb1; } + + bb9: { + unreachable; + } +} + +ALLOC0 (size: 16, align: 8) { + 00 00 00 00 00 00 00 00 __ __ __ __ __ __ __ __ │ ........░░░░░░░░ } diff --git a/tests/mir-opt/pre-codegen/matches_macro.issue_77355_opt.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/matches_macro.issue_77355_opt.PreCodegen.after.mir deleted file mode 100644 index d41135c6a4fa3..0000000000000 --- a/tests/mir-opt/pre-codegen/matches_macro.issue_77355_opt.PreCodegen.after.mir +++ /dev/null @@ -1,22 +0,0 @@ -// MIR for `issue_77355_opt` after PreCodegen - -fn issue_77355_opt(_1: Foo) -> u64 { - debug num => _1; - let mut _0: u64; - let mut _2: isize; - - bb0: { - _2 = discriminant(_1); - switchInt(move _2) -> [1: bb1, 2: bb1, otherwise: bb2]; - } - - bb1: { - _0 = const 23_u64; - return; - } - - bb2: { - _0 = const 42_u64; - return; - } -} diff --git a/tests/mir-opt/pre-codegen/matches_macro.rs b/tests/mir-opt/pre-codegen/matches_macro.rs deleted file mode 100644 index 42de229657189..0000000000000 --- a/tests/mir-opt/pre-codegen/matches_macro.rs +++ /dev/null @@ -1,27 +0,0 @@ -// This test verifies that the MIR we output using the `matches!()` macro is close -// to the MIR for an `if let` branch. - -pub enum Foo { - A, - B, - C, - D, - E, - F, -} - -// EMIT_MIR matches_macro.issue_77355_opt.PreCodegen.after.mir -fn issue_77355_opt(num: Foo) -> u64 { - // CHECK-LABEL: fn issue_77355_opt( - // CHECK: switchInt({{.*}}) -> [1: bb1, 2: bb1, otherwise: bb2]; - // CHECK: bb1: { - // CHECK-NEXT: _0 = const 23_u64; - // CHECK-NEXT: return; - // CHECK: bb2: { - // CHECK-NEXT: _0 = const 42_u64; - // CHECK-NEXT: return; - if matches!(num, Foo::B | Foo::C) { 23 } else { 42 } -} -fn main() { - issue_77355_opt(Foo::A); -} 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 ed965770adbe0..99805da56694c 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 @@ -8,15 +8,16 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { let mut _4: std::ops::Range; let mut _5: std::ops::Range; let mut _6: &mut std::ops::Range; - let mut _14: std::option::Option; - let mut _16: &impl Fn(u32); - let mut _17: (u32,); - let _18: (); + let mut _12: std::option::Option; + let mut _15: isize; + let mut _17: &impl Fn(u32); + let mut _18: (u32,); + let _19: (); scope 1 { debug iter => _5; - let _15: u32; + let _16: u32; scope 2 { - debug x => _15; + debug x => _16; } scope 4 (inlined iter::range::>::next) { debug self => _6; @@ -25,10 +26,10 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { let mut _7: &u32; let mut _8: &u32; let mut _11: bool; - let _12: u32; - let mut _13: u32; + let _13: u32; + let mut _14: u32; scope 6 { - debug old => _12; + debug old => _13; scope 7 { } } @@ -53,9 +54,9 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb1: { - StorageLive(_14); - _6 = &mut _5; StorageLive(_12); + _6 = &mut _5; + StorageLive(_13); StorageLive(_11); StorageLive(_7); _7 = &(_5.0: u32); @@ -68,49 +69,69 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { _11 = Lt(move _9, move _10); StorageDead(_10); StorageDead(_9); - switchInt(move _11) -> [0: bb2, otherwise: bb4]; + switchInt(move _11) -> [0: bb2, otherwise: bb3]; } bb2: { StorageDead(_8); StorageDead(_7); - StorageDead(_11); - StorageDead(_12); - StorageDead(_14); - StorageDead(_5); - drop(_3) -> [return: bb3, unwind unreachable]; + _12 = const Option::::None; + goto -> bb5; } bb3: { - return; + StorageDead(_8); + StorageDead(_7); + _13 = (_5.0: u32); + StorageLive(_14); + _14 = ::forward_unchecked(_13, const 1_usize) -> [return: bb4, unwind unreachable]; } bb4: { - StorageDead(_8); - StorageDead(_7); - _12 = (_5.0: u32); - StorageLive(_13); - _13 = ::forward_unchecked(_12, const 1_usize) -> [return: bb5, unwind unreachable]; + (_5.0: u32) = move _14; + StorageDead(_14); + _12 = Option::::Some(_13); + goto -> bb5; } bb5: { - (_5.0: u32) = move _13; - StorageDead(_13); - _14 = Option::::Some(_12); StorageDead(_11); + StorageDead(_13); + _15 = discriminant(_12); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; + } + + bb6: { StorageDead(_12); - _15 = ((_14 as Some).0: u32); - StorageLive(_16); - _16 = &_3; + StorageDead(_5); + drop(_3) -> [return: bb7, unwind unreachable]; + } + + bb7: { + return; + } + + bb8: { + _16 = ((_12 as Some).0: u32); StorageLive(_17); - _17 = (_15,); - _18 = >::call(move _16, move _17) -> [return: bb6, unwind unreachable]; + _17 = &_3; + StorageLive(_18); + _18 = (_16,); + _19 = >::call(move _17, move _18) -> [return: bb9, unwind unreachable]; } - bb6: { + bb9: { + StorageDead(_18); StorageDead(_17); - StorageDead(_16); - StorageDead(_14); + StorageDead(_12); goto -> bb1; } + + bb10: { + unreachable; + } +} + +ALLOC0 (size: 8, align: 4) { + 00 00 00 00 __ __ __ __ │ ....░░░░ } 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 a7ee9be19bd4c..f40f130717569 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 @@ -8,15 +8,16 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { let mut _4: std::ops::Range; let mut _5: std::ops::Range; let mut _6: &mut std::ops::Range; - let mut _14: std::option::Option; - let mut _16: &impl Fn(u32); - let mut _17: (u32,); - let _18: (); + let mut _12: std::option::Option; + let mut _15: isize; + let mut _17: &impl Fn(u32); + let mut _18: (u32,); + let _19: (); scope 1 { debug iter => _5; - let _15: u32; + let _16: u32; scope 2 { - debug x => _15; + debug x => _16; } scope 4 (inlined iter::range::>::next) { debug self => _6; @@ -25,10 +26,10 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { let mut _7: &u32; let mut _8: &u32; let mut _11: bool; - let _12: u32; - let mut _13: u32; + let _13: u32; + let mut _14: u32; scope 6 { - debug old => _12; + debug old => _13; scope 7 { } } @@ -53,9 +54,9 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb1: { - StorageLive(_14); - _6 = &mut _5; StorageLive(_12); + _6 = &mut _5; + StorageLive(_13); StorageLive(_11); StorageLive(_7); _7 = &(_5.0: u32); @@ -68,57 +69,77 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { _11 = Lt(move _9, move _10); StorageDead(_10); StorageDead(_9); - switchInt(move _11) -> [0: bb2, otherwise: bb4]; + switchInt(move _11) -> [0: bb2, otherwise: bb3]; } bb2: { StorageDead(_8); StorageDead(_7); - StorageDead(_11); - StorageDead(_12); - StorageDead(_14); - StorageDead(_5); - drop(_3) -> [return: bb3, unwind continue]; + _12 = const Option::::None; + goto -> bb5; } bb3: { - return; + StorageDead(_8); + StorageDead(_7); + _13 = (_5.0: u32); + StorageLive(_14); + _14 = ::forward_unchecked(_13, const 1_usize) -> [return: bb4, unwind: bb11]; } bb4: { - StorageDead(_8); - StorageDead(_7); - _12 = (_5.0: u32); - StorageLive(_13); - _13 = ::forward_unchecked(_12, const 1_usize) -> [return: bb5, unwind: bb7]; + (_5.0: u32) = move _14; + StorageDead(_14); + _12 = Option::::Some(_13); + goto -> bb5; } bb5: { - (_5.0: u32) = move _13; - StorageDead(_13); - _14 = Option::::Some(_12); StorageDead(_11); + StorageDead(_13); + _15 = discriminant(_12); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; + } + + bb6: { StorageDead(_12); - _15 = ((_14 as Some).0: u32); - StorageLive(_16); - _16 = &_3; + StorageDead(_5); + drop(_3) -> [return: bb7, unwind continue]; + } + + bb7: { + return; + } + + bb8: { + _16 = ((_12 as Some).0: u32); StorageLive(_17); - _17 = (_15,); - _18 = >::call(move _16, move _17) -> [return: bb6, unwind: bb7]; + _17 = &_3; + StorageLive(_18); + _18 = (_16,); + _19 = >::call(move _17, move _18) -> [return: bb9, unwind: bb11]; } - bb6: { + bb9: { + StorageDead(_18); StorageDead(_17); - StorageDead(_16); - StorageDead(_14); + StorageDead(_12); goto -> bb1; } - bb7 (cleanup): { - drop(_3) -> [return: bb8, unwind terminate(cleanup)]; + bb10: { + unreachable; } - bb8 (cleanup): { + bb11 (cleanup): { + drop(_3) -> [return: bb12, unwind terminate(cleanup)]; + } + + bb12 (cleanup): { resume; } } + +ALLOC0 (size: 8, align: 4) { + 00 00 00 00 __ __ __ __ │ ....░░░░ +} 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 543e8918e3943..83915d3c44931 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 @@ -8,20 +8,21 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _4: std::ops::Range; let mut _5: std::ops::Range; let mut _6: &mut std::ops::Range; - let mut _14: std::option::Option; - let mut _16: usize; - let mut _17: bool; - let mut _19: &impl Fn(usize, &T); - let mut _20: (usize, &T); - let _21: (); + let mut _12: std::option::Option; + let mut _15: isize; + let mut _17: usize; + let mut _18: bool; + let mut _20: &impl Fn(usize, &T); + let mut _21: (usize, &T); + let _22: (); scope 1 { debug iter => _5; - let _15: usize; + let _16: usize; scope 2 { - debug i => _15; - let _18: &T; + debug i => _16; + let _19: &T; scope 3 { - debug x => _18; + debug x => _19; } } scope 5 (inlined iter::range::>::next) { @@ -31,10 +32,10 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _7: &usize; let mut _8: &usize; let mut _11: bool; - let _12: usize; - let mut _13: usize; + let _13: usize; + let mut _14: usize; scope 7 { - debug old => _12; + debug old => _13; scope 8 { } } @@ -62,9 +63,9 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb1: { - StorageLive(_14); - _6 = &mut _5; StorageLive(_12); + _6 = &mut _5; + StorageLive(_13); StorageLive(_11); StorageLive(_7); _7 = &(_5.0: usize); @@ -77,56 +78,76 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _11 = Lt(move _9, move _10); StorageDead(_10); StorageDead(_9); - switchInt(move _11) -> [0: bb2, otherwise: bb4]; + switchInt(move _11) -> [0: bb2, otherwise: bb3]; } bb2: { StorageDead(_8); StorageDead(_7); - StorageDead(_11); - StorageDead(_12); - StorageDead(_14); - StorageDead(_5); - drop(_2) -> [return: bb3, unwind unreachable]; + _12 = const Option::::None; + goto -> bb5; } bb3: { - return; + StorageDead(_8); + StorageDead(_7); + _13 = (_5.0: usize); + StorageLive(_14); + _14 = ::forward_unchecked(_13, const 1_usize) -> [return: bb4, unwind unreachable]; } bb4: { - StorageDead(_8); - StorageDead(_7); - _12 = (_5.0: usize); - StorageLive(_13); - _13 = ::forward_unchecked(_12, const 1_usize) -> [return: bb5, unwind unreachable]; + (_5.0: usize) = move _14; + StorageDead(_14); + _12 = Option::::Some(_13); + goto -> bb5; } bb5: { - (_5.0: usize) = move _13; - StorageDead(_13); - _14 = Option::::Some(_12); StorageDead(_11); - StorageDead(_12); - _15 = ((_14 as Some).0: usize); - _16 = Len((*_1)); - _17 = Lt(_15, _16); - assert(move _17, "index out of bounds: the length is {} but the index is {}", move _16, _15) -> [success: bb6, unwind unreachable]; + StorageDead(_13); + _15 = discriminant(_12); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb11]; } bb6: { - _18 = &(*_1)[_15]; - StorageLive(_19); - _19 = &_2; - StorageLive(_20); - _20 = (_15, _18); - _21 = >::call(move _19, move _20) -> [return: bb7, unwind unreachable]; + StorageDead(_12); + StorageDead(_5); + drop(_2) -> [return: bb7, unwind unreachable]; } bb7: { + return; + } + + bb8: { + _16 = ((_12 as Some).0: usize); + _17 = Len((*_1)); + _18 = Lt(_16, _17); + assert(move _18, "index out of bounds: the length is {} but the index is {}", move _17, _16) -> [success: bb9, unwind unreachable]; + } + + bb9: { + _19 = &(*_1)[_16]; + StorageLive(_20); + _20 = &_2; + StorageLive(_21); + _21 = (_16, _19); + _22 = >::call(move _20, move _21) -> [return: bb10, unwind unreachable]; + } + + bb10: { + StorageDead(_21); StorageDead(_20); - StorageDead(_19); - StorageDead(_14); + StorageDead(_12); goto -> bb1; } + + bb11: { + unreachable; + } +} + +ALLOC0 (size: 16, align: 8) { + 00 00 00 00 00 00 00 00 __ __ __ __ __ __ __ __ │ ........░░░░░░░░ } 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 a16e9cd9e516d..0a005a460e84d 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 @@ -8,20 +8,21 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _4: std::ops::Range; let mut _5: std::ops::Range; let mut _6: &mut std::ops::Range; - let mut _14: std::option::Option; - let mut _16: usize; - let mut _17: bool; - let mut _19: &impl Fn(usize, &T); - let mut _20: (usize, &T); - let _21: (); + let mut _12: std::option::Option; + let mut _15: isize; + let mut _17: usize; + let mut _18: bool; + let mut _20: &impl Fn(usize, &T); + let mut _21: (usize, &T); + let _22: (); scope 1 { debug iter => _5; - let _15: usize; + let _16: usize; scope 2 { - debug i => _15; - let _18: &T; + debug i => _16; + let _19: &T; scope 3 { - debug x => _18; + debug x => _19; } } scope 5 (inlined iter::range::>::next) { @@ -31,10 +32,10 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _7: &usize; let mut _8: &usize; let mut _11: bool; - let _12: usize; - let mut _13: usize; + let _13: usize; + let mut _14: usize; scope 7 { - debug old => _12; + debug old => _13; scope 8 { } } @@ -62,9 +63,9 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb1: { - StorageLive(_14); - _6 = &mut _5; StorageLive(_12); + _6 = &mut _5; + StorageLive(_13); StorageLive(_11); StorageLive(_7); _7 = &(_5.0: usize); @@ -77,64 +78,84 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _11 = Lt(move _9, move _10); StorageDead(_10); StorageDead(_9); - switchInt(move _11) -> [0: bb2, otherwise: bb4]; + switchInt(move _11) -> [0: bb2, otherwise: bb3]; } bb2: { StorageDead(_8); StorageDead(_7); - StorageDead(_11); - StorageDead(_12); - StorageDead(_14); - StorageDead(_5); - drop(_2) -> [return: bb3, unwind continue]; + _12 = const Option::::None; + goto -> bb5; } bb3: { - return; + StorageDead(_8); + StorageDead(_7); + _13 = (_5.0: usize); + StorageLive(_14); + _14 = ::forward_unchecked(_13, const 1_usize) -> [return: bb4, unwind: bb12]; } bb4: { - StorageDead(_8); - StorageDead(_7); - _12 = (_5.0: usize); - StorageLive(_13); - _13 = ::forward_unchecked(_12, const 1_usize) -> [return: bb5, unwind: bb8]; + (_5.0: usize) = move _14; + StorageDead(_14); + _12 = Option::::Some(_13); + goto -> bb5; } bb5: { - (_5.0: usize) = move _13; - StorageDead(_13); - _14 = Option::::Some(_12); StorageDead(_11); - StorageDead(_12); - _15 = ((_14 as Some).0: usize); - _16 = Len((*_1)); - _17 = Lt(_15, _16); - assert(move _17, "index out of bounds: the length is {} but the index is {}", move _16, _15) -> [success: bb6, unwind: bb8]; + StorageDead(_13); + _15 = discriminant(_12); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb11]; } bb6: { - _18 = &(*_1)[_15]; - StorageLive(_19); - _19 = &_2; - StorageLive(_20); - _20 = (_15, _18); - _21 = >::call(move _19, move _20) -> [return: bb7, unwind: bb8]; + StorageDead(_12); + StorageDead(_5); + drop(_2) -> [return: bb7, unwind continue]; } bb7: { + return; + } + + bb8: { + _16 = ((_12 as Some).0: usize); + _17 = Len((*_1)); + _18 = Lt(_16, _17); + assert(move _18, "index out of bounds: the length is {} but the index is {}", move _17, _16) -> [success: bb9, unwind: bb12]; + } + + bb9: { + _19 = &(*_1)[_16]; + StorageLive(_20); + _20 = &_2; + StorageLive(_21); + _21 = (_16, _19); + _22 = >::call(move _20, move _21) -> [return: bb10, unwind: bb12]; + } + + bb10: { + StorageDead(_21); StorageDead(_20); - StorageDead(_19); - StorageDead(_14); + StorageDead(_12); goto -> bb1; } - bb8 (cleanup): { - drop(_2) -> [return: bb9, unwind terminate(cleanup)]; + bb11: { + unreachable; } - bb9 (cleanup): { + bb12 (cleanup): { + drop(_2) -> [return: bb13, unwind terminate(cleanup)]; + } + + bb13 (cleanup): { resume; } } + +ALLOC0 (size: 16, align: 8) { + 00 00 00 00 00 00 00 00 __ __ __ __ __ __ __ __ │ ........░░░░░░░░ +} diff --git a/tests/mir-opt/pre-codegen/try_identity.new.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/try_identity.new.PreCodegen.after.mir index 16d6d9719b641..c1d4d4871d02c 100644 --- a/tests/mir-opt/pre-codegen/try_identity.new.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/try_identity.new.PreCodegen.after.mir @@ -6,51 +6,65 @@ fn new(_1: Result) -> Result { let mut _2: isize; let _3: T; let mut _4: std::ops::ControlFlow; - let _5: T; - let _6: E; - let _7: E; + let _5: E; + let mut _6: isize; + let _7: T; + let _8: E; scope 1 { debug v => _3; } scope 2 { - debug e => _6; + debug e => _5; } scope 3 { - debug v => _5; + debug v => _7; } scope 4 { - debug e => _7; + debug e => _8; } bb0: { StorageLive(_4); _2 = discriminant(_1); - switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; + switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb7]; } bb1: { _3 = move ((_1 as Ok).0: T); _4 = ControlFlow::::Continue(_3); - _5 = move ((_4 as Continue).0: T); - _0 = Result::::Ok(_5); - StorageDead(_4); goto -> bb3; } bb2: { - _6 = move ((_1 as Err).0: E); - _4 = ControlFlow::::Break(_6); - _7 = move ((_4 as Break).0: E); - _0 = Result::::Err(_7); - StorageDead(_4); + _5 = move ((_1 as Err).0: E); + _4 = ControlFlow::::Break(_5); goto -> bb3; } bb3: { - return; + _6 = discriminant(_4); + switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb7]; } bb4: { + _7 = move ((_4 as Continue).0: T); + _0 = Result::::Ok(_7); + StorageDead(_4); + goto -> bb6; + } + + bb5: { + _8 = move ((_4 as Break).0: E); + _0 = Result::::Err(_8); + StorageDead(_4); + goto -> bb6; + } + + bb6: { + return; + } + + bb7: { unreachable; } } diff --git a/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff similarity index 87% rename from tests/mir-opt/separate_const_switch.identity.JumpThreading.diff rename to tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff index ab3d91ab91887..d273161528464 100644 --- a/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff +++ b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff @@ -1,5 +1,5 @@ -- // MIR for `identity` before JumpThreading -+ // MIR for `identity` after JumpThreading +- // MIR for `identity` before SeparateConstSwitch ++ // MIR for `identity` after SeparateConstSwitch fn identity(_1: Result) -> Result { debug x => _1; @@ -79,8 +79,7 @@ StorageDead(_8); StorageDead(_3); _4 = discriminant(_2); -- switchInt(move _4) -> [0: bb1, 1: bb2, otherwise: bb6]; -+ goto -> bb1; + switchInt(move _4) -> [0: bb1, 1: bb2, otherwise: bb6]; } bb4: { @@ -89,8 +88,7 @@ _11 = Result::::Err(_10); _2 = ControlFlow::, i32>::Break(move _11); StorageDead(_11); -- goto -> bb3; -+ goto -> bb7; + goto -> bb3; } bb5: { @@ -101,15 +99,6 @@ bb6: { unreachable; -+ } -+ -+ bb7: { -+ StorageDead(_10); -+ StorageDead(_9); -+ StorageDead(_8); -+ StorageDead(_3); -+ _4 = discriminant(_2); -+ goto -> bb2; } } diff --git a/tests/mir-opt/separate_const_switch.rs b/tests/mir-opt/separate_const_switch.rs index bad61d97475a8..3f43cdf4350b7 100644 --- a/tests/mir-opt/separate_const_switch.rs +++ b/tests/mir-opt/separate_const_switch.rs @@ -6,7 +6,7 @@ use std::ops::ControlFlow; -// EMIT_MIR separate_const_switch.too_complex.JumpThreading.diff +// EMIT_MIR separate_const_switch.too_complex.SeparateConstSwitch.diff fn too_complex(x: Result) -> Option { // The pass should break the outer match into // two blocks that only have one parent each. @@ -23,7 +23,7 @@ fn too_complex(x: Result) -> Option { } } -// EMIT_MIR separate_const_switch.identity.JumpThreading.diff +// EMIT_MIR separate_const_switch.identity.SeparateConstSwitch.diff fn identity(x: Result) -> Result { Ok(x?) } diff --git a/tests/mir-opt/separate_const_switch.too_complex.JumpThreading.diff b/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff similarity index 83% rename from tests/mir-opt/separate_const_switch.too_complex.JumpThreading.diff rename to tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff index 1ac527e9338a1..294bfa661cfa4 100644 --- a/tests/mir-opt/separate_const_switch.too_complex.JumpThreading.diff +++ b/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff @@ -1,5 +1,5 @@ -- // MIR for `too_complex` before JumpThreading -+ // MIR for `too_complex` after JumpThreading +- // MIR for `too_complex` before SeparateConstSwitch ++ // MIR for `too_complex` after SeparateConstSwitch fn too_complex(_1: Result) -> Option { debug x => _1; @@ -33,8 +33,7 @@ bb1: { _5 = ((_1 as Err).0: usize); _2 = ControlFlow::::Break(_5); -- goto -> bb3; -+ goto -> bb8; + goto -> bb3; } bb2: { @@ -45,8 +44,7 @@ bb3: { _6 = discriminant(_2); -- switchInt(move _6) -> [0: bb5, 1: bb4, otherwise: bb7]; -+ goto -> bb5; + switchInt(move _6) -> [0: bb5, 1: bb4, otherwise: bb7]; } bb4: { @@ -70,11 +68,6 @@ bb7: { unreachable; -+ } -+ -+ bb8: { -+ _6 = discriminant(_2); -+ goto -> bb4; } }