From 44437dadd215466bd4ae5baf3b704cdec1950aa3 Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Tue, 27 Oct 2020 20:03:28 +0100 Subject: [PATCH 01/18] Introduce new dataflow implementation for available locals, and use it to implement unneeded deref mir-opt pass --- compiler/rustc_middle/src/mir/mod.rs | 2 +- compiler/rustc_middle/src/mir/tcx.rs | 16 + .../rustc_mir/src/dataflow/framework/mod.rs | 15 + .../src/dataflow/impls/available_locals.rs | 338 ++++++++++++++++++ compiler/rustc_mir/src/dataflow/impls/mod.rs | 2 + .../rustc_mir/src/transform/instcombine.rs | 136 +------ compiler/rustc_mir/src/transform/mod.rs | 2 + .../rustc_mir/src/transform/unneeded_deref.rs | 183 ++++++++++ .../ref_deref_project.main.ConstProp.diff | 2 +- ...e_closure_borrows_arg.foo.Inline.after.mir | 2 +- ...st_combine_deref.deep_opt.InstCombine.diff | 92 ----- ...e_deref.do_not_miscompile.InstCombine.diff | 85 ----- ...st_combine_deref.dont_opt.InstCombine.diff | 53 --- ..._combine_deref.opt_struct.InstCombine.diff | 44 --- src/test/mir-opt/inst_combine_deref.rs | 69 ---- ..._combine_deref.simple_opt.InstCombine.diff | 34 -- ...ument_coverage.bar.InstrumentCoverage.diff | 13 - ...ment_coverage.main.InstrumentCoverage.diff | 51 --- src/test/mir-opt/issue-78192.rs | 2 +- ...76432.test.SimplifyComparisonIntegral.diff | 6 +- ....diff => issue_78192.f.UnneededDeref.diff} | 7 +- ...c.try_identity.DestinationPropagation.diff | 72 ---- ...t.{impl#0}-append.SimplifyArmIdentity.diff | 104 ------ ...unneeded_deref.deep_opt.UnneededDeref.diff | 92 +++++ ...deref.do_not_miscompile.UnneededDeref.diff | 84 +++++ ..._not_miscompile_mut_ref.UnneededDeref.diff | 70 ++++ ...o_not_opt_different_bbs.UnneededDeref.diff | 64 ++++ ..._deref.do_not_use_moved.UnneededDeref.diff | 35 ++ ...unneeded_deref.dont_opt.UnneededDeref.diff | 52 +++ ...eeded_deref.operand_opt.UnneededDeref.diff | 71 ++++ ...deref.opt_different_bbs.UnneededDeref.diff | 58 +++ ...eref.opt_different_bbs2.UnneededDeref.diff | 52 +++ ...needed_deref.opt_struct.UnneededDeref.diff | 44 +++ src/test/mir-opt/unneeded_deref.rs | 161 +++++++++ ...needed_deref.simple_opt.UnneededDeref.diff | 34 ++ ...ded_deref.very_deep_opt.UnneededDeref.diff | 254 +++++++++++++ 36 files changed, 1640 insertions(+), 761 deletions(-) create mode 100644 compiler/rustc_mir/src/dataflow/impls/available_locals.rs create mode 100644 compiler/rustc_mir/src/transform/unneeded_deref.rs delete mode 100644 src/test/mir-opt/inst_combine_deref.deep_opt.InstCombine.diff delete mode 100644 src/test/mir-opt/inst_combine_deref.do_not_miscompile.InstCombine.diff delete mode 100644 src/test/mir-opt/inst_combine_deref.dont_opt.InstCombine.diff delete mode 100644 src/test/mir-opt/inst_combine_deref.opt_struct.InstCombine.diff delete mode 100644 src/test/mir-opt/inst_combine_deref.rs delete mode 100644 src/test/mir-opt/inst_combine_deref.simple_opt.InstCombine.diff delete mode 100644 src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff delete mode 100644 src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff rename src/test/mir-opt/{issue_78192.f.InstCombine.diff => issue_78192.f.UnneededDeref.diff} (87%) delete mode 100644 src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff delete mode 100644 src/test/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff create mode 100644 src/test/mir-opt/unneeded_deref.deep_opt.UnneededDeref.diff create mode 100644 src/test/mir-opt/unneeded_deref.do_not_miscompile.UnneededDeref.diff create mode 100644 src/test/mir-opt/unneeded_deref.do_not_miscompile_mut_ref.UnneededDeref.diff create mode 100644 src/test/mir-opt/unneeded_deref.do_not_opt_different_bbs.UnneededDeref.diff create mode 100644 src/test/mir-opt/unneeded_deref.do_not_use_moved.UnneededDeref.diff create mode 100644 src/test/mir-opt/unneeded_deref.dont_opt.UnneededDeref.diff create mode 100644 src/test/mir-opt/unneeded_deref.operand_opt.UnneededDeref.diff create mode 100644 src/test/mir-opt/unneeded_deref.opt_different_bbs.UnneededDeref.diff create mode 100644 src/test/mir-opt/unneeded_deref.opt_different_bbs2.UnneededDeref.diff create mode 100644 src/test/mir-opt/unneeded_deref.opt_struct.UnneededDeref.diff create mode 100644 src/test/mir-opt/unneeded_deref.rs create mode 100644 src/test/mir-opt/unneeded_deref.simple_opt.UnneededDeref.diff create mode 100644 src/test/mir-opt/unneeded_deref.very_deep_opt.UnneededDeref.diff diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 5fe7b0f647dcd..c1ed623058d43 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2395,7 +2395,7 @@ impl<'tcx> UserTypeProjections { /// Encodes the effect of a user-supplied type annotation on the /// subcomponents of a pattern. The effect is determined by applying the -/// given list of proejctions to some underlying base type. Often, +/// given list of projections to some underlying base type. Often, /// the projection element list `projs` is empty, in which case this /// directly encodes a type in `base`. But in the case of complex patterns with /// subpatterns and bindings, we want to apply only a *part* of the type to a variable, diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index f0bfdae261c64..866040945a8fc 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -7,6 +7,7 @@ use crate::mir::*; use crate::ty::subst::Subst; use crate::ty::{self, Ty, TyCtxt}; use rustc_hir as hir; +use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_target::abi::VariantIdx; #[derive(Copy, Clone, Debug, TypeFoldable)] @@ -208,6 +209,21 @@ impl<'tcx> Rvalue<'tcx> { _ => RvalueInitializationState::Deep, } } + + /// Returns all locals that participate in the Rvalue + pub fn participating_locals(&self, location: Location) -> impl Iterator { + struct LocalVisitor(Vec); + + impl<'tcx> Visitor<'tcx> for LocalVisitor { + fn visit_local(&mut self, local: &Local, _: PlaceContext, _: Location) { + self.0.push(*local); + } + } + + let mut visitor = LocalVisitor(vec![]); + visitor.visit_rvalue(self, location); + visitor.0.into_iter() + } } impl<'tcx> Operand<'tcx> { diff --git a/compiler/rustc_mir/src/dataflow/framework/mod.rs b/compiler/rustc_mir/src/dataflow/framework/mod.rs index 524ad0af1a7b4..fe5aa9ae04b3b 100644 --- a/compiler/rustc_mir/src/dataflow/framework/mod.rs +++ b/compiler/rustc_mir/src/dataflow/framework/mod.rs @@ -412,6 +412,9 @@ pub trait GenKill { self.kill(elem); } } + + /// Returns whether `elem` is alive + fn is_alive(&self, elem: T) -> bool; } /// Stores a transfer function for a gen/kill problem. @@ -450,6 +453,10 @@ impl GenKill for GenKillSet { self.kill.insert(elem); self.gen.remove(elem); } + + fn is_alive(&self, elem: T) -> bool { + self.gen.contains(elem) && !self.kill.contains(elem) + } } impl GenKill for BitSet { @@ -460,6 +467,10 @@ impl GenKill for BitSet { fn kill(&mut self, elem: T) { self.remove(elem); } + + fn is_alive(&self, elem: T) -> bool { + self.contains(elem) + } } impl GenKill for lattice::Dual> { @@ -470,6 +481,10 @@ impl GenKill for lattice::Dual> { fn kill(&mut self, elem: T) { self.0.remove(elem); } + + fn is_alive(&self, elem: T) -> bool { + self.0.contains(elem) + } } // NOTE: DO NOT CHANGE VARIANT ORDER. The derived `Ord` impls rely on the current order. diff --git a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs new file mode 100644 index 0000000000000..5da53fdbfa351 --- /dev/null +++ b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs @@ -0,0 +1,338 @@ +use std::{fmt, hash::BuildHasherDefault}; + +use rustc_data_structures::fx::FxIndexMap; +use rustc_index::{bit_set::BitSet, vec::Idx}; +use rustc_middle::{ + mir::{self, Body, Local, Location}, + mir::{visit::Visitor, BorrowKind, Operand, Place, Rvalue, Statement, StatementKind}, +}; +use smallvec::SmallVec; + +use crate::dataflow::{ + fmt::DebugWithAdapter, fmt::DebugWithContext, lattice, lattice::Dual, AnalysisDomain, Forward, + GenKill, GenKillAnalysis, +}; + +/// Dataflow analysis for availability of locals. A local is available at a given program point, +/// if the value of the local can freely be used at the given program point. +/// Consider the following example: +/// ``` +/// _1 = 4; +/// _2 = &_1; +/// _3 = *_2 +/// ``` +/// In the above example, `_2` is available at the third statement, so the statement can be +/// simplified to `_3 = _1`. +/// In general, an available local can be used freely on any path from the definition of `_2` to +/// statement `s`, if `_2` and its value is guaranteed to not be changed on all paths. +/// +/// In the following example `_2` is not available in `bb2`, +/// since we do not know if `_2 = &5` is executed. +/// ``` +/// bb0 { +/// _2 = &_1; +/// switchInt(_1) -> [4: bb1, otherwise: bb2] +/// } +/// +/// bb1 { +/// _2 = &5; +/// } +/// +/// bb2 { +/// _3 = *_2 +/// } +/// ``` +pub struct AvailableLocals { + local_with_location_map: LocalWithLocationMap, +} + +type State = Dual>; + +impl<'a, 'tcx> AvailableLocals { + pub fn new(body: &'a Body<'tcx>) -> Self { + let local_with_location_map = LocalWithLocationMap::new(body); + debug!("Constructed {:?}", local_with_location_map); + Self { local_with_location_map } + } + + /// Returns the state with context attached, making debug easier + pub fn debug_state(&'a self, state: &'a State) -> impl fmt::Debug + 'a { + DebugWithAdapter { this: state, ctxt: &self.local_with_location_map } + } + + /// Returns whether the given local is available at the given state + pub fn is_available(&self, local: Local, state: &'a State) -> bool { + self.local_with_location_map.local_with_locations(local).any( + |place_taken_ref_local_with_location| { + state.0.contains(place_taken_ref_local_with_location) + }, + ) + } + + fn transfer_function(&'a self, available: &'a mut T) -> TransferFunction<'a, T> + where + T: GenKill, + { + TransferFunction { available, local_with_location_map: &self.local_with_location_map } + } +} +impl AnalysisDomain<'tcx> for AvailableLocals { + /// We want a *forward must* analysis. + /// At each join point, we only keep locals that were available in both basic blocks. + /// For this, we use the Dual of a semi-lattice, such that intersection is the join operator + type Domain = State; + type Direction = Forward; + + const NAME: &'static str = "available_locals"; + + fn bottom_value(&self, _: &mir::Body<'tcx>) -> Self::Domain { + // If we were not using the dual, we would have nothing available, but since we are using + // the dual, we also "reverse" the bottom to be filled + // bottom = nothing is available + let bottom = BitSet::new_filled(self.local_with_location_map.len()); + lattice::Dual(bottom) + } + + fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut Self::Domain) { + // In the start block, nothing is available at first + state.0.clear(); + + // only the function parameters are available + for arg in body.args_iter() { + state.0.insert(self.local_with_location_map.local_with_specific_location(arg, None)); + } + } +} + +impl GenKillAnalysis<'tcx> for AvailableLocals { + type Idx = LocalWithLocationIndex; + + fn statement_effect( + &self, + trans: &mut impl GenKill, + statement: &mir::Statement<'tcx>, + location: Location, + ) { + self.transfer_function(trans).visit_statement(statement, location); + } + + fn terminator_effect( + &self, + trans: &mut impl GenKill, + terminator: &mir::Terminator<'tcx>, + location: Location, + ) { + self.transfer_function(trans).visit_terminator(terminator, location); + } + + fn call_return_effect( + &self, + _trans: &mut impl GenKill, + _block: mir::BasicBlock, + _func: &mir::Operand<'tcx>, + _args: &[mir::Operand<'tcx>], + _dest_place: mir::Place<'tcx>, + ) { + // Conservatively do not try to reason about calls + } +} + +// Compiling rustc stage2 reveals that 95% of locals are only used at 2 locations +const LOCAL_WITH_LOCATION_SMALLVEC_CAP: usize = 2; + +#[derive(Debug)] +struct LocalWithLocationMap( + FxIndexMap< + Local, + SmallVec<[(LocalWithLocationIndex, Option); LOCAL_WITH_LOCATION_SMALLVEC_CAP]>, + >, +); + +impl LocalWithLocationMap { + fn new(body: &Body<'tcx>) -> Self { + let mut map = FxIndexMap::with_capacity_and_hasher( + 1 + body.arg_count + body.vars_and_temps_iter().len(), + BuildHasherDefault::default(), + ); + + // return pointer + map.entry(body.local_decls.next_index()) + .or_insert(SmallVec::with_capacity(2)) + .push((0usize.into(), None)); + + for arg in body.args_iter().chain(body.vars_and_temps_iter()) { + map.entry(arg).or_insert(SmallVec::with_capacity(2)).push((0usize.into(), None)); + } + + let mut builder = LocalWithLocationMapBuilder(&mut map); + builder.visit_body(body); + + // set indices + let mut idx = LocalWithLocationIndex::from(0usize); + for x in map.values_mut() { + for (idx_to_set, _) in x.iter_mut() { + *idx_to_set = idx; + idx.increment_by(1); + } + } + + Self(map) + } + + fn local_with_specific_location( + &self, + local: Local, + location: Option, + ) -> LocalWithLocationIndex { + debug!("Looking for {:?} in {:?}", (local, location), self.0); + let locations = self.0.get(&local).unwrap(); + *locations + .iter() + .find(|(_, l)| *l == location) + .map(|(location_idx, _)| location_idx) + .unwrap() + } + + fn local_with_locations( + &self, + local: Local, + ) -> impl Iterator + '_ { + debug!("Looking for {:?} in {:?}", local, self.0); + let locations = self.0.get(&local).unwrap(); + return locations.iter().map(move |(location_idx, _)| *location_idx); + } + + fn len(&self) -> usize { + let mut count = 0; + for v in self.0.values() { + count += v.len(); + } + count + } +} + +struct LocalWithLocationMapBuilder<'a>( + &'a mut FxIndexMap); 2]>>, +); + +impl<'a, 'tcx> Visitor<'tcx> for LocalWithLocationMapBuilder<'a> { + fn visit_assign(&mut self, place: &Place<'tcx>, _: &Rvalue<'tcx>, location: Location) { + self.0 + .entry(place.local) + .or_insert(SmallVec::with_capacity(2)) + .push((0usize.into(), Some(location))); + } +} + +rustc_index::newtype_index! { + pub struct LocalWithLocationIndex { + DEBUG_FORMAT = "ll_{}" + } +} + +impl DebugWithContext for LocalWithLocationIndex { + fn fmt_with(&self, ctx: &AvailableLocals, f: &mut fmt::Formatter<'_>) -> fmt::Result { + DebugWithContext::fmt_with(self, &ctx.local_with_location_map, f) + } +} + +impl DebugWithContext for LocalWithLocationIndex { + fn fmt_with(&self, ctx: &LocalWithLocationMap, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // find local and location + for (local, value) in ctx.0.iter() { + if let Some((idx, location)) = value.iter().find(|(idx, _)| idx == self) { + return write!(f, "{:?}: {:?}", idx, (local, location)); + } + } + unreachable!() + } +} + +struct TransferFunction<'a, T> +where + T: GenKill, +{ + available: &'a mut T, + local_with_location_map: &'a LocalWithLocationMap, +} + +impl<'a, 'tcx, T> TransferFunction<'a, T> +where + T: GenKill, +{ + fn invalidate_local(&mut self, local_invalidated: Local, _location: Location) { + for x in self.local_with_location_map.local_with_locations(local_invalidated) { + debug!("Invalidating {:?} which corresponds to {:?}", x, local_invalidated); + self.available.kill(x); + } + } + + fn add_available(&mut self, local: Local, rvalue: Rvalue<'tcx>, location: Location) { + self.invalidate_local(local, location); + + // If rvalue is a move into the assigned local, then the local being moved should be invalidated + match rvalue { + Rvalue::Use(Operand::Move(moved)) => self.invalidate_local(moved.local, location), + _ => {} + } + + let all_participating_alive = + rvalue.participating_locals(location).all(|participating_local| { + self.local_with_location_map + .local_with_locations(participating_local) + .any(|participating_local_idx| self.available.is_alive(participating_local_idx)) + }); + if all_participating_alive { + let index = + self.local_with_location_map.local_with_specific_location(local, Some(location)); + debug!("Inserting {:?} which corresponds to {:?}", index, (local, Some(location))); + self.available.gen(index); + } + } +} + +impl<'a, 'tcx, T> Visitor<'tcx> for TransferFunction<'a, T> +where + T: GenKill, +{ + fn visit_assign( + &mut self, + assigned_place: &Place<'tcx>, + rvalue: &Rvalue<'tcx>, + location: Location, + ) { + if let Some(assigned_local) = assigned_place.as_local() { + let disallowed_place_opt = match rvalue { + Rvalue::Ref(_, BorrowKind::Mut { .. } | BorrowKind::Shallow, ref_of) => { + Some(ref_of) + } + Rvalue::AddressOf(_, ref_of) => Some(ref_of), + _ => None, + }; + + if let Some(disallowed_place) = disallowed_place_opt { + // It is difficult to reason about availability of mutable places or raw pointers, so throw out any + // availability information about the local taken a reference of. + debug!( + "Found disallowed reference of `{:?}`. Invalidating {:?} and {:?}", + disallowed_place, disallowed_place.local, assigned_local + ); + self.invalidate_local(disallowed_place.local, location); + self.invalidate_local(assigned_local, location) + } else { + self.add_available(assigned_local, rvalue.clone(), location); + } + } + + self.super_assign(assigned_place, rvalue, location); + } + + fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { + match statement.kind { + StatementKind::StorageDead(dead) => { + self.invalidate_local(dead, location); + } + _ => self.super_statement(statement, location), + } + } +} diff --git a/compiler/rustc_mir/src/dataflow/impls/mod.rs b/compiler/rustc_mir/src/dataflow/impls/mod.rs index 185f0edfeb6bc..d4c13dc932334 100644 --- a/compiler/rustc_mir/src/dataflow/impls/mod.rs +++ b/compiler/rustc_mir/src/dataflow/impls/mod.rs @@ -20,12 +20,14 @@ use super::on_lookup_result_bits; use crate::dataflow::drop_flag_effects; use crate::dataflow::framework::SwitchIntEdgeEffects; +mod available_locals; mod borrowed_locals; pub(super) mod borrows; mod init_locals; mod liveness; mod storage_liveness; +pub use self::available_locals::{AvailableLocals, LocalWithLocationIndex}; pub use self::borrowed_locals::{MaybeBorrowedLocals, MaybeMutBorrowedLocals}; pub use self::borrows::Borrows; pub use self::init_locals::MaybeInitializedLocals; diff --git a/compiler/rustc_mir/src/transform/instcombine.rs b/compiler/rustc_mir/src/transform/instcombine.rs index 59b7db2431900..4b198cfd0f78b 100644 --- a/compiler/rustc_mir/src/transform/instcombine.rs +++ b/compiler/rustc_mir/src/transform/instcombine.rs @@ -4,14 +4,10 @@ use crate::transform::MirPass; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::Mutability; use rustc_index::vec::Idx; +use rustc_middle::mir::visit::{MutVisitor, Visitor}; + use rustc_middle::mir::{ - visit::PlaceContext, - visit::{MutVisitor, Visitor}, - Statement, -}; -use rustc_middle::mir::{ - BinOp, Body, BorrowKind, Constant, Local, Location, Operand, Place, PlaceRef, ProjectionElem, - Rvalue, + BinOp, Body, Constant, Local, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, }; use rustc_middle::ty::{self, TyCtxt}; use std::mem; @@ -76,36 +72,10 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> { *rvalue = Rvalue::Use(operand); } - if let Some(place) = self.optimizations.unneeded_deref.remove(&location) { - debug!("unneeded_deref: replacing {:?} with {:?}", rvalue, place); - *rvalue = Rvalue::Use(Operand::Copy(place)); - } - self.super_rvalue(rvalue, location) } } -struct MutatingUseVisitor { - has_mutating_use: bool, - local_to_look_for: Local, -} - -impl MutatingUseVisitor { - fn has_mutating_use_in_stmt(local: Local, stmt: &Statement<'tcx>, location: Location) -> bool { - let mut _self = Self { has_mutating_use: false, local_to_look_for: local }; - _self.visit_statement(stmt, location); - _self.has_mutating_use - } -} - -impl<'tcx> Visitor<'tcx> for MutatingUseVisitor { - fn visit_local(&mut self, local: &Local, context: PlaceContext, _: Location) { - if *local == self.local_to_look_for { - self.has_mutating_use |= context.is_mutating_use(); - } - } -} - /// Finds optimization opportunities on the MIR. struct OptimizationFinder<'b, 'tcx> { body: &'b Body<'tcx>, @@ -118,103 +88,6 @@ impl OptimizationFinder<'b, 'tcx> { OptimizationFinder { body, tcx, optimizations: OptimizationList::default() } } - fn find_deref_of_address(&mut self, rvalue: &Rvalue<'tcx>, location: Location) -> Option<()> { - // FIXME(#78192): This optimization can result in unsoundness. - if !self.tcx.sess.opts.debugging_opts.unsound_mir_opts { - return None; - } - - // Look for the sequence - // - // _2 = &_1; - // ... - // _5 = (*_2); - // - // which we can replace the last statement with `_5 = _1;` to avoid the load of `_2`. - if let Rvalue::Use(op) = rvalue { - let local_being_derefed = match op.place()?.as_ref() { - PlaceRef { local, projection: [ProjectionElem::Deref] } => Some(local), - _ => None, - }?; - - let mut dead_locals_seen = vec![]; - - let stmt_index = location.statement_index; - // Look behind for statement that assigns the local from a address of operator. - // 6 is chosen as a heuristic determined by seeing the number of times - // the optimization kicked in compiling rust std. - let lower_index = stmt_index.saturating_sub(6); - let statements_to_look_in = self.body.basic_blocks()[location.block].statements - [lower_index..stmt_index] - .iter() - .rev(); - for stmt in statements_to_look_in { - match &stmt.kind { - // Exhaustive match on statements to detect conditions that warrant we bail out of the optimization. - rustc_middle::mir::StatementKind::Assign(box (l, r)) - if l.local == local_being_derefed => - { - match r { - // Looking for immutable reference e.g _local_being_deref = &_1; - Rvalue::Ref( - _, - // Only apply the optimization if it is an immutable borrow. - BorrowKind::Shared, - place_taken_address_of, - ) => { - // Make sure that the place has not been marked dead - if dead_locals_seen.contains(&place_taken_address_of.local) { - return None; - } - - self.optimizations - .unneeded_deref - .insert(location, *place_taken_address_of); - return Some(()); - } - - // We found an assignment of `local_being_deref` that is not an immutable ref, e.g the following sequence - // _2 = &_1; - // _3 = &5 - // _2 = _3; <-- this means it is no longer valid to replace the last statement with `_5 = _1;` - // _5 = (*_2); - _ => return None, - } - } - - // Inline asm can do anything, so bail out of the optimization. - rustc_middle::mir::StatementKind::LlvmInlineAsm(_) => return None, - - // Remember `StorageDead`s, as the local being marked dead could be the - // place RHS we are looking for, in which case we need to abort to avoid UB - // using an uninitialized place - rustc_middle::mir::StatementKind::StorageDead(dead) => { - dead_locals_seen.push(*dead) - } - - // Check that `local_being_deref` is not being used in a mutating way which can cause misoptimization. - rustc_middle::mir::StatementKind::Assign(box (_, _)) - | rustc_middle::mir::StatementKind::Coverage(_) - | rustc_middle::mir::StatementKind::Nop - | rustc_middle::mir::StatementKind::FakeRead(_, _) - | rustc_middle::mir::StatementKind::StorageLive(_) - | rustc_middle::mir::StatementKind::Retag(_, _) - | rustc_middle::mir::StatementKind::AscribeUserType(_, _) - | rustc_middle::mir::StatementKind::SetDiscriminant { .. } => { - if MutatingUseVisitor::has_mutating_use_in_stmt( - local_being_derefed, - stmt, - location, - ) { - return None; - } - } - } - } - } - Some(()) - } - fn find_unneeded_equality_comparison(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { // find Ne(_place, false) or Ne(false, _place) // or Eq(_place, true) or Eq(true, _place) @@ -281,8 +154,6 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> { } } - let _ = self.find_deref_of_address(rvalue, location); - self.find_unneeded_equality_comparison(rvalue, location); self.super_rvalue(rvalue, location) @@ -294,5 +165,4 @@ struct OptimizationList<'tcx> { and_stars: FxHashSet, arrays_lengths: FxHashMap>, unneeded_equality_comparison: FxHashMap>, - unneeded_deref: FxHashMap>, } diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs index e3fea2d2701e5..7f09b6d8bfa5d 100644 --- a/compiler/rustc_mir/src/transform/mod.rs +++ b/compiler/rustc_mir/src/transform/mod.rs @@ -46,6 +46,7 @@ pub mod simplify_branches; pub mod simplify_comparison_integral; pub mod simplify_try; pub mod uninhabited_enum_branching; +pub mod unneeded_deref; pub mod unreachable_prop; pub mod validate; @@ -395,6 +396,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // inst combine is after MatchBranchSimplification to clean up Ne(_1, false) &multiple_return_terminators::MultipleReturnTerminators, &instcombine::InstCombine, + &unneeded_deref::UnneededDeref, &const_prop::ConstProp, &simplify_branches::SimplifyBranches::new("after-const-prop"), &early_otherwise_branch::EarlyOtherwiseBranch, diff --git a/compiler/rustc_mir/src/transform/unneeded_deref.rs b/compiler/rustc_mir/src/transform/unneeded_deref.rs new file mode 100644 index 0000000000000..f631303aa11ce --- /dev/null +++ b/compiler/rustc_mir/src/transform/unneeded_deref.rs @@ -0,0 +1,183 @@ +use rustc_data_structures::fx::FxHashMap; +use rustc_index::bit_set::BitSet; +use rustc_middle::{ + mir::visit::Visitor, + mir::{ + visit::{MutVisitor, PlaceContext}, + Body, BorrowKind, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, Statement, + StatementKind, + }, + ty::TyCtxt, +}; + +use super::MirPass; +use crate::dataflow::Analysis; +use crate::dataflow::{ + impls::{AvailableLocals, LocalWithLocationIndex}, + lattice::Dual, + Results, ResultsVisitor, +}; + +/// Pass to find cases where a dereference of a reference can be avoided by +/// using the referenced value directly. +/// +/// Consider the following example: +/// ``` +/// _1 = 4; +/// _2 = &_1; +/// _3 = *_2 +/// ``` +/// +/// This is optimized into: +/// ``` +/// _1 = 4; +/// _2 = &_1; +/// _3 = _1 +/// ``` +/// +/// Later passes can then potentially remove `_2` as it is now unused. +pub struct UnneededDeref; + +impl<'tcx> MirPass<'tcx> for UnneededDeref { + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + let optimizations = UnneededDerefVisitor::go(body, tcx); + if !optimizations.is_empty() { + MutVisitor::visit_body(&mut ApplyOpts { optimizations, tcx }, body); + } + } +} + +struct UnneededDerefVisitor<'a, 'tcx> { + refs: FxHashMap>, + optimizations: &'a mut FxHashMap<(Location, Place<'tcx>), Place<'tcx>>, + results: &'a Results<'tcx, AvailableLocals>, + state: Option>>, +} + +impl<'a, 'tcx> Visitor<'tcx> for UnneededDerefVisitor<'a, 'tcx> { + fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) { + let analysis = &self.results.analysis; + let _: Option<_> = try { + debug!("Visiting place {:?}", place); + let state = self.state.as_ref()?; + + match place.as_ref() { + PlaceRef { projection: [ProjectionElem::Deref], .. } => { + debug!("Refs {:?}", self.refs); + let place_taken_ref_of = self.refs.get(&place.local)?; + let place_taken_ref_of_available = + analysis.is_available(place_taken_ref_of.local, state); + + debug!( + "{:?} has availability {:?}", + place_taken_ref_of.local, place_taken_ref_of_available + ); + if place_taken_ref_of_available { + let place_available = analysis.is_available(place.local, state); + debug!("{:?} has availability {:?}", place.local, place_available); + if place_available { + self.optimizations + .insert((location, place.clone()), place_taken_ref_of.clone()); + } + } + } + + _ => None?, + } + }; + self.super_place(place, context, location); + } +} + +impl<'a, 'tcx> UnneededDerefVisitor<'a, 'tcx> { + fn go( + body: &'a Body<'tcx>, + tcx: TyCtxt<'tcx>, + ) -> FxHashMap<(Location, Place<'tcx>), Place<'tcx>> { + let analysis = AvailableLocals::new(body); + + let mut ref_finder = RefFinder::new(); + ref_finder.visit_body(body); + let refs = ref_finder.refs; + let mut optimizations = FxHashMap::default(); + + // There is point in looking for derefs, if we haven't seen any refs + if refs.is_empty() { + return optimizations; + } + + let results = analysis.into_engine(tcx, body).iterate_to_fixpoint(); + + let mut _self = UnneededDerefVisitor { + refs, + optimizations: &mut optimizations, + results: &results, + state: None, + }; + + results.visit_reachable_with(body, &mut _self); + + optimizations + } +} + +impl<'a, 'tcx> ResultsVisitor<'a, 'tcx> for UnneededDerefVisitor<'a, 'tcx> { + type FlowState = Dual>; + fn visit_statement_before_primary_effect( + &mut self, + state: &Self::FlowState, + stmt: &'mir Statement<'tcx>, + location: Location, + ) { + self.state = Some(state.clone()); + let analysis = &self.results.analysis; + debug!("state: {:?} before statement {:?}", analysis.debug_state(state), stmt); + let _: Option<_> = try { + match &stmt.kind { + StatementKind::Assign(box (_, rvalue)) => match rvalue { + rvalue => self.visit_rvalue(rvalue, location), + }, + _ => {} + } + }; + } +} + +struct RefFinder<'tcx> { + refs: FxHashMap>, +} + +impl<'tcx> RefFinder<'tcx> { + fn new() -> Self { + Self { refs: FxHashMap::>::default() } + } +} + +impl<'tcx> Visitor<'tcx> for RefFinder<'tcx> { + fn visit_assign(&mut self, lhs: &Place<'tcx>, rvalue: &Rvalue<'tcx>, _: Location) { + match rvalue { + Rvalue::Ref(_, BorrowKind::Shared, place_taken_ref_of) => { + self.refs.insert(lhs.local, place_taken_ref_of.clone()); + } + _ => {} + } + } +} + +struct ApplyOpts<'tcx> { + optimizations: FxHashMap<(Location, Place<'tcx>), Place<'tcx>>, + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> MutVisitor<'tcx> for ApplyOpts<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn visit_place(&mut self, place: &mut Place<'tcx>, _context: PlaceContext, location: Location) { + if let Some(found_place) = self.optimizations.remove(&(location, *place)) { + debug!("unneeded_deref: replacing {:?} with {:?}", place, found_place); + *place = found_place; + } + } +} diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff index 812c7c9771801..7ec0751263fb1 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff @@ -19,7 +19,7 @@ // + span: $DIR/ref_deref_project.rs:5:6: 5:17 // + literal: Const { ty: &(i32, i32), val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0])) } _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17 - _1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17 + _1 = ((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17 StorageDead(_2); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 StorageDead(_1); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 _0 = const (); // scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2 diff --git a/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir index db504b416fe1d..4bda9ae383c22 100644 --- a/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir @@ -40,7 +40,7 @@ fn foo(_1: T, _2: &i32) -> i32 { _9 = move (_5.1: &i32); // scope 1 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 StorageLive(_10); // scope 2 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 _10 = _8; // scope 2 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 - _0 = (*_8); // scope 3 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 + _0 = (*_10); // scope 3 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 StorageDead(_10); // scope 2 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 StorageDead(_9); // scope 1 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 StorageDead(_8); // scope 1 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 diff --git a/src/test/mir-opt/inst_combine_deref.deep_opt.InstCombine.diff b/src/test/mir-opt/inst_combine_deref.deep_opt.InstCombine.diff deleted file mode 100644 index 1d20e17a8499b..0000000000000 --- a/src/test/mir-opt/inst_combine_deref.deep_opt.InstCombine.diff +++ /dev/null @@ -1,92 +0,0 @@ -- // MIR for `deep_opt` before InstCombine -+ // MIR for `deep_opt` after InstCombine - - fn deep_opt() -> (u64, u64, u64) { - let mut _0: (u64, u64, u64); // return place in scope 0 at $DIR/inst_combine_deref.rs:11:18: 11:33 - let _1: u64; // in scope 0 at $DIR/inst_combine_deref.rs:12:9: 12:11 - let mut _10: u64; // in scope 0 at $DIR/inst_combine_deref.rs:21:6: 21:8 - let mut _11: u64; // in scope 0 at $DIR/inst_combine_deref.rs:21:10: 21:12 - let mut _12: u64; // in scope 0 at $DIR/inst_combine_deref.rs:21:14: 21:16 - scope 1 { - debug x1 => _1; // in scope 1 at $DIR/inst_combine_deref.rs:12:9: 12:11 - let _2: u64; // in scope 1 at $DIR/inst_combine_deref.rs:13:9: 13:11 - scope 2 { - debug x2 => _2; // in scope 2 at $DIR/inst_combine_deref.rs:13:9: 13:11 - let _3: u64; // in scope 2 at $DIR/inst_combine_deref.rs:14:9: 14:11 - scope 3 { - debug x3 => _3; // in scope 3 at $DIR/inst_combine_deref.rs:14:9: 14:11 - let _4: &u64; // in scope 3 at $DIR/inst_combine_deref.rs:15:9: 15:11 - scope 4 { - debug y1 => _4; // in scope 4 at $DIR/inst_combine_deref.rs:15:9: 15:11 - let _5: &u64; // in scope 4 at $DIR/inst_combine_deref.rs:16:9: 16:11 - scope 5 { - debug y2 => _5; // in scope 5 at $DIR/inst_combine_deref.rs:16:9: 16:11 - let _6: &u64; // in scope 5 at $DIR/inst_combine_deref.rs:17:9: 17:11 - scope 6 { - debug y3 => _6; // in scope 6 at $DIR/inst_combine_deref.rs:17:9: 17:11 - let _7: u64; // in scope 6 at $DIR/inst_combine_deref.rs:18:9: 18:11 - scope 7 { - debug z1 => _7; // in scope 7 at $DIR/inst_combine_deref.rs:18:9: 18:11 - let _8: u64; // in scope 7 at $DIR/inst_combine_deref.rs:19:9: 19:11 - scope 8 { - debug z2 => _8; // in scope 8 at $DIR/inst_combine_deref.rs:19:9: 19:11 - let _9: u64; // in scope 8 at $DIR/inst_combine_deref.rs:20:9: 20:11 - scope 9 { - debug z3 => _9; // in scope 9 at $DIR/inst_combine_deref.rs:20:9: 20:11 - } - } - } - } - } - } - } - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/inst_combine_deref.rs:12:9: 12:11 - _1 = const 1_u64; // scope 0 at $DIR/inst_combine_deref.rs:12:14: 12:15 - StorageLive(_2); // scope 1 at $DIR/inst_combine_deref.rs:13:9: 13:11 - _2 = const 2_u64; // scope 1 at $DIR/inst_combine_deref.rs:13:14: 13:15 - StorageLive(_3); // scope 2 at $DIR/inst_combine_deref.rs:14:9: 14:11 - _3 = const 3_u64; // scope 2 at $DIR/inst_combine_deref.rs:14:14: 14:15 - StorageLive(_4); // scope 3 at $DIR/inst_combine_deref.rs:15:9: 15:11 - _4 = &_1; // scope 3 at $DIR/inst_combine_deref.rs:15:14: 15:17 - StorageLive(_5); // scope 4 at $DIR/inst_combine_deref.rs:16:9: 16:11 - _5 = &_2; // scope 4 at $DIR/inst_combine_deref.rs:16:14: 16:17 - StorageLive(_6); // scope 5 at $DIR/inst_combine_deref.rs:17:9: 17:11 - _6 = &_3; // scope 5 at $DIR/inst_combine_deref.rs:17:14: 17:17 - StorageLive(_7); // scope 6 at $DIR/inst_combine_deref.rs:18:9: 18:11 -- _7 = (*_4); // scope 6 at $DIR/inst_combine_deref.rs:18:14: 18:17 -+ _7 = _1; // scope 6 at $DIR/inst_combine_deref.rs:18:14: 18:17 - StorageLive(_8); // scope 7 at $DIR/inst_combine_deref.rs:19:9: 19:11 -- _8 = (*_5); // scope 7 at $DIR/inst_combine_deref.rs:19:14: 19:17 -+ _8 = _2; // scope 7 at $DIR/inst_combine_deref.rs:19:14: 19:17 - StorageLive(_9); // scope 8 at $DIR/inst_combine_deref.rs:20:9: 20:11 -- _9 = (*_6); // scope 8 at $DIR/inst_combine_deref.rs:20:14: 20:17 -+ _9 = _3; // scope 8 at $DIR/inst_combine_deref.rs:20:14: 20:17 - StorageLive(_10); // scope 9 at $DIR/inst_combine_deref.rs:21:6: 21:8 - _10 = _7; // scope 9 at $DIR/inst_combine_deref.rs:21:6: 21:8 - StorageLive(_11); // scope 9 at $DIR/inst_combine_deref.rs:21:10: 21:12 - _11 = _8; // scope 9 at $DIR/inst_combine_deref.rs:21:10: 21:12 - StorageLive(_12); // scope 9 at $DIR/inst_combine_deref.rs:21:14: 21:16 - _12 = _9; // scope 9 at $DIR/inst_combine_deref.rs:21:14: 21:16 - (_0.0: u64) = move _10; // scope 9 at $DIR/inst_combine_deref.rs:21:5: 21:17 - (_0.1: u64) = move _11; // scope 9 at $DIR/inst_combine_deref.rs:21:5: 21:17 - (_0.2: u64) = move _12; // scope 9 at $DIR/inst_combine_deref.rs:21:5: 21:17 - StorageDead(_12); // scope 9 at $DIR/inst_combine_deref.rs:21:16: 21:17 - StorageDead(_11); // scope 9 at $DIR/inst_combine_deref.rs:21:16: 21:17 - StorageDead(_10); // scope 9 at $DIR/inst_combine_deref.rs:21:16: 21:17 - StorageDead(_9); // scope 8 at $DIR/inst_combine_deref.rs:22:1: 22:2 - StorageDead(_8); // scope 7 at $DIR/inst_combine_deref.rs:22:1: 22:2 - StorageDead(_7); // scope 6 at $DIR/inst_combine_deref.rs:22:1: 22:2 - StorageDead(_6); // scope 5 at $DIR/inst_combine_deref.rs:22:1: 22:2 - StorageDead(_5); // scope 4 at $DIR/inst_combine_deref.rs:22:1: 22:2 - StorageDead(_4); // scope 3 at $DIR/inst_combine_deref.rs:22:1: 22:2 - StorageDead(_3); // scope 2 at $DIR/inst_combine_deref.rs:22:1: 22:2 - StorageDead(_2); // scope 1 at $DIR/inst_combine_deref.rs:22:1: 22:2 - StorageDead(_1); // scope 0 at $DIR/inst_combine_deref.rs:22:1: 22:2 - return; // scope 0 at $DIR/inst_combine_deref.rs:22:2: 22:2 - } - } - diff --git a/src/test/mir-opt/inst_combine_deref.do_not_miscompile.InstCombine.diff b/src/test/mir-opt/inst_combine_deref.do_not_miscompile.InstCombine.diff deleted file mode 100644 index 23c18bde2262b..0000000000000 --- a/src/test/mir-opt/inst_combine_deref.do_not_miscompile.InstCombine.diff +++ /dev/null @@ -1,85 +0,0 @@ -- // MIR for `do_not_miscompile` before InstCombine -+ // MIR for `do_not_miscompile` after InstCombine - - fn do_not_miscompile() -> () { - let mut _0: (); // return place in scope 0 at $DIR/inst_combine_deref.rs:54:24: 54:24 - let _1: i32; // in scope 0 at $DIR/inst_combine_deref.rs:55:9: 55:10 - let mut _5: &i32; // in scope 0 at $DIR/inst_combine_deref.rs:59:10: 59:12 - let _6: &i32; // in scope 0 at $DIR/inst_combine_deref.rs:59:10: 59:12 - let _7: (); // in scope 0 at $DIR/inst_combine_deref.rs:60:5: 60:23 - let mut _8: bool; // in scope 0 at $DIR/inst_combine_deref.rs:60:5: 60:23 - let mut _9: bool; // in scope 0 at $DIR/inst_combine_deref.rs:60:13: 60:21 - let mut _10: i32; // in scope 0 at $DIR/inst_combine_deref.rs:60:13: 60:15 - let mut _11: !; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - scope 1 { - debug x => _1; // in scope 1 at $DIR/inst_combine_deref.rs:55:9: 55:10 - let _2: i32; // in scope 1 at $DIR/inst_combine_deref.rs:56:9: 56:10 - scope 2 { - debug a => _2; // in scope 2 at $DIR/inst_combine_deref.rs:56:9: 56:10 - let mut _3: &i32; // in scope 2 at $DIR/inst_combine_deref.rs:57:9: 57:14 - scope 3 { - debug y => _3; // in scope 3 at $DIR/inst_combine_deref.rs:57:9: 57:14 - let _4: &mut &i32; // in scope 3 at $DIR/inst_combine_deref.rs:58:9: 58:10 - scope 4 { - debug z => _4; // in scope 4 at $DIR/inst_combine_deref.rs:58:9: 58:10 - } - } - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/inst_combine_deref.rs:55:9: 55:10 - _1 = const 42_i32; // scope 0 at $DIR/inst_combine_deref.rs:55:13: 55:15 - StorageLive(_2); // scope 1 at $DIR/inst_combine_deref.rs:56:9: 56:10 - _2 = const 99_i32; // scope 1 at $DIR/inst_combine_deref.rs:56:13: 56:15 - StorageLive(_3); // scope 2 at $DIR/inst_combine_deref.rs:57:9: 57:14 - _3 = &_1; // scope 2 at $DIR/inst_combine_deref.rs:57:17: 57:19 - StorageLive(_4); // scope 3 at $DIR/inst_combine_deref.rs:58:9: 58:10 - _4 = &mut _3; // scope 3 at $DIR/inst_combine_deref.rs:58:13: 58:19 - StorageLive(_5); // scope 4 at $DIR/inst_combine_deref.rs:59:10: 59:12 - StorageLive(_6); // scope 4 at $DIR/inst_combine_deref.rs:59:10: 59:12 - _6 = &_2; // scope 4 at $DIR/inst_combine_deref.rs:59:10: 59:12 -- _5 = &(*_6); // scope 4 at $DIR/inst_combine_deref.rs:59:10: 59:12 -+ _5 = _6; // scope 4 at $DIR/inst_combine_deref.rs:59:10: 59:12 - (*_4) = move _5; // scope 4 at $DIR/inst_combine_deref.rs:59:5: 59:12 - StorageDead(_5); // scope 4 at $DIR/inst_combine_deref.rs:59:11: 59:12 - StorageDead(_6); // scope 4 at $DIR/inst_combine_deref.rs:59:12: 59:13 - StorageLive(_7); // scope 4 at $DIR/inst_combine_deref.rs:60:5: 60:23 - StorageLive(_8); // scope 4 at $DIR/inst_combine_deref.rs:60:5: 60:23 - StorageLive(_9); // scope 4 at $DIR/inst_combine_deref.rs:60:13: 60:21 - StorageLive(_10); // scope 4 at $DIR/inst_combine_deref.rs:60:13: 60:15 - _10 = (*_3); // scope 4 at $DIR/inst_combine_deref.rs:60:13: 60:15 - _9 = Eq(move _10, const 99_i32); // scope 4 at $DIR/inst_combine_deref.rs:60:13: 60:21 - StorageDead(_10); // scope 4 at $DIR/inst_combine_deref.rs:60:20: 60:21 - _8 = Not(move _9); // scope 4 at $DIR/inst_combine_deref.rs:60:5: 60:23 - StorageDead(_9); // scope 4 at $DIR/inst_combine_deref.rs:60:22: 60:23 - switchInt(_8) -> [false: bb1, otherwise: bb2]; // scope 4 at $DIR/inst_combine_deref.rs:60:5: 60:23 - } - - bb1: { - _7 = const (); // scope 4 at $DIR/inst_combine_deref.rs:60:5: 60:23 - StorageDead(_8); // scope 4 at $DIR/inst_combine_deref.rs:60:22: 60:23 - StorageDead(_7); // scope 4 at $DIR/inst_combine_deref.rs:60:22: 60:23 - _0 = const (); // scope 0 at $DIR/inst_combine_deref.rs:54:24: 61:2 - StorageDead(_4); // scope 3 at $DIR/inst_combine_deref.rs:61:1: 61:2 - StorageDead(_3); // scope 2 at $DIR/inst_combine_deref.rs:61:1: 61:2 - StorageDead(_2); // scope 1 at $DIR/inst_combine_deref.rs:61:1: 61:2 - StorageDead(_1); // scope 0 at $DIR/inst_combine_deref.rs:61:1: 61:2 - return; // scope 0 at $DIR/inst_combine_deref.rs:61:2: 61:2 - } - - bb2: { - StorageLive(_11); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - begin_panic::<&str>(const "assertion failed: *y == 99"); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/std/src/macros.rs:LL:COL - // + literal: Const { ty: fn(&str) -> ! {std::rt::begin_panic::<&str>}, val: Value(Scalar()) } - // ty::Const - // + ty: &str - // + val: Value(Slice { data: Allocation { bytes: [97, 115, 115, 101, 114, 116, 105, 111, 110, 32, 102, 97, 105, 108, 101, 100, 58, 32, 42, 121, 32, 61, 61, 32, 57, 57], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [67108863], len: Size { raw: 26 } }, size: Size { raw: 26 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 26 }) - // mir::Constant - // + span: $DIR/inst_combine_deref.rs:1:1: 1:1 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [97, 115, 115, 101, 114, 116, 105, 111, 110, 32, 102, 97, 105, 108, 101, 100, 58, 32, 42, 121, 32, 61, 61, 32, 57, 57], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [67108863], len: Size { raw: 26 } }, size: Size { raw: 26 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 26 }) } - } - } - diff --git a/src/test/mir-opt/inst_combine_deref.dont_opt.InstCombine.diff b/src/test/mir-opt/inst_combine_deref.dont_opt.InstCombine.diff deleted file mode 100644 index 69036491a10b7..0000000000000 --- a/src/test/mir-opt/inst_combine_deref.dont_opt.InstCombine.diff +++ /dev/null @@ -1,53 +0,0 @@ -- // MIR for `dont_opt` before InstCombine -+ // MIR for `dont_opt` after InstCombine - - fn dont_opt() -> u64 { - let mut _0: u64; // return place in scope 0 at $DIR/inst_combine_deref.rs:43:18: 43:21 - let _1: i32; // in scope 0 at $DIR/inst_combine_deref.rs:44:9: 44:10 - let mut _5: &i32; // in scope 0 at $DIR/inst_combine_deref.rs:48:10: 48:14 - scope 1 { - debug y => _1; // in scope 1 at $DIR/inst_combine_deref.rs:44:9: 44:10 - let _2: &i32; // in scope 1 at $DIR/inst_combine_deref.rs:45:9: 45:13 - scope 2 { - debug _ref => _2; // in scope 2 at $DIR/inst_combine_deref.rs:45:9: 45:13 - let _3: i32; // in scope 2 at $DIR/inst_combine_deref.rs:46:9: 46:10 - scope 3 { - debug x => _3; // in scope 3 at $DIR/inst_combine_deref.rs:46:9: 46:10 - let mut _4: &i32; // in scope 3 at $DIR/inst_combine_deref.rs:47:9: 47:15 - scope 4 { - debug _1 => _4; // in scope 4 at $DIR/inst_combine_deref.rs:47:9: 47:15 - let _6: i32; // in scope 4 at $DIR/inst_combine_deref.rs:49:9: 49:11 - scope 5 { - debug _4 => _6; // in scope 5 at $DIR/inst_combine_deref.rs:49:9: 49:11 - } - } - } - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/inst_combine_deref.rs:44:9: 44:10 - _1 = const 5_i32; // scope 0 at $DIR/inst_combine_deref.rs:44:13: 44:14 - StorageLive(_2); // scope 1 at $DIR/inst_combine_deref.rs:45:9: 45:13 - _2 = &_1; // scope 1 at $DIR/inst_combine_deref.rs:45:16: 45:18 - StorageLive(_3); // scope 2 at $DIR/inst_combine_deref.rs:46:9: 46:10 - _3 = const 5_i32; // scope 2 at $DIR/inst_combine_deref.rs:46:13: 46:14 - StorageLive(_4); // scope 3 at $DIR/inst_combine_deref.rs:47:9: 47:15 - _4 = &_3; // scope 3 at $DIR/inst_combine_deref.rs:47:18: 47:20 - StorageLive(_5); // scope 4 at $DIR/inst_combine_deref.rs:48:10: 48:14 -- _5 = &(*_2); // scope 4 at $DIR/inst_combine_deref.rs:48:10: 48:14 -+ _5 = _2; // scope 4 at $DIR/inst_combine_deref.rs:48:10: 48:14 - _4 = move _5; // scope 4 at $DIR/inst_combine_deref.rs:48:5: 48:14 - StorageDead(_5); // scope 4 at $DIR/inst_combine_deref.rs:48:13: 48:14 - StorageLive(_6); // scope 4 at $DIR/inst_combine_deref.rs:49:9: 49:11 - _6 = (*_4); // scope 4 at $DIR/inst_combine_deref.rs:49:14: 49:17 - _0 = const 0_u64; // scope 5 at $DIR/inst_combine_deref.rs:50:5: 50:6 - StorageDead(_6); // scope 4 at $DIR/inst_combine_deref.rs:51:1: 51:2 - StorageDead(_4); // scope 3 at $DIR/inst_combine_deref.rs:51:1: 51:2 - StorageDead(_3); // scope 2 at $DIR/inst_combine_deref.rs:51:1: 51:2 - StorageDead(_2); // scope 1 at $DIR/inst_combine_deref.rs:51:1: 51:2 - StorageDead(_1); // scope 0 at $DIR/inst_combine_deref.rs:51:1: 51:2 - return; // scope 0 at $DIR/inst_combine_deref.rs:51:2: 51:2 - } - } - diff --git a/src/test/mir-opt/inst_combine_deref.opt_struct.InstCombine.diff b/src/test/mir-opt/inst_combine_deref.opt_struct.InstCombine.diff deleted file mode 100644 index c867543d05ea3..0000000000000 --- a/src/test/mir-opt/inst_combine_deref.opt_struct.InstCombine.diff +++ /dev/null @@ -1,44 +0,0 @@ -- // MIR for `opt_struct` before InstCombine -+ // MIR for `opt_struct` after InstCombine - - fn opt_struct(_1: S) -> u64 { - debug s => _1; // in scope 0 at $DIR/inst_combine_deref.rs:30:15: 30:16 - let mut _0: u64; // return place in scope 0 at $DIR/inst_combine_deref.rs:30:24: 30:27 - let _2: &u64; // in scope 0 at $DIR/inst_combine_deref.rs:31:9: 31:10 - let mut _5: u64; // in scope 0 at $DIR/inst_combine_deref.rs:34:5: 34:7 - let mut _6: u64; // in scope 0 at $DIR/inst_combine_deref.rs:34:10: 34:11 - scope 1 { - debug a => _2; // in scope 1 at $DIR/inst_combine_deref.rs:31:9: 31:10 - let _3: &u64; // in scope 1 at $DIR/inst_combine_deref.rs:32:9: 32:10 - scope 2 { - debug b => _3; // in scope 2 at $DIR/inst_combine_deref.rs:32:9: 32:10 - let _4: u64; // in scope 2 at $DIR/inst_combine_deref.rs:33:9: 33:10 - scope 3 { - debug x => _4; // in scope 3 at $DIR/inst_combine_deref.rs:33:9: 33:10 - } - } - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/inst_combine_deref.rs:31:9: 31:10 - _2 = &(_1.0: u64); // scope 0 at $DIR/inst_combine_deref.rs:31:13: 31:17 - StorageLive(_3); // scope 1 at $DIR/inst_combine_deref.rs:32:9: 32:10 - _3 = &(_1.1: u64); // scope 1 at $DIR/inst_combine_deref.rs:32:13: 32:17 - StorageLive(_4); // scope 2 at $DIR/inst_combine_deref.rs:33:9: 33:10 -- _4 = (*_2); // scope 2 at $DIR/inst_combine_deref.rs:33:13: 33:15 -+ _4 = (_1.0: u64); // scope 2 at $DIR/inst_combine_deref.rs:33:13: 33:15 - StorageLive(_5); // scope 3 at $DIR/inst_combine_deref.rs:34:5: 34:7 -- _5 = (*_3); // scope 3 at $DIR/inst_combine_deref.rs:34:5: 34:7 -+ _5 = (_1.1: u64); // scope 3 at $DIR/inst_combine_deref.rs:34:5: 34:7 - StorageLive(_6); // scope 3 at $DIR/inst_combine_deref.rs:34:10: 34:11 - _6 = _4; // scope 3 at $DIR/inst_combine_deref.rs:34:10: 34:11 - _0 = Add(move _5, move _6); // scope 3 at $DIR/inst_combine_deref.rs:34:5: 34:11 - StorageDead(_6); // scope 3 at $DIR/inst_combine_deref.rs:34:10: 34:11 - StorageDead(_5); // scope 3 at $DIR/inst_combine_deref.rs:34:10: 34:11 - StorageDead(_4); // scope 2 at $DIR/inst_combine_deref.rs:35:1: 35:2 - StorageDead(_3); // scope 1 at $DIR/inst_combine_deref.rs:35:1: 35:2 - StorageDead(_2); // scope 0 at $DIR/inst_combine_deref.rs:35:1: 35:2 - return; // scope 0 at $DIR/inst_combine_deref.rs:35:2: 35:2 - } - } - diff --git a/src/test/mir-opt/inst_combine_deref.rs b/src/test/mir-opt/inst_combine_deref.rs deleted file mode 100644 index 78361c336607c..0000000000000 --- a/src/test/mir-opt/inst_combine_deref.rs +++ /dev/null @@ -1,69 +0,0 @@ -// compile-flags: -O -Zunsound-mir-opts -// EMIT_MIR inst_combine_deref.simple_opt.InstCombine.diff -fn simple_opt() -> u64 { - let x = 5; - let y = &x; - let z = *y; - z -} - -// EMIT_MIR inst_combine_deref.deep_opt.InstCombine.diff -fn deep_opt() -> (u64, u64, u64) { - let x1 = 1; - let x2 = 2; - let x3 = 3; - let y1 = &x1; - let y2 = &x2; - let y3 = &x3; - let z1 = *y1; - let z2 = *y2; - let z3 = *y3; - (z1, z2, z3) -} - -struct S { - a: u64, - b: u64, -} - -// EMIT_MIR inst_combine_deref.opt_struct.InstCombine.diff -fn opt_struct(s: S) -> u64 { - let a = &s.a; - let b = &s.b; - let x = *a; - *b + x -} - -// EMIT_MIR inst_combine_deref.dont_opt.InstCombine.diff -// do not optimize a sequence looking like this: -// _1 = &_2; -// _1 = _3; -// _4 = *_1; -// as the _1 = _3 assignment makes it not legal to replace the last statement with _4 = _2 -fn dont_opt() -> u64 { - let y = 5; - let _ref = &y; - let x = 5; - let mut _1 = &x; - _1 = _ref; - let _4 = *_1; - 0 -} - -// EMIT_MIR inst_combine_deref.do_not_miscompile.InstCombine.diff -fn do_not_miscompile() { - let x = 42; - let a = 99; - let mut y = &x; - let z = &mut y; - *z = &a; - assert!(*y == 99); -} - -fn main() { - simple_opt(); - deep_opt(); - opt_struct(S { a: 0, b: 1 }); - dont_opt(); - do_not_miscompile(); -} diff --git a/src/test/mir-opt/inst_combine_deref.simple_opt.InstCombine.diff b/src/test/mir-opt/inst_combine_deref.simple_opt.InstCombine.diff deleted file mode 100644 index f52dfe379ca30..0000000000000 --- a/src/test/mir-opt/inst_combine_deref.simple_opt.InstCombine.diff +++ /dev/null @@ -1,34 +0,0 @@ -- // MIR for `simple_opt` before InstCombine -+ // MIR for `simple_opt` after InstCombine - - fn simple_opt() -> u64 { - let mut _0: u64; // return place in scope 0 at $DIR/inst_combine_deref.rs:3:20: 3:23 - let _1: u64; // in scope 0 at $DIR/inst_combine_deref.rs:4:9: 4:10 - scope 1 { - debug x => _1; // in scope 1 at $DIR/inst_combine_deref.rs:4:9: 4:10 - let _2: &u64; // in scope 1 at $DIR/inst_combine_deref.rs:5:9: 5:10 - scope 2 { - debug y => _2; // in scope 2 at $DIR/inst_combine_deref.rs:5:9: 5:10 - let _3: u64; // in scope 2 at $DIR/inst_combine_deref.rs:6:9: 6:10 - scope 3 { - debug z => _3; // in scope 3 at $DIR/inst_combine_deref.rs:6:9: 6:10 - } - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/inst_combine_deref.rs:4:9: 4:10 - _1 = const 5_u64; // scope 0 at $DIR/inst_combine_deref.rs:4:13: 4:14 - StorageLive(_2); // scope 1 at $DIR/inst_combine_deref.rs:5:9: 5:10 - _2 = &_1; // scope 1 at $DIR/inst_combine_deref.rs:5:13: 5:15 - StorageLive(_3); // scope 2 at $DIR/inst_combine_deref.rs:6:9: 6:10 -- _3 = (*_2); // scope 2 at $DIR/inst_combine_deref.rs:6:13: 6:15 -+ _3 = _1; // scope 2 at $DIR/inst_combine_deref.rs:6:13: 6:15 - _0 = _3; // scope 3 at $DIR/inst_combine_deref.rs:7:5: 7:6 - StorageDead(_3); // scope 2 at $DIR/inst_combine_deref.rs:8:1: 8:2 - StorageDead(_2); // scope 1 at $DIR/inst_combine_deref.rs:8:1: 8:2 - StorageDead(_1); // scope 0 at $DIR/inst_combine_deref.rs:8:1: 8:2 - return; // scope 0 at $DIR/inst_combine_deref.rs:8:2: 8:2 - } - } - diff --git a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff deleted file mode 100644 index 5048359e5c654..0000000000000 --- a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff +++ /dev/null @@ -1,13 +0,0 @@ -- // MIR for `bar` before InstrumentCoverage -+ // MIR for `bar` after InstrumentCoverage - - fn bar() -> bool { - let mut _0: bool; // return place in scope 0 at /the/src/instrument_coverage.rs:19:13: 19:17 - - bb0: { - _0 = const true; // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9 -+ Coverage::Counter(1) for /the/src/instrument_coverage.rs:20:5 - 21:2; // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2 - return; // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2 - } - } - diff --git a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff deleted file mode 100644 index c67d0e2ffe656..0000000000000 --- a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff +++ /dev/null @@ -1,51 +0,0 @@ -- // MIR for `main` before InstrumentCoverage -+ // MIR for `main` after InstrumentCoverage - - fn main() -> () { - let mut _0: (); // return place in scope 0 at /the/src/instrument_coverage.rs:10:11: 10:11 - let mut _1: (); // in scope 0 at /the/src/instrument_coverage.rs:10:1: 16:2 - let mut _2: bool; // in scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17 - let mut _3: !; // in scope 0 at /the/src/instrument_coverage.rs:12:18: 14:10 - - bb0: { - falseUnwind -> [real: bb1, cleanup: bb6]; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 - } - - bb1: { - StorageLive(_2); // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17 - _2 = bar() -> [return: bb2, unwind: bb6]; // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17 - // mir::Constant - // + span: /the/src/instrument_coverage.rs:12:12: 12:15 - // + literal: Const { ty: fn() -> bool {bar}, val: Value(Scalar()) } - } - - bb2: { - FakeRead(ForMatchedPlace, _2); // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17 -+ Coverage::Counter(1) for /the/src/instrument_coverage.rs:12:12 - 12:17; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 - switchInt(_2) -> [false: bb4, otherwise: bb3]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 - } - - bb3: { - falseEdge -> [real: bb5, imaginary: bb4]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 - } - - bb4: { - _1 = const (); // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 - StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6 -+ Coverage::Expression(4294967295) = 1 - 2 for /the/src/instrument_coverage.rs:15:6 - 15:7; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 - goto -> bb0; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 - } - - bb5: { - _0 = const (); // scope 0 at /the/src/instrument_coverage.rs:13:13: 13:18 - StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6 -+ Coverage::Counter(2) for /the/src/instrument_coverage.rs:13:13 - 13:18; // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2 -+ Coverage::Expression(4294967294) = 2 + 0 for /the/src/instrument_coverage.rs:16:1 - 16:2; // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2 - return; // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2 - } - - bb6 (cleanup): { - resume; // scope 0 at /the/src/instrument_coverage.rs:10:1: 16:2 - } - } - diff --git a/src/test/mir-opt/issue-78192.rs b/src/test/mir-opt/issue-78192.rs index 906d094f72b4a..b5a24ad54b7e1 100644 --- a/src/test/mir-opt/issue-78192.rs +++ b/src/test/mir-opt/issue-78192.rs @@ -1,4 +1,4 @@ -// EMIT_MIR issue_78192.f.InstCombine.diff +// EMIT_MIR issue_78192.f.UnneededDeref.diff pub fn f(a: &T) -> *const T { let b: &*const T = &(a as *const T); *b diff --git a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff index 499134b69919f..1175ced49eba4 100644 --- a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff @@ -86,15 +86,15 @@ _15 = &(*_2)[2 of 3]; // scope 1 at $DIR/issue_76432.rs:9:26: 9:32 StorageLive(_16); // scope 2 at $DIR/issue_76432.rs:9:38: 9:52 StorageLive(_17); // scope 2 at $DIR/issue_76432.rs:9:38: 9:52 - _17 = &raw const (*_13); // scope 2 at $DIR/issue_76432.rs:9:38: 9:40 + _17 = &raw const (*_2)[0 of 3]; // scope 2 at $DIR/issue_76432.rs:9:38: 9:40 _16 = _17; // scope 2 at $DIR/issue_76432.rs:9:38: 9:52 StorageLive(_18); // scope 2 at $DIR/issue_76432.rs:9:54: 9:68 StorageLive(_19); // scope 2 at $DIR/issue_76432.rs:9:54: 9:68 - _19 = &raw const (*_14); // scope 2 at $DIR/issue_76432.rs:9:54: 9:56 + _19 = &raw const (*_2)[1 of 3]; // scope 2 at $DIR/issue_76432.rs:9:54: 9:56 _18 = _19; // scope 2 at $DIR/issue_76432.rs:9:54: 9:68 StorageLive(_20); // scope 2 at $DIR/issue_76432.rs:9:70: 9:84 StorageLive(_21); // scope 2 at $DIR/issue_76432.rs:9:70: 9:84 - _21 = &raw const (*_15); // scope 2 at $DIR/issue_76432.rs:9:70: 9:72 + _21 = &raw const (*_2)[2 of 3]; // scope 2 at $DIR/issue_76432.rs:9:70: 9:72 _20 = _21; // scope 2 at $DIR/issue_76432.rs:9:70: 9:84 _9 = [move _16, move _18, move _20]; // scope 2 at $DIR/issue_76432.rs:9:37: 9:85 StorageDead(_21); // scope 2 at $DIR/issue_76432.rs:9:84: 9:85 diff --git a/src/test/mir-opt/issue_78192.f.InstCombine.diff b/src/test/mir-opt/issue_78192.f.UnneededDeref.diff similarity index 87% rename from src/test/mir-opt/issue_78192.f.InstCombine.diff rename to src/test/mir-opt/issue_78192.f.UnneededDeref.diff index ec3be78525802..0c1795f91290d 100644 --- a/src/test/mir-opt/issue_78192.f.InstCombine.diff +++ b/src/test/mir-opt/issue_78192.f.UnneededDeref.diff @@ -1,5 +1,5 @@ -- // MIR for `f` before InstCombine -+ // MIR for `f` after InstCombine +- // MIR for `f` before UnneededDeref ++ // MIR for `f` after UnneededDeref fn f(_1: &T) -> *const T { debug a => _1; // in scope 0 at $DIR/issue-78192.rs:2:13: 2:14 @@ -17,8 +17,7 @@ StorageLive(_4); // scope 0 at $DIR/issue-78192.rs:3:25: 3:40 _4 = &raw const (*_1); // scope 0 at $DIR/issue-78192.rs:3:26: 3:27 _3 = &_4; // scope 0 at $DIR/issue-78192.rs:3:24: 3:40 -- _2 = &(*_3); // scope 0 at $DIR/issue-78192.rs:3:24: 3:40 -+ _2 = _3; // scope 0 at $DIR/issue-78192.rs:3:24: 3:40 + _2 = _3; // scope 0 at $DIR/issue-78192.rs:3:24: 3:40 StorageDead(_3); // scope 0 at $DIR/issue-78192.rs:3:40: 3:41 _0 = (*_2); // scope 1 at $DIR/issue-78192.rs:4:5: 4:7 StorageDead(_4); // scope 0 at $DIR/issue-78192.rs:5:1: 5:2 diff --git a/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff b/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff deleted file mode 100644 index c3e503bf2c686..0000000000000 --- a/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff +++ /dev/null @@ -1,72 +0,0 @@ -- // MIR for `try_identity` before DestinationPropagation -+ // MIR for `try_identity` after DestinationPropagation - - fn try_identity(_1: std::result::Result) -> std::result::Result { - debug x => _1; // in scope 0 at $DIR/simplify_try.rs:6:17: 6:18 - let mut _0: std::result::Result; // return place in scope 0 at $DIR/simplify_try.rs:6:41: 6:57 - let _2: u32; // in scope 0 at $DIR/simplify_try.rs:7:9: 7:10 - let mut _3: std::result::Result; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15 - let mut _4: std::result::Result; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:14 - let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15 - let _6: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15 - let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15 - let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15 - let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15 - let _10: u32; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15 - let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:8:8: 8:9 - scope 1 { - debug y => _2; // in scope 1 at $DIR/simplify_try.rs:7:9: 7:10 - } - scope 2 { - debug err => _6; // in scope 2 at $DIR/simplify_try.rs:7:14: 7:15 - scope 3 { - scope 7 { - debug t => _9; // in scope 7 at $SRC_DIR/libcore/convert/mod.rs:LL:COL - } - scope 8 { - debug v => _8; // in scope 8 at $SRC_DIR/libcore/result.rs:LL:COL - let mut _12: i32; // in scope 8 at $DIR/simplify_try.rs:7:14: 7:15 - } - } - } - scope 4 { - debug val => _10; // in scope 4 at $DIR/simplify_try.rs:7:13: 7:15 - scope 5 { - } - } - scope 6 { -- debug self => _4; // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL -+ debug self => _0; // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:7:9: 7:10 -- StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:7:13: 7:15 -- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:7:13: 7:14 -- _4 = _1; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14 -- _3 = move _4; // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL -- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15 -- _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15 -+ nop; // scope 0 at $DIR/simplify_try.rs:7:13: 7:15 -+ nop; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14 -+ _0 = _1; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14 -+ nop; // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL -+ nop; // scope 0 at $DIR/simplify_try.rs:7:14: 7:15 -+ _5 = discriminant(_0); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15 - goto -> bb1; // scope 0 at $DIR/simplify_try.rs:7:14: 7:15 - } - - bb1: { -- _0 = move _3; // scope 1 at $DIR/simplify_try.rs:8:5: 8:10 -- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:7:15: 7:16 -+ nop; // scope 1 at $DIR/simplify_try.rs:8:5: 8:10 -+ nop; // scope 0 at $DIR/simplify_try.rs:7:15: 7:16 - StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:9:1: 9:2 - goto -> bb2; // scope 0 at $DIR/simplify_try.rs:9:2: 9:2 - } - - bb2: { - return; // scope 0 at $DIR/simplify_try.rs:9:2: 9:2 - } - } - diff --git a/src/test/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff deleted file mode 100644 index 11f6b5337414a..0000000000000 --- a/src/test/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff +++ /dev/null @@ -1,104 +0,0 @@ -- // MIR for `::append` before SimplifyArmIdentity -+ // MIR for `::append` after SimplifyArmIdentity - - fn ::append(_1: &mut LinkedList, _2: &mut LinkedList) -> () { - debug self => _1; // in scope 0 at $DIR/simplify_try_if_let.rs:20:19: 20:28 - debug other => _2; // in scope 0 at $DIR/simplify_try_if_let.rs:20:30: 20:35 - let mut _0: (); // return place in scope 0 at $DIR/simplify_try_if_let.rs:20:48: 20:48 - let mut _3: isize; // in scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17 - let mut _4: std::ptr::NonNull; // in scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26 - let mut _5: std::option::Option>; // in scope 0 at $DIR/simplify_try_if_let.rs:26:43: 26:60 - let mut _6: &mut std::option::Option>; // in scope 0 at $DIR/simplify_try_if_let.rs:26:43: 26:53 - let mut _7: isize; // in scope 0 at $DIR/simplify_try_if_let.rs:26:24: 26:40 - let mut _9: std::option::Option>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:46: 28:62 - let mut _10: std::ptr::NonNull; // in scope 0 at $DIR/simplify_try_if_let.rs:28:51: 28:61 - let mut _11: &mut Node; // in scope 0 at $DIR/simplify_try_if_let.rs:28:25: 28:38 - let mut _12: &mut std::ptr::NonNull; // in scope 0 at $DIR/simplify_try_if_let.rs:28:25: 28:29 - scope 1 { - debug tail => _4; // in scope 1 at $DIR/simplify_try_if_let.rs:23:18: 23:26 - let _8: std::ptr::NonNull; // in scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39 - scope 2 { -- debug other_head => _8; // in scope 2 at $DIR/simplify_try_if_let.rs:26:29: 26:39 -+ debug other_head => ((_9 as Some).0: std::ptr::NonNull); // in scope 2 at $DIR/simplify_try_if_let.rs:26:29: 26:39 - scope 3 { - } - } - } - - bb0: { - _3 = discriminant(((*_1).1: std::option::Option>)); // scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17 - switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17 - } - - bb1: { - StorageLive(_4); // scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26 - _4 = ((((*_1).1: std::option::Option>) as Some).0: std::ptr::NonNull); // scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26 - StorageLive(_5); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:60 - StorageLive(_6); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:53 - _6 = &mut ((*_2).0: std::option::Option>); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:53 - _5 = Option::>::take(move _6) -> bb4; // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:60 - // mir::Constant - // + span: $DIR/simplify_try_if_let.rs:26:54: 26:58 - // + literal: Const { ty: for<'r> fn(&'r mut std::option::Option>) -> std::option::Option> {std::option::Option::>::take}, val: Value(Scalar()) } - } - - bb2: { - unreachable; // scope 0 at $DIR/simplify_try_if_let.rs:21:15: 21:24 - } - - bb3: { - _0 = const (); // scope 0 at $DIR/simplify_try_if_let.rs:22:21: 22:24 - goto -> bb9; // scope 0 at $DIR/simplify_try_if_let.rs:21:9: 32:10 - } - - bb4: { - StorageDead(_6); // scope 1 at $DIR/simplify_try_if_let.rs:26:59: 26:60 - _7 = discriminant(_5); // scope 1 at $DIR/simplify_try_if_let.rs:26:24: 26:40 - switchInt(move _7) -> [1_isize: bb6, otherwise: bb5]; // scope 1 at $DIR/simplify_try_if_let.rs:26:24: 26:40 - } - - bb5: { - _0 = const (); // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18 - goto -> bb8; // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18 - } - - bb6: { - StorageLive(_8); // scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39 - _8 = ((_5 as Some).0: std::ptr::NonNull); // scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39 - StorageLive(_9); // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62 -- StorageLive(_10); // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61 -- _10 = _8; // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61 -- ((_9 as Some).0: std::ptr::NonNull) = move _10; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62 -- discriminant(_9) = 1; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62 -- StorageDead(_10); // scope 3 at $DIR/simplify_try_if_let.rs:28:61: 28:62 -+ _9 = move _5; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62 - StorageLive(_11); // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:38 - StorageLive(_12); // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:29 - _12 = &mut _4; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:29 - _11 = NonNull::::as_mut(move _12) -> bb7; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:38 - // mir::Constant - // + span: $DIR/simplify_try_if_let.rs:28:30: 28:36 - // + literal: Const { ty: for<'r> unsafe fn(&'r mut std::ptr::NonNull) -> &'r mut Node {std::ptr::NonNull::::as_mut}, val: Value(Scalar()) } - } - - bb7: { - StorageDead(_12); // scope 3 at $DIR/simplify_try_if_let.rs:28:37: 28:38 - ((*_11).0: std::option::Option>) = move _9; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:62 - StorageDead(_9); // scope 3 at $DIR/simplify_try_if_let.rs:28:61: 28:62 - StorageDead(_11); // scope 3 at $DIR/simplify_try_if_let.rs:28:62: 28:63 - _0 = const (); // scope 3 at $DIR/simplify_try_if_let.rs:27:21: 29:22 - StorageDead(_8); // scope 1 at $DIR/simplify_try_if_let.rs:30:17: 30:18 - goto -> bb8; // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18 - } - - bb8: { - StorageDead(_5); // scope 1 at $DIR/simplify_try_if_let.rs:31:13: 31:14 - StorageDead(_4); // scope 0 at $DIR/simplify_try_if_let.rs:31:13: 31:14 - goto -> bb9; // scope 0 at $DIR/simplify_try_if_let.rs:21:9: 32:10 - } - - bb9: { - return; // scope 0 at $DIR/simplify_try_if_let.rs:33:6: 33:6 - } - } - diff --git a/src/test/mir-opt/unneeded_deref.deep_opt.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.deep_opt.UnneededDeref.diff new file mode 100644 index 0000000000000..c4f8298795751 --- /dev/null +++ b/src/test/mir-opt/unneeded_deref.deep_opt.UnneededDeref.diff @@ -0,0 +1,92 @@ +- // MIR for `deep_opt` before UnneededDeref ++ // MIR for `deep_opt` after UnneededDeref + + fn deep_opt() -> (u64, u64, u64) { + let mut _0: (u64, u64, u64); // return place in scope 0 at $DIR/unneeded_deref.rs:11:18: 11:33 + let _1: u64; // in scope 0 at $DIR/unneeded_deref.rs:12:9: 12:11 + let mut _10: u64; // in scope 0 at $DIR/unneeded_deref.rs:21:6: 21:8 + let mut _11: u64; // in scope 0 at $DIR/unneeded_deref.rs:21:10: 21:12 + let mut _12: u64; // in scope 0 at $DIR/unneeded_deref.rs:21:14: 21:16 + scope 1 { + debug x1 => _1; // in scope 1 at $DIR/unneeded_deref.rs:12:9: 12:11 + let _2: u64; // in scope 1 at $DIR/unneeded_deref.rs:13:9: 13:11 + scope 2 { + debug x2 => _2; // in scope 2 at $DIR/unneeded_deref.rs:13:9: 13:11 + let _3: u64; // in scope 2 at $DIR/unneeded_deref.rs:14:9: 14:11 + scope 3 { + debug x3 => _3; // in scope 3 at $DIR/unneeded_deref.rs:14:9: 14:11 + let _4: &u64; // in scope 3 at $DIR/unneeded_deref.rs:15:9: 15:11 + scope 4 { + debug y1 => _4; // in scope 4 at $DIR/unneeded_deref.rs:15:9: 15:11 + let _5: &u64; // in scope 4 at $DIR/unneeded_deref.rs:16:9: 16:11 + scope 5 { + debug y2 => _5; // in scope 5 at $DIR/unneeded_deref.rs:16:9: 16:11 + let _6: &u64; // in scope 5 at $DIR/unneeded_deref.rs:17:9: 17:11 + scope 6 { + debug y3 => _6; // in scope 6 at $DIR/unneeded_deref.rs:17:9: 17:11 + let _7: u64; // in scope 6 at $DIR/unneeded_deref.rs:18:9: 18:11 + scope 7 { + debug z1 => _7; // in scope 7 at $DIR/unneeded_deref.rs:18:9: 18:11 + let _8: u64; // in scope 7 at $DIR/unneeded_deref.rs:19:9: 19:11 + scope 8 { + debug z2 => _8; // in scope 8 at $DIR/unneeded_deref.rs:19:9: 19:11 + let _9: u64; // in scope 8 at $DIR/unneeded_deref.rs:20:9: 20:11 + scope 9 { + debug z3 => _9; // in scope 9 at $DIR/unneeded_deref.rs:20:9: 20:11 + } + } + } + } + } + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/unneeded_deref.rs:12:9: 12:11 + _1 = const 1_u64; // scope 0 at $DIR/unneeded_deref.rs:12:14: 12:15 + StorageLive(_2); // scope 1 at $DIR/unneeded_deref.rs:13:9: 13:11 + _2 = const 2_u64; // scope 1 at $DIR/unneeded_deref.rs:13:14: 13:15 + StorageLive(_3); // scope 2 at $DIR/unneeded_deref.rs:14:9: 14:11 + _3 = const 3_u64; // scope 2 at $DIR/unneeded_deref.rs:14:14: 14:15 + StorageLive(_4); // scope 3 at $DIR/unneeded_deref.rs:15:9: 15:11 + _4 = &_1; // scope 3 at $DIR/unneeded_deref.rs:15:14: 15:17 + StorageLive(_5); // scope 4 at $DIR/unneeded_deref.rs:16:9: 16:11 + _5 = &_2; // scope 4 at $DIR/unneeded_deref.rs:16:14: 16:17 + StorageLive(_6); // scope 5 at $DIR/unneeded_deref.rs:17:9: 17:11 + _6 = &_3; // scope 5 at $DIR/unneeded_deref.rs:17:14: 17:17 + StorageLive(_7); // scope 6 at $DIR/unneeded_deref.rs:18:9: 18:11 +- _7 = (*_4); // scope 6 at $DIR/unneeded_deref.rs:18:14: 18:17 ++ _7 = _1; // scope 6 at $DIR/unneeded_deref.rs:18:14: 18:17 + StorageLive(_8); // scope 7 at $DIR/unneeded_deref.rs:19:9: 19:11 +- _8 = (*_5); // scope 7 at $DIR/unneeded_deref.rs:19:14: 19:17 ++ _8 = _2; // scope 7 at $DIR/unneeded_deref.rs:19:14: 19:17 + StorageLive(_9); // scope 8 at $DIR/unneeded_deref.rs:20:9: 20:11 +- _9 = (*_6); // scope 8 at $DIR/unneeded_deref.rs:20:14: 20:17 ++ _9 = _3; // scope 8 at $DIR/unneeded_deref.rs:20:14: 20:17 + StorageLive(_10); // scope 9 at $DIR/unneeded_deref.rs:21:6: 21:8 + _10 = _7; // scope 9 at $DIR/unneeded_deref.rs:21:6: 21:8 + StorageLive(_11); // scope 9 at $DIR/unneeded_deref.rs:21:10: 21:12 + _11 = _8; // scope 9 at $DIR/unneeded_deref.rs:21:10: 21:12 + StorageLive(_12); // scope 9 at $DIR/unneeded_deref.rs:21:14: 21:16 + _12 = _9; // scope 9 at $DIR/unneeded_deref.rs:21:14: 21:16 + (_0.0: u64) = move _10; // scope 9 at $DIR/unneeded_deref.rs:21:5: 21:17 + (_0.1: u64) = move _11; // scope 9 at $DIR/unneeded_deref.rs:21:5: 21:17 + (_0.2: u64) = move _12; // scope 9 at $DIR/unneeded_deref.rs:21:5: 21:17 + StorageDead(_12); // scope 9 at $DIR/unneeded_deref.rs:21:16: 21:17 + StorageDead(_11); // scope 9 at $DIR/unneeded_deref.rs:21:16: 21:17 + StorageDead(_10); // scope 9 at $DIR/unneeded_deref.rs:21:16: 21:17 + StorageDead(_9); // scope 8 at $DIR/unneeded_deref.rs:22:1: 22:2 + StorageDead(_8); // scope 7 at $DIR/unneeded_deref.rs:22:1: 22:2 + StorageDead(_7); // scope 6 at $DIR/unneeded_deref.rs:22:1: 22:2 + StorageDead(_6); // scope 5 at $DIR/unneeded_deref.rs:22:1: 22:2 + StorageDead(_5); // scope 4 at $DIR/unneeded_deref.rs:22:1: 22:2 + StorageDead(_4); // scope 3 at $DIR/unneeded_deref.rs:22:1: 22:2 + StorageDead(_3); // scope 2 at $DIR/unneeded_deref.rs:22:1: 22:2 + StorageDead(_2); // scope 1 at $DIR/unneeded_deref.rs:22:1: 22:2 + StorageDead(_1); // scope 0 at $DIR/unneeded_deref.rs:22:1: 22:2 + return; // scope 0 at $DIR/unneeded_deref.rs:22:2: 22:2 + } + } + diff --git a/src/test/mir-opt/unneeded_deref.do_not_miscompile.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.do_not_miscompile.UnneededDeref.diff new file mode 100644 index 0000000000000..61576bfeca37a --- /dev/null +++ b/src/test/mir-opt/unneeded_deref.do_not_miscompile.UnneededDeref.diff @@ -0,0 +1,84 @@ +- // MIR for `do_not_miscompile` before UnneededDeref ++ // MIR for `do_not_miscompile` after UnneededDeref + + fn do_not_miscompile() -> () { + let mut _0: (); // return place in scope 0 at $DIR/unneeded_deref.rs:54:24: 54:24 + let _1: i32; // in scope 0 at $DIR/unneeded_deref.rs:55:9: 55:10 + let mut _5: &i32; // in scope 0 at $DIR/unneeded_deref.rs:59:10: 59:12 + let _6: &i32; // in scope 0 at $DIR/unneeded_deref.rs:59:10: 59:12 + let _7: (); // in scope 0 at $DIR/unneeded_deref.rs:60:5: 60:23 + let mut _8: bool; // in scope 0 at $DIR/unneeded_deref.rs:60:5: 60:23 + let mut _9: bool; // in scope 0 at $DIR/unneeded_deref.rs:60:13: 60:21 + let mut _10: i32; // in scope 0 at $DIR/unneeded_deref.rs:60:13: 60:15 + let mut _11: !; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + scope 1 { + debug x => _1; // in scope 1 at $DIR/unneeded_deref.rs:55:9: 55:10 + let _2: i32; // in scope 1 at $DIR/unneeded_deref.rs:56:9: 56:10 + scope 2 { + debug a => _2; // in scope 2 at $DIR/unneeded_deref.rs:56:9: 56:10 + let mut _3: &i32; // in scope 2 at $DIR/unneeded_deref.rs:57:9: 57:14 + scope 3 { + debug y => _3; // in scope 3 at $DIR/unneeded_deref.rs:57:9: 57:14 + let _4: &mut &i32; // in scope 3 at $DIR/unneeded_deref.rs:58:9: 58:10 + scope 4 { + debug z => _4; // in scope 4 at $DIR/unneeded_deref.rs:58:9: 58:10 + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/unneeded_deref.rs:55:9: 55:10 + _1 = const 42_i32; // scope 0 at $DIR/unneeded_deref.rs:55:13: 55:15 + StorageLive(_2); // scope 1 at $DIR/unneeded_deref.rs:56:9: 56:10 + _2 = const 99_i32; // scope 1 at $DIR/unneeded_deref.rs:56:13: 56:15 + StorageLive(_3); // scope 2 at $DIR/unneeded_deref.rs:57:9: 57:14 + _3 = &_1; // scope 2 at $DIR/unneeded_deref.rs:57:17: 57:19 + StorageLive(_4); // scope 3 at $DIR/unneeded_deref.rs:58:9: 58:10 + _4 = &mut _3; // scope 3 at $DIR/unneeded_deref.rs:58:13: 58:19 + StorageLive(_5); // scope 4 at $DIR/unneeded_deref.rs:59:10: 59:12 + StorageLive(_6); // scope 4 at $DIR/unneeded_deref.rs:59:10: 59:12 + _6 = &_2; // scope 4 at $DIR/unneeded_deref.rs:59:10: 59:12 + _5 = _6; // scope 4 at $DIR/unneeded_deref.rs:59:10: 59:12 + (*_4) = move _5; // scope 4 at $DIR/unneeded_deref.rs:59:5: 59:12 + StorageDead(_5); // scope 4 at $DIR/unneeded_deref.rs:59:11: 59:12 + StorageDead(_6); // scope 4 at $DIR/unneeded_deref.rs:59:12: 59:13 + StorageLive(_7); // scope 4 at $DIR/unneeded_deref.rs:60:5: 60:23 + StorageLive(_8); // scope 4 at $DIR/unneeded_deref.rs:60:5: 60:23 + StorageLive(_9); // scope 4 at $DIR/unneeded_deref.rs:60:13: 60:21 + StorageLive(_10); // scope 4 at $DIR/unneeded_deref.rs:60:13: 60:15 + _10 = (*_3); // scope 4 at $DIR/unneeded_deref.rs:60:13: 60:15 + _9 = Eq(move _10, const 99_i32); // scope 4 at $DIR/unneeded_deref.rs:60:13: 60:21 + StorageDead(_10); // scope 4 at $DIR/unneeded_deref.rs:60:20: 60:21 + _8 = Not(move _9); // scope 4 at $DIR/unneeded_deref.rs:60:5: 60:23 + StorageDead(_9); // scope 4 at $DIR/unneeded_deref.rs:60:22: 60:23 + switchInt(_8) -> [false: bb1, otherwise: bb2]; // scope 4 at $DIR/unneeded_deref.rs:60:5: 60:23 + } + + bb1: { + _7 = const (); // scope 4 at $DIR/unneeded_deref.rs:60:5: 60:23 + StorageDead(_8); // scope 4 at $DIR/unneeded_deref.rs:60:22: 60:23 + StorageDead(_7); // scope 4 at $DIR/unneeded_deref.rs:60:22: 60:23 + _0 = const (); // scope 0 at $DIR/unneeded_deref.rs:54:24: 61:2 + StorageDead(_4); // scope 3 at $DIR/unneeded_deref.rs:61:1: 61:2 + StorageDead(_3); // scope 2 at $DIR/unneeded_deref.rs:61:1: 61:2 + StorageDead(_2); // scope 1 at $DIR/unneeded_deref.rs:61:1: 61:2 + StorageDead(_1); // scope 0 at $DIR/unneeded_deref.rs:61:1: 61:2 + return; // scope 0 at $DIR/unneeded_deref.rs:61:2: 61:2 + } + + bb2: { + StorageLive(_11); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + begin_panic::<&str>(const "assertion failed: *y == 99"); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/std/src/macros.rs:LL:COL + // + literal: Const { ty: fn(&str) -> ! {std::rt::begin_panic::<&str>}, val: Value(Scalar()) } + // ty::Const + // + ty: &str + // + val: Value(Slice { data: Allocation { bytes: [97, 115, 115, 101, 114, 116, 105, 111, 110, 32, 102, 97, 105, 108, 101, 100, 58, 32, 42, 121, 32, 61, 61, 32, 57, 57], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [67108863], len: Size { raw: 26 } }, size: Size { raw: 26 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 26 }) + // mir::Constant + // + span: $DIR/unneeded_deref.rs:1:1: 1:1 + // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [97, 115, 115, 101, 114, 116, 105, 111, 110, 32, 102, 97, 105, 108, 101, 100, 58, 32, 42, 121, 32, 61, 61, 32, 57, 57], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [67108863], len: Size { raw: 26 } }, size: Size { raw: 26 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 26 }) } + } + } + diff --git a/src/test/mir-opt/unneeded_deref.do_not_miscompile_mut_ref.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.do_not_miscompile_mut_ref.UnneededDeref.diff new file mode 100644 index 0000000000000..f740736247c41 --- /dev/null +++ b/src/test/mir-opt/unneeded_deref.do_not_miscompile_mut_ref.UnneededDeref.diff @@ -0,0 +1,70 @@ +- // MIR for `do_not_miscompile_mut_ref` before UnneededDeref ++ // MIR for `do_not_miscompile_mut_ref` after UnneededDeref + + fn do_not_miscompile_mut_ref() -> () { + let mut _0: (); // return place in scope 0 at $DIR/unneeded_deref.rs:65:32: 65:32 + let _1: u32; // in scope 0 at $DIR/unneeded_deref.rs:66:9: 66:10 + let _4: &u32; // in scope 0 at $DIR/unneeded_deref.rs:69:29: 69:31 + let _6: &u32; // in scope 0 at $DIR/unneeded_deref.rs:70:19: 70:21 + let mut _8: *const u32; // in scope 0 at $DIR/unneeded_deref.rs:73:9: 73:10 + scope 1 { + debug a => _1; // in scope 1 at $DIR/unneeded_deref.rs:66:9: 66:10 + let _2: u32; // in scope 1 at $DIR/unneeded_deref.rs:67:9: 67:10 + scope 2 { + debug b => _2; // in scope 2 at $DIR/unneeded_deref.rs:67:9: 67:10 + let mut _3: *const u32; // in scope 2 at $DIR/unneeded_deref.rs:69:9: 69:14 + scope 3 { + debug c => _3; // in scope 3 at $DIR/unneeded_deref.rs:69:9: 69:14 + let _5: &u32; // in scope 3 at $DIR/unneeded_deref.rs:70:9: 70:10 + scope 4 { + debug d => _5; // in scope 4 at $DIR/unneeded_deref.rs:70:9: 70:10 + let _7: &u32; // in scope 4 at $DIR/unneeded_deref.rs:72:9: 72:10 + scope 5 { + debug x => _7; // in scope 5 at $DIR/unneeded_deref.rs:72:9: 72:10 + let _9: u32; // in scope 5 at $DIR/unneeded_deref.rs:74:9: 74:10 + scope 7 { + debug z => _9; // in scope 7 at $DIR/unneeded_deref.rs:74:9: 74:10 + } + } + scope 6 { + } + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/unneeded_deref.rs:66:9: 66:10 + _1 = const 1_u32; // scope 0 at $DIR/unneeded_deref.rs:66:13: 66:17 + StorageLive(_2); // scope 1 at $DIR/unneeded_deref.rs:67:9: 67:10 + _2 = const 2_u32; // scope 1 at $DIR/unneeded_deref.rs:67:13: 67:17 + StorageLive(_3); // scope 2 at $DIR/unneeded_deref.rs:69:9: 69:14 + StorageLive(_4); // scope 2 at $DIR/unneeded_deref.rs:69:29: 69:31 + _4 = &_1; // scope 2 at $DIR/unneeded_deref.rs:69:29: 69:31 +- _3 = &raw const (*_4); // scope 2 at $DIR/unneeded_deref.rs:69:29: 69:31 ++ _3 = &raw const _1; // scope 2 at $DIR/unneeded_deref.rs:69:29: 69:31 + StorageDead(_4); // scope 2 at $DIR/unneeded_deref.rs:69:31: 69:32 + StorageLive(_5); // scope 3 at $DIR/unneeded_deref.rs:70:9: 70:10 + StorageLive(_6); // scope 3 at $DIR/unneeded_deref.rs:70:19: 70:21 + _6 = &_2; // scope 3 at $DIR/unneeded_deref.rs:70:19: 70:21 + _5 = _6; // scope 3 at $DIR/unneeded_deref.rs:70:19: 70:21 + StorageDead(_6); // scope 3 at $DIR/unneeded_deref.rs:70:21: 70:22 + StorageLive(_7); // scope 4 at $DIR/unneeded_deref.rs:72:9: 72:10 + _7 = &(*_3); // scope 6 at $DIR/unneeded_deref.rs:72:22: 72:25 + StorageLive(_8); // scope 5 at $DIR/unneeded_deref.rs:73:9: 73:10 + _8 = &raw const (*_5); // scope 5 at $DIR/unneeded_deref.rs:73:9: 73:10 + _3 = move _8; // scope 5 at $DIR/unneeded_deref.rs:73:5: 73:10 + StorageDead(_8); // scope 5 at $DIR/unneeded_deref.rs:73:9: 73:10 + StorageLive(_9); // scope 5 at $DIR/unneeded_deref.rs:74:9: 74:10 + _9 = (*_7); // scope 5 at $DIR/unneeded_deref.rs:74:13: 74:15 + _0 = const (); // scope 0 at $DIR/unneeded_deref.rs:65:32: 75:2 + StorageDead(_9); // scope 5 at $DIR/unneeded_deref.rs:75:1: 75:2 + StorageDead(_7); // scope 4 at $DIR/unneeded_deref.rs:75:1: 75:2 + StorageDead(_5); // scope 3 at $DIR/unneeded_deref.rs:75:1: 75:2 + StorageDead(_3); // scope 2 at $DIR/unneeded_deref.rs:75:1: 75:2 + StorageDead(_2); // scope 1 at $DIR/unneeded_deref.rs:75:1: 75:2 + StorageDead(_1); // scope 0 at $DIR/unneeded_deref.rs:75:1: 75:2 + return; // scope 0 at $DIR/unneeded_deref.rs:75:2: 75:2 + } + } + diff --git a/src/test/mir-opt/unneeded_deref.do_not_opt_different_bbs.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.do_not_opt_different_bbs.UnneededDeref.diff new file mode 100644 index 0000000000000..e605567785301 --- /dev/null +++ b/src/test/mir-opt/unneeded_deref.do_not_opt_different_bbs.UnneededDeref.diff @@ -0,0 +1,64 @@ +- // MIR for `do_not_opt_different_bbs` before UnneededDeref ++ // MIR for `do_not_opt_different_bbs` after UnneededDeref + + fn do_not_opt_different_bbs(_1: bool) -> u64 { + debug input => _1; // in scope 0 at $DIR/unneeded_deref.rs:134:29: 134:34 + let mut _0: u64; // return place in scope 0 at $DIR/unneeded_deref.rs:134:45: 134:48 + let _2: u64; // in scope 0 at $DIR/unneeded_deref.rs:135:9: 135:10 + let mut _4: bool; // in scope 0 at $DIR/unneeded_deref.rs:136:16: 136:21 + let _5: &u64; // in scope 0 at $DIR/unneeded_deref.rs:136:36: 136:39 + let _6: u64; // in scope 0 at $DIR/unneeded_deref.rs:136:37: 136:39 + scope 1 { + debug x => _2; // in scope 1 at $DIR/unneeded_deref.rs:135:9: 135:10 + let _3: &u64; // in scope 1 at $DIR/unneeded_deref.rs:136:9: 136:10 + let mut _8: &u64; // in scope 1 at $DIR/unneeded_deref.rs:136:36: 136:39 + scope 2 { + debug y => _3; // in scope 2 at $DIR/unneeded_deref.rs:136:9: 136:10 + let _7: u64; // in scope 2 at $DIR/unneeded_deref.rs:137:9: 137:10 + scope 3 { + debug z => _7; // in scope 3 at $DIR/unneeded_deref.rs:137:9: 137:10 + } + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/unneeded_deref.rs:135:9: 135:10 + _2 = const 5_u64; // scope 0 at $DIR/unneeded_deref.rs:135:13: 135:14 + StorageLive(_3); // scope 1 at $DIR/unneeded_deref.rs:136:9: 136:10 + StorageLive(_4); // scope 1 at $DIR/unneeded_deref.rs:136:16: 136:21 + _4 = _1; // scope 1 at $DIR/unneeded_deref.rs:136:16: 136:21 + switchInt(_4) -> [false: bb1, otherwise: bb2]; // scope 1 at $DIR/unneeded_deref.rs:136:13: 136:41 + } + + bb1: { + StorageLive(_5); // scope 1 at $DIR/unneeded_deref.rs:136:36: 136:39 + _8 = const do_not_opt_different_bbs::promoted[0]; // scope 1 at $DIR/unneeded_deref.rs:136:36: 136:39 + // ty::Const + // + ty: &u64 + // + val: Unevaluated(WithOptConstParam { did: DefId(0:17 ~ unneeded_deref[317d]::do_not_opt_different_bbs), const_param_did: None }, [], Some(promoted[0])) + // mir::Constant + // + span: $DIR/unneeded_deref.rs:136:36: 136:39 + // + literal: Const { ty: &u64, val: Unevaluated(WithOptConstParam { did: DefId(0:17 ~ unneeded_deref[317d]::do_not_opt_different_bbs), const_param_did: None }, [], Some(promoted[0])) } + _5 = _8; // scope 1 at $DIR/unneeded_deref.rs:136:36: 136:39 + _3 = _5; // scope 1 at $DIR/unneeded_deref.rs:136:36: 136:39 + StorageDead(_5); // scope 1 at $DIR/unneeded_deref.rs:136:40: 136:41 + goto -> bb3; // scope 1 at $DIR/unneeded_deref.rs:136:13: 136:41 + } + + bb2: { + _3 = &_2; // scope 1 at $DIR/unneeded_deref.rs:136:24: 136:26 + goto -> bb3; // scope 1 at $DIR/unneeded_deref.rs:136:13: 136:41 + } + + bb3: { + StorageDead(_4); // scope 1 at $DIR/unneeded_deref.rs:136:41: 136:42 + StorageLive(_7); // scope 2 at $DIR/unneeded_deref.rs:137:9: 137:10 + _7 = (*_3); // scope 2 at $DIR/unneeded_deref.rs:137:13: 137:15 + _0 = _7; // scope 3 at $DIR/unneeded_deref.rs:138:5: 138:6 + StorageDead(_7); // scope 2 at $DIR/unneeded_deref.rs:139:1: 139:2 + StorageDead(_3); // scope 1 at $DIR/unneeded_deref.rs:139:1: 139:2 + StorageDead(_2); // scope 0 at $DIR/unneeded_deref.rs:139:1: 139:2 + return; // scope 0 at $DIR/unneeded_deref.rs:139:2: 139:2 + } + } + diff --git a/src/test/mir-opt/unneeded_deref.do_not_use_moved.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.do_not_use_moved.UnneededDeref.diff new file mode 100644 index 0000000000000..1ece5aca01beb --- /dev/null +++ b/src/test/mir-opt/unneeded_deref.do_not_use_moved.UnneededDeref.diff @@ -0,0 +1,35 @@ +- // MIR for `do_not_use_moved` before UnneededDeref ++ // MIR for `do_not_use_moved` after UnneededDeref + + fn do_not_use_moved(_1: T) -> () { + debug x => _1; // in scope 0 at $DIR/unneeded_deref.rs:110:24: 110:25 + let mut _0: (); // return place in scope 0 at $DIR/unneeded_deref.rs:110:30: 110:30 + let _2: T; // in scope 0 at $DIR/unneeded_deref.rs:111:9: 111:10 + scope 1 { + debug b => _2; // in scope 1 at $DIR/unneeded_deref.rs:111:9: 111:10 + let _3: &T; // in scope 1 at $DIR/unneeded_deref.rs:112:9: 112:10 + scope 2 { + debug z => _3; // in scope 2 at $DIR/unneeded_deref.rs:112:9: 112:10 + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/unneeded_deref.rs:111:9: 111:10 + _2 = move _1; // scope 0 at $DIR/unneeded_deref.rs:111:13: 111:14 + StorageLive(_3); // scope 1 at $DIR/unneeded_deref.rs:112:9: 112:10 + _3 = &_2; // scope 1 at $DIR/unneeded_deref.rs:112:13: 112:15 + _0 = const (); // scope 0 at $DIR/unneeded_deref.rs:110:30: 113:2 + StorageDead(_3); // scope 1 at $DIR/unneeded_deref.rs:113:1: 113:2 + drop(_2) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/unneeded_deref.rs:113:1: 113:2 + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/unneeded_deref.rs:113:1: 113:2 + return; // scope 0 at $DIR/unneeded_deref.rs:113:2: 113:2 + } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/unneeded_deref.rs:110:1: 113:2 + } + } + diff --git a/src/test/mir-opt/unneeded_deref.dont_opt.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.dont_opt.UnneededDeref.diff new file mode 100644 index 0000000000000..5e63e68a2800b --- /dev/null +++ b/src/test/mir-opt/unneeded_deref.dont_opt.UnneededDeref.diff @@ -0,0 +1,52 @@ +- // MIR for `dont_opt` before UnneededDeref ++ // MIR for `dont_opt` after UnneededDeref + + fn dont_opt() -> u64 { + let mut _0: u64; // return place in scope 0 at $DIR/unneeded_deref.rs:43:18: 43:21 + let _1: i32; // in scope 0 at $DIR/unneeded_deref.rs:44:9: 44:10 + let mut _5: &i32; // in scope 0 at $DIR/unneeded_deref.rs:48:10: 48:14 + scope 1 { + debug y => _1; // in scope 1 at $DIR/unneeded_deref.rs:44:9: 44:10 + let _2: &i32; // in scope 1 at $DIR/unneeded_deref.rs:45:9: 45:13 + scope 2 { + debug _ref => _2; // in scope 2 at $DIR/unneeded_deref.rs:45:9: 45:13 + let _3: i32; // in scope 2 at $DIR/unneeded_deref.rs:46:9: 46:10 + scope 3 { + debug x => _3; // in scope 3 at $DIR/unneeded_deref.rs:46:9: 46:10 + let mut _4: &i32; // in scope 3 at $DIR/unneeded_deref.rs:47:9: 47:15 + scope 4 { + debug _1 => _4; // in scope 4 at $DIR/unneeded_deref.rs:47:9: 47:15 + let _6: i32; // in scope 4 at $DIR/unneeded_deref.rs:49:9: 49:11 + scope 5 { + debug _4 => _6; // in scope 5 at $DIR/unneeded_deref.rs:49:9: 49:11 + } + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/unneeded_deref.rs:44:9: 44:10 + _1 = const 5_i32; // scope 0 at $DIR/unneeded_deref.rs:44:13: 44:14 + StorageLive(_2); // scope 1 at $DIR/unneeded_deref.rs:45:9: 45:13 + _2 = &_1; // scope 1 at $DIR/unneeded_deref.rs:45:16: 45:18 + StorageLive(_3); // scope 2 at $DIR/unneeded_deref.rs:46:9: 46:10 + _3 = const 5_i32; // scope 2 at $DIR/unneeded_deref.rs:46:13: 46:14 + StorageLive(_4); // scope 3 at $DIR/unneeded_deref.rs:47:9: 47:15 + _4 = &_3; // scope 3 at $DIR/unneeded_deref.rs:47:18: 47:20 + StorageLive(_5); // scope 4 at $DIR/unneeded_deref.rs:48:10: 48:14 + _5 = _2; // scope 4 at $DIR/unneeded_deref.rs:48:10: 48:14 + _4 = move _5; // scope 4 at $DIR/unneeded_deref.rs:48:5: 48:14 + StorageDead(_5); // scope 4 at $DIR/unneeded_deref.rs:48:13: 48:14 + StorageLive(_6); // scope 4 at $DIR/unneeded_deref.rs:49:9: 49:11 + _6 = (*_4); // scope 4 at $DIR/unneeded_deref.rs:49:14: 49:17 + _0 = const 0_u64; // scope 5 at $DIR/unneeded_deref.rs:50:5: 50:6 + StorageDead(_6); // scope 4 at $DIR/unneeded_deref.rs:51:1: 51:2 + StorageDead(_4); // scope 3 at $DIR/unneeded_deref.rs:51:1: 51:2 + StorageDead(_3); // scope 2 at $DIR/unneeded_deref.rs:51:1: 51:2 + StorageDead(_2); // scope 1 at $DIR/unneeded_deref.rs:51:1: 51:2 + StorageDead(_1); // scope 0 at $DIR/unneeded_deref.rs:51:1: 51:2 + return; // scope 0 at $DIR/unneeded_deref.rs:51:2: 51:2 + } + } + diff --git a/src/test/mir-opt/unneeded_deref.operand_opt.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.operand_opt.UnneededDeref.diff new file mode 100644 index 0000000000000..f0632406c7787 --- /dev/null +++ b/src/test/mir-opt/unneeded_deref.operand_opt.UnneededDeref.diff @@ -0,0 +1,71 @@ +- // MIR for `operand_opt` before UnneededDeref ++ // MIR for `operand_opt` after UnneededDeref + + fn operand_opt(_1: Option) -> bool { + debug input => _1; // in scope 0 at $DIR/unneeded_deref.rs:142:25: 142:30 + let mut _0: bool; // return place in scope 0 at $DIR/unneeded_deref.rs:142:46: 142:50 + let _2: bool; // in scope 0 at $DIR/unneeded_deref.rs:143:9: 143:10 + let mut _3: &std::option::Option; // in scope 0 at $DIR/unneeded_deref.rs:143:13: 143:18 + let mut _5: &std::option::Option; // in scope 0 at $DIR/unneeded_deref.rs:144:13: 144:18 + let mut _6: bool; // in scope 0 at $DIR/unneeded_deref.rs:145:5: 145:6 + let mut _7: bool; // in scope 0 at $DIR/unneeded_deref.rs:145:10: 145:11 + let mut _10: isize; // in scope 0 at $DIR/unneeded_deref.rs:143:13: 143:28 + let mut _11: isize; // in scope 0 at $DIR/unneeded_deref.rs:144:13: 144:28 + scope 1 { + debug x => _2; // in scope 1 at $DIR/unneeded_deref.rs:143:9: 143:10 + let _4: bool; // in scope 1 at $DIR/unneeded_deref.rs:144:9: 144:10 + scope 2 { + debug y => _4; // in scope 2 at $DIR/unneeded_deref.rs:144:9: 144:10 + } + scope 4 (inlined Option::::is_some) { // at $DIR/unneeded_deref.rs:144:13: 144:28 + debug self => _5; // in scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 + let mut _9: isize; // in scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 + } + } + scope 3 (inlined Option::::is_some) { // at $DIR/unneeded_deref.rs:143:13: 143:28 + debug self => _3; // in scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 + let mut _8: isize; // in scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/unneeded_deref.rs:143:9: 143:10 + StorageLive(_3); // scope 0 at $DIR/unneeded_deref.rs:143:13: 143:18 + _3 = &_1; // scope 0 at $DIR/unneeded_deref.rs:143:13: 143:18 +- _8 = discriminant((*_3)); // scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 ++ _8 = discriminant(_1); // scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 + StorageLive(_10); // scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 + _10 = move _8; // scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 + _2 = Eq(_10, const 1_isize); // scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 + StorageDead(_10); // scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 + goto -> bb1; // scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 + } + + bb1: { + StorageDead(_3); // scope 0 at $DIR/unneeded_deref.rs:143:27: 143:28 + StorageLive(_4); // scope 1 at $DIR/unneeded_deref.rs:144:9: 144:10 + StorageLive(_5); // scope 1 at $DIR/unneeded_deref.rs:144:13: 144:18 + _5 = &_1; // scope 1 at $DIR/unneeded_deref.rs:144:13: 144:18 +- _9 = discriminant((*_5)); // scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 ++ _9 = discriminant(_1); // scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 + StorageLive(_11); // scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 + _11 = move _9; // scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 + _4 = Eq(_11, const 1_isize); // scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 + StorageDead(_11); // scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 + goto -> bb2; // scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 + } + + bb2: { + StorageDead(_5); // scope 1 at $DIR/unneeded_deref.rs:144:27: 144:28 + StorageLive(_6); // scope 2 at $DIR/unneeded_deref.rs:145:5: 145:6 + _6 = _2; // scope 2 at $DIR/unneeded_deref.rs:145:5: 145:6 + StorageLive(_7); // scope 2 at $DIR/unneeded_deref.rs:145:10: 145:11 + _7 = _4; // scope 2 at $DIR/unneeded_deref.rs:145:10: 145:11 + _0 = Eq(move _6, move _7); // scope 2 at $DIR/unneeded_deref.rs:145:5: 145:11 + StorageDead(_7); // scope 2 at $DIR/unneeded_deref.rs:145:10: 145:11 + StorageDead(_6); // scope 2 at $DIR/unneeded_deref.rs:145:10: 145:11 + StorageDead(_4); // scope 1 at $DIR/unneeded_deref.rs:146:1: 146:2 + StorageDead(_2); // scope 0 at $DIR/unneeded_deref.rs:146:1: 146:2 + return; // scope 0 at $DIR/unneeded_deref.rs:146:2: 146:2 + } + } + diff --git a/src/test/mir-opt/unneeded_deref.opt_different_bbs.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.opt_different_bbs.UnneededDeref.diff new file mode 100644 index 0000000000000..6142bc9acea14 --- /dev/null +++ b/src/test/mir-opt/unneeded_deref.opt_different_bbs.UnneededDeref.diff @@ -0,0 +1,58 @@ +- // MIR for `opt_different_bbs` before UnneededDeref ++ // MIR for `opt_different_bbs` after UnneededDeref + + fn opt_different_bbs(_1: bool) -> u64 { + debug input => _1; // in scope 0 at $DIR/unneeded_deref.rs:116:22: 116:27 + let mut _0: u64; // return place in scope 0 at $DIR/unneeded_deref.rs:116:38: 116:41 + let _2: u64; // in scope 0 at $DIR/unneeded_deref.rs:117:9: 117:10 + let mut _4: i32; // in scope 0 at $DIR/unneeded_deref.rs:119:13: 119:38 + let mut _5: bool; // in scope 0 at $DIR/unneeded_deref.rs:119:16: 119:21 + scope 1 { + debug x => _2; // in scope 1 at $DIR/unneeded_deref.rs:117:9: 117:10 + let _3: &u64; // in scope 1 at $DIR/unneeded_deref.rs:118:9: 118:10 + scope 2 { + debug y => _3; // in scope 2 at $DIR/unneeded_deref.rs:118:9: 118:10 + scope 3 { + let _6: u64; // in scope 3 at $DIR/unneeded_deref.rs:120:9: 120:10 + scope 4 { + debug z => _6; // in scope 4 at $DIR/unneeded_deref.rs:120:9: 120:10 + } + } + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/unneeded_deref.rs:117:9: 117:10 + _2 = const 5_u64; // scope 0 at $DIR/unneeded_deref.rs:117:13: 117:14 + StorageLive(_3); // scope 1 at $DIR/unneeded_deref.rs:118:9: 118:10 + _3 = &_2; // scope 1 at $DIR/unneeded_deref.rs:118:13: 118:15 + StorageLive(_4); // scope 2 at $DIR/unneeded_deref.rs:119:13: 119:38 + StorageLive(_5); // scope 2 at $DIR/unneeded_deref.rs:119:16: 119:21 + _5 = _1; // scope 2 at $DIR/unneeded_deref.rs:119:16: 119:21 + switchInt(_5) -> [false: bb1, otherwise: bb2]; // scope 2 at $DIR/unneeded_deref.rs:119:13: 119:38 + } + + bb1: { + _4 = const 3_i32; // scope 2 at $DIR/unneeded_deref.rs:119:35: 119:36 + goto -> bb3; // scope 2 at $DIR/unneeded_deref.rs:119:13: 119:38 + } + + bb2: { + _4 = const 2_i32; // scope 2 at $DIR/unneeded_deref.rs:119:24: 119:25 + goto -> bb3; // scope 2 at $DIR/unneeded_deref.rs:119:13: 119:38 + } + + bb3: { + StorageDead(_5); // scope 2 at $DIR/unneeded_deref.rs:119:38: 119:39 + StorageDead(_4); // scope 2 at $DIR/unneeded_deref.rs:119:38: 119:39 + StorageLive(_6); // scope 3 at $DIR/unneeded_deref.rs:120:9: 120:10 +- _6 = (*_3); // scope 3 at $DIR/unneeded_deref.rs:120:13: 120:15 ++ _6 = _2; // scope 3 at $DIR/unneeded_deref.rs:120:13: 120:15 + _0 = _6; // scope 4 at $DIR/unneeded_deref.rs:121:5: 121:6 + StorageDead(_6); // scope 3 at $DIR/unneeded_deref.rs:122:1: 122:2 + StorageDead(_3); // scope 1 at $DIR/unneeded_deref.rs:122:1: 122:2 + StorageDead(_2); // scope 0 at $DIR/unneeded_deref.rs:122:1: 122:2 + return; // scope 0 at $DIR/unneeded_deref.rs:122:2: 122:2 + } + } + diff --git a/src/test/mir-opt/unneeded_deref.opt_different_bbs2.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.opt_different_bbs2.UnneededDeref.diff new file mode 100644 index 0000000000000..d274ae0fa4008 --- /dev/null +++ b/src/test/mir-opt/unneeded_deref.opt_different_bbs2.UnneededDeref.diff @@ -0,0 +1,52 @@ +- // MIR for `opt_different_bbs2` before UnneededDeref ++ // MIR for `opt_different_bbs2` after UnneededDeref + + fn opt_different_bbs2(_1: bool) -> u64 { + debug input => _1; // in scope 0 at $DIR/unneeded_deref.rs:125:23: 125:28 + let mut _0: u64; // return place in scope 0 at $DIR/unneeded_deref.rs:125:39: 125:42 + let _2: u64; // in scope 0 at $DIR/unneeded_deref.rs:126:9: 126:10 + let mut _5: bool; // in scope 0 at $DIR/unneeded_deref.rs:128:16: 128:21 + scope 1 { + debug x => _2; // in scope 1 at $DIR/unneeded_deref.rs:126:9: 126:10 + let _3: &u64; // in scope 1 at $DIR/unneeded_deref.rs:127:9: 127:10 + scope 2 { + debug y => _3; // in scope 2 at $DIR/unneeded_deref.rs:127:9: 127:10 + let _4: u64; // in scope 2 at $DIR/unneeded_deref.rs:128:9: 128:10 + scope 3 { + debug z => _4; // in scope 3 at $DIR/unneeded_deref.rs:128:9: 128:10 + } + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/unneeded_deref.rs:126:9: 126:10 + _2 = const 5_u64; // scope 0 at $DIR/unneeded_deref.rs:126:13: 126:14 + StorageLive(_3); // scope 1 at $DIR/unneeded_deref.rs:127:9: 127:10 + _3 = &_2; // scope 1 at $DIR/unneeded_deref.rs:127:13: 127:15 + StorageLive(_4); // scope 2 at $DIR/unneeded_deref.rs:128:9: 128:10 + StorageLive(_5); // scope 2 at $DIR/unneeded_deref.rs:128:16: 128:21 + _5 = _1; // scope 2 at $DIR/unneeded_deref.rs:128:16: 128:21 + switchInt(_5) -> [false: bb1, otherwise: bb2]; // scope 2 at $DIR/unneeded_deref.rs:128:13: 128:39 + } + + bb1: { + _4 = const 3_u64; // scope 2 at $DIR/unneeded_deref.rs:128:36: 128:37 + goto -> bb3; // scope 2 at $DIR/unneeded_deref.rs:128:13: 128:39 + } + + bb2: { +- _4 = (*_3); // scope 2 at $DIR/unneeded_deref.rs:128:24: 128:26 ++ _4 = _2; // scope 2 at $DIR/unneeded_deref.rs:128:24: 128:26 + goto -> bb3; // scope 2 at $DIR/unneeded_deref.rs:128:13: 128:39 + } + + bb3: { + StorageDead(_5); // scope 2 at $DIR/unneeded_deref.rs:128:39: 128:40 + _0 = _4; // scope 3 at $DIR/unneeded_deref.rs:129:5: 129:6 + StorageDead(_4); // scope 2 at $DIR/unneeded_deref.rs:130:1: 130:2 + StorageDead(_3); // scope 1 at $DIR/unneeded_deref.rs:130:1: 130:2 + StorageDead(_2); // scope 0 at $DIR/unneeded_deref.rs:130:1: 130:2 + return; // scope 0 at $DIR/unneeded_deref.rs:130:2: 130:2 + } + } + diff --git a/src/test/mir-opt/unneeded_deref.opt_struct.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.opt_struct.UnneededDeref.diff new file mode 100644 index 0000000000000..078ac8e0ab268 --- /dev/null +++ b/src/test/mir-opt/unneeded_deref.opt_struct.UnneededDeref.diff @@ -0,0 +1,44 @@ +- // MIR for `opt_struct` before UnneededDeref ++ // MIR for `opt_struct` after UnneededDeref + + fn opt_struct(_1: S) -> u64 { + debug s => _1; // in scope 0 at $DIR/unneeded_deref.rs:30:15: 30:16 + let mut _0: u64; // return place in scope 0 at $DIR/unneeded_deref.rs:30:24: 30:27 + let _2: &u64; // in scope 0 at $DIR/unneeded_deref.rs:31:9: 31:10 + let mut _5: u64; // in scope 0 at $DIR/unneeded_deref.rs:34:5: 34:7 + let mut _6: u64; // in scope 0 at $DIR/unneeded_deref.rs:34:10: 34:11 + scope 1 { + debug a => _2; // in scope 1 at $DIR/unneeded_deref.rs:31:9: 31:10 + let _3: &u64; // in scope 1 at $DIR/unneeded_deref.rs:32:9: 32:10 + scope 2 { + debug b => _3; // in scope 2 at $DIR/unneeded_deref.rs:32:9: 32:10 + let _4: u64; // in scope 2 at $DIR/unneeded_deref.rs:33:9: 33:10 + scope 3 { + debug x => _4; // in scope 3 at $DIR/unneeded_deref.rs:33:9: 33:10 + } + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/unneeded_deref.rs:31:9: 31:10 + _2 = &(_1.0: u64); // scope 0 at $DIR/unneeded_deref.rs:31:13: 31:17 + StorageLive(_3); // scope 1 at $DIR/unneeded_deref.rs:32:9: 32:10 + _3 = &(_1.1: u64); // scope 1 at $DIR/unneeded_deref.rs:32:13: 32:17 + StorageLive(_4); // scope 2 at $DIR/unneeded_deref.rs:33:9: 33:10 +- _4 = (*_2); // scope 2 at $DIR/unneeded_deref.rs:33:13: 33:15 ++ _4 = (_1.0: u64); // scope 2 at $DIR/unneeded_deref.rs:33:13: 33:15 + StorageLive(_5); // scope 3 at $DIR/unneeded_deref.rs:34:5: 34:7 +- _5 = (*_3); // scope 3 at $DIR/unneeded_deref.rs:34:5: 34:7 ++ _5 = (_1.1: u64); // scope 3 at $DIR/unneeded_deref.rs:34:5: 34:7 + StorageLive(_6); // scope 3 at $DIR/unneeded_deref.rs:34:10: 34:11 + _6 = _4; // scope 3 at $DIR/unneeded_deref.rs:34:10: 34:11 + _0 = Add(move _5, move _6); // scope 3 at $DIR/unneeded_deref.rs:34:5: 34:11 + StorageDead(_6); // scope 3 at $DIR/unneeded_deref.rs:34:10: 34:11 + StorageDead(_5); // scope 3 at $DIR/unneeded_deref.rs:34:10: 34:11 + StorageDead(_4); // scope 2 at $DIR/unneeded_deref.rs:35:1: 35:2 + StorageDead(_3); // scope 1 at $DIR/unneeded_deref.rs:35:1: 35:2 + StorageDead(_2); // scope 0 at $DIR/unneeded_deref.rs:35:1: 35:2 + return; // scope 0 at $DIR/unneeded_deref.rs:35:2: 35:2 + } + } + diff --git a/src/test/mir-opt/unneeded_deref.rs b/src/test/mir-opt/unneeded_deref.rs new file mode 100644 index 0000000000000..7de50d86f8483 --- /dev/null +++ b/src/test/mir-opt/unneeded_deref.rs @@ -0,0 +1,161 @@ +// compile-flags: -O -Zunsound-mir-opts +// EMIT_MIR unneeded_deref.simple_opt.UnneededDeref.diff +fn simple_opt() -> u64 { + let x = 5; + let y = &x; + let z = *y; + z +} + +// EMIT_MIR unneeded_deref.deep_opt.UnneededDeref.diff +fn deep_opt() -> (u64, u64, u64) { + let x1 = 1; + let x2 = 2; + let x3 = 3; + let y1 = &x1; + let y2 = &x2; + let y3 = &x3; + let z1 = *y1; + let z2 = *y2; + let z3 = *y3; + (z1, z2, z3) +} + +struct S { + a: u64, + b: u64, +} + +// EMIT_MIR unneeded_deref.opt_struct.UnneededDeref.diff +fn opt_struct(s: S) -> u64 { + let a = &s.a; + let b = &s.b; + let x = *a; + *b + x +} + +// EMIT_MIR unneeded_deref.dont_opt.UnneededDeref.diff +// do not optimize a sequence looking like this: +// _1 = &_2; +// _1 = _3; +// _4 = *_1; +// as the _1 = _3 assignment makes it not legal to replace the last statement with _4 = _2 +fn dont_opt() -> u64 { + let y = 5; + let _ref = &y; + let x = 5; + let mut _1 = &x; + _1 = _ref; + let _4 = *_1; + 0 +} + +// EMIT_MIR unneeded_deref.do_not_miscompile.UnneededDeref.diff +fn do_not_miscompile() { + let x = 42; + let a = 99; + let mut y = &x; + let z = &mut y; + *z = &a; + assert!(*y == 99); +} + +// EMIT_MIR unneeded_deref.do_not_miscompile_mut_ref.UnneededDeref.diff +// See #78192 +fn do_not_miscompile_mut_ref() { + let a = 1u32; + let b = 2u32; + + let mut c: *const u32 = &a; + let d: &u32 = &b; + + let x = unsafe { &*c }; + c = d; + let z = *x; +} + +// EMIT_MIR unneeded_deref.very_deep_opt.UnneededDeref.diff +fn very_deep_opt() -> (u64, u64, u64, u64, u64, u64, u64, u64, u64) { + let x1 = 1; + let x2 = 2; + let x3 = 3; + let x4 = 4; + let x5 = 5; + let x6 = 6; + let x7 = 7; + let x8 = 8; + let x9 = 9; + let y1 = &x1; + let y2 = &x2; + let y3 = &x3; + let y4 = &x4; + let y5 = &x5; + let y6 = &x6; + let y7 = &x7; + let y8 = &x8; + let y9 = &x9; + let z1 = *y1; + let z2 = *y2; + let z3 = *y3; + let z4 = *y4; + let z5 = *y5; + let z6 = *y6; + let z7 = *y7; + let z8 = *y8; + let z9 = *y9; + (z1, z2, z3, z4, z5, z6, z7, z8, z9) +} + +// EMIT_MIR unneeded_deref.do_not_use_moved.UnneededDeref.diff +fn do_not_use_moved(x: T) { + let b = x; + let z = &b; +} + +// EMIT_MIR unneeded_deref.opt_different_bbs.UnneededDeref.diff +fn opt_different_bbs(input: bool) -> u64 { + let x = 5; + let y = &x; + let _ = if input { 2 } else { 3 }; + let z = *y; + z +} + +// EMIT_MIR unneeded_deref.opt_different_bbs2.UnneededDeref.diff +fn opt_different_bbs2(input: bool) -> u64 { + let x = 5; + let y = &x; + let z = if input { *y } else { 3 }; + z +} + +// EMIT_MIR unneeded_deref.do_not_opt_different_bbs.UnneededDeref.diff +// We cannot know whether z should be 5 or 33 +fn do_not_opt_different_bbs(input: bool) -> u64 { + let x = 5; + let y = if input { &x } else { &33 }; + let z = *y; + z +} + +// EMIT_MIR unneeded_deref.operand_opt.UnneededDeref.diff +fn operand_opt(input: Option) -> bool { + let x = input.is_some(); + let y = input.is_some(); + x == y +} + +fn main() { + simple_opt(); + deep_opt(); + opt_struct(S { a: 0, b: 1 }); + dont_opt(); + do_not_miscompile(); + do_not_miscompile_mut_ref(); + very_deep_opt(); + do_not_use_moved(String::new()); + opt_different_bbs(false); + opt_different_bbs2(false); + do_not_opt_different_bbs(false); + operand_opt(Some(true)); +} diff --git a/src/test/mir-opt/unneeded_deref.simple_opt.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.simple_opt.UnneededDeref.diff new file mode 100644 index 0000000000000..eb91889dde87f --- /dev/null +++ b/src/test/mir-opt/unneeded_deref.simple_opt.UnneededDeref.diff @@ -0,0 +1,34 @@ +- // MIR for `simple_opt` before UnneededDeref ++ // MIR for `simple_opt` after UnneededDeref + + fn simple_opt() -> u64 { + let mut _0: u64; // return place in scope 0 at $DIR/unneeded_deref.rs:3:20: 3:23 + let _1: u64; // in scope 0 at $DIR/unneeded_deref.rs:4:9: 4:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/unneeded_deref.rs:4:9: 4:10 + let _2: &u64; // in scope 1 at $DIR/unneeded_deref.rs:5:9: 5:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/unneeded_deref.rs:5:9: 5:10 + let _3: u64; // in scope 2 at $DIR/unneeded_deref.rs:6:9: 6:10 + scope 3 { + debug z => _3; // in scope 3 at $DIR/unneeded_deref.rs:6:9: 6:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/unneeded_deref.rs:4:9: 4:10 + _1 = const 5_u64; // scope 0 at $DIR/unneeded_deref.rs:4:13: 4:14 + StorageLive(_2); // scope 1 at $DIR/unneeded_deref.rs:5:9: 5:10 + _2 = &_1; // scope 1 at $DIR/unneeded_deref.rs:5:13: 5:15 + StorageLive(_3); // scope 2 at $DIR/unneeded_deref.rs:6:9: 6:10 +- _3 = (*_2); // scope 2 at $DIR/unneeded_deref.rs:6:13: 6:15 ++ _3 = _1; // scope 2 at $DIR/unneeded_deref.rs:6:13: 6:15 + _0 = _3; // scope 3 at $DIR/unneeded_deref.rs:7:5: 7:6 + StorageDead(_3); // scope 2 at $DIR/unneeded_deref.rs:8:1: 8:2 + StorageDead(_2); // scope 1 at $DIR/unneeded_deref.rs:8:1: 8:2 + StorageDead(_1); // scope 0 at $DIR/unneeded_deref.rs:8:1: 8:2 + return; // scope 0 at $DIR/unneeded_deref.rs:8:2: 8:2 + } + } + diff --git a/src/test/mir-opt/unneeded_deref.very_deep_opt.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.very_deep_opt.UnneededDeref.diff new file mode 100644 index 0000000000000..48750c8dbe1ba --- /dev/null +++ b/src/test/mir-opt/unneeded_deref.very_deep_opt.UnneededDeref.diff @@ -0,0 +1,254 @@ +- // MIR for `very_deep_opt` before UnneededDeref ++ // MIR for `very_deep_opt` after UnneededDeref + + fn very_deep_opt() -> (u64, u64, u64, u64, u64, u64, u64, u64, u64) { + let mut _0: (u64, u64, u64, u64, u64, u64, u64, u64, u64); // return place in scope 0 at $DIR/unneeded_deref.rs:78:23: 78:68 + let _1: u64; // in scope 0 at $DIR/unneeded_deref.rs:79:9: 79:11 + let mut _28: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:6: 106:8 + let mut _29: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:10: 106:12 + let mut _30: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:14: 106:16 + let mut _31: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:18: 106:20 + let mut _32: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:22: 106:24 + let mut _33: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:26: 106:28 + let mut _34: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:30: 106:32 + let mut _35: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:34: 106:36 + let mut _36: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:38: 106:40 + scope 1 { + debug x1 => _1; // in scope 1 at $DIR/unneeded_deref.rs:79:9: 79:11 + let _2: u64; // in scope 1 at $DIR/unneeded_deref.rs:80:9: 80:11 + scope 2 { + debug x2 => _2; // in scope 2 at $DIR/unneeded_deref.rs:80:9: 80:11 + let _3: u64; // in scope 2 at $DIR/unneeded_deref.rs:81:9: 81:11 + scope 3 { + debug x3 => _3; // in scope 3 at $DIR/unneeded_deref.rs:81:9: 81:11 + let _4: u64; // in scope 3 at $DIR/unneeded_deref.rs:82:9: 82:11 + scope 4 { + debug x4 => _4; // in scope 4 at $DIR/unneeded_deref.rs:82:9: 82:11 + let _5: u64; // in scope 4 at $DIR/unneeded_deref.rs:83:9: 83:11 + scope 5 { + debug x5 => _5; // in scope 5 at $DIR/unneeded_deref.rs:83:9: 83:11 + let _6: u64; // in scope 5 at $DIR/unneeded_deref.rs:84:9: 84:11 + scope 6 { + debug x6 => _6; // in scope 6 at $DIR/unneeded_deref.rs:84:9: 84:11 + let _7: u64; // in scope 6 at $DIR/unneeded_deref.rs:85:9: 85:11 + scope 7 { + debug x7 => _7; // in scope 7 at $DIR/unneeded_deref.rs:85:9: 85:11 + let _8: u64; // in scope 7 at $DIR/unneeded_deref.rs:86:9: 86:11 + scope 8 { + debug x8 => _8; // in scope 8 at $DIR/unneeded_deref.rs:86:9: 86:11 + let _9: u64; // in scope 8 at $DIR/unneeded_deref.rs:87:9: 87:11 + scope 9 { + debug x9 => _9; // in scope 9 at $DIR/unneeded_deref.rs:87:9: 87:11 + let _10: &u64; // in scope 9 at $DIR/unneeded_deref.rs:88:9: 88:11 + scope 10 { + debug y1 => _10; // in scope 10 at $DIR/unneeded_deref.rs:88:9: 88:11 + let _11: &u64; // in scope 10 at $DIR/unneeded_deref.rs:89:9: 89:11 + scope 11 { + debug y2 => _11; // in scope 11 at $DIR/unneeded_deref.rs:89:9: 89:11 + let _12: &u64; // in scope 11 at $DIR/unneeded_deref.rs:90:9: 90:11 + scope 12 { + debug y3 => _12; // in scope 12 at $DIR/unneeded_deref.rs:90:9: 90:11 + let _13: &u64; // in scope 12 at $DIR/unneeded_deref.rs:91:9: 91:11 + scope 13 { + debug y4 => _13; // in scope 13 at $DIR/unneeded_deref.rs:91:9: 91:11 + let _14: &u64; // in scope 13 at $DIR/unneeded_deref.rs:92:9: 92:11 + scope 14 { + debug y5 => _14; // in scope 14 at $DIR/unneeded_deref.rs:92:9: 92:11 + let _15: &u64; // in scope 14 at $DIR/unneeded_deref.rs:93:9: 93:11 + scope 15 { + debug y6 => _15; // in scope 15 at $DIR/unneeded_deref.rs:93:9: 93:11 + let _16: &u64; // in scope 15 at $DIR/unneeded_deref.rs:94:9: 94:11 + scope 16 { + debug y7 => _16; // in scope 16 at $DIR/unneeded_deref.rs:94:9: 94:11 + let _17: &u64; // in scope 16 at $DIR/unneeded_deref.rs:95:9: 95:11 + scope 17 { + debug y8 => _17; // in scope 17 at $DIR/unneeded_deref.rs:95:9: 95:11 + let _18: &u64; // in scope 17 at $DIR/unneeded_deref.rs:96:9: 96:11 + scope 18 { + debug y9 => _18; // in scope 18 at $DIR/unneeded_deref.rs:96:9: 96:11 + let _19: u64; // in scope 18 at $DIR/unneeded_deref.rs:97:9: 97:11 + scope 19 { + debug z1 => _19; // in scope 19 at $DIR/unneeded_deref.rs:97:9: 97:11 + let _20: u64; // in scope 19 at $DIR/unneeded_deref.rs:98:9: 98:11 + scope 20 { + debug z2 => _20; // in scope 20 at $DIR/unneeded_deref.rs:98:9: 98:11 + let _21: u64; // in scope 20 at $DIR/unneeded_deref.rs:99:9: 99:11 + scope 21 { + debug z3 => _21; // in scope 21 at $DIR/unneeded_deref.rs:99:9: 99:11 + let _22: u64; // in scope 21 at $DIR/unneeded_deref.rs:100:9: 100:11 + scope 22 { + debug z4 => _22; // in scope 22 at $DIR/unneeded_deref.rs:100:9: 100:11 + let _23: u64; // in scope 22 at $DIR/unneeded_deref.rs:101:9: 101:11 + scope 23 { + debug z5 => _23; // in scope 23 at $DIR/unneeded_deref.rs:101:9: 101:11 + let _24: u64; // in scope 23 at $DIR/unneeded_deref.rs:102:9: 102:11 + scope 24 { + debug z6 => _24; // in scope 24 at $DIR/unneeded_deref.rs:102:9: 102:11 + let _25: u64; // in scope 24 at $DIR/unneeded_deref.rs:103:9: 103:11 + scope 25 { + debug z7 => _25; // in scope 25 at $DIR/unneeded_deref.rs:103:9: 103:11 + let _26: u64; // in scope 25 at $DIR/unneeded_deref.rs:104:9: 104:11 + scope 26 { + debug z8 => _26; // in scope 26 at $DIR/unneeded_deref.rs:104:9: 104:11 + let _27: u64; // in scope 26 at $DIR/unneeded_deref.rs:105:9: 105:11 + scope 27 { + debug z9 => _27; // in scope 27 at $DIR/unneeded_deref.rs:105:9: 105:11 + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/unneeded_deref.rs:79:9: 79:11 + _1 = const 1_u64; // scope 0 at $DIR/unneeded_deref.rs:79:14: 79:15 + StorageLive(_2); // scope 1 at $DIR/unneeded_deref.rs:80:9: 80:11 + _2 = const 2_u64; // scope 1 at $DIR/unneeded_deref.rs:80:14: 80:15 + StorageLive(_3); // scope 2 at $DIR/unneeded_deref.rs:81:9: 81:11 + _3 = const 3_u64; // scope 2 at $DIR/unneeded_deref.rs:81:14: 81:15 + StorageLive(_4); // scope 3 at $DIR/unneeded_deref.rs:82:9: 82:11 + _4 = const 4_u64; // scope 3 at $DIR/unneeded_deref.rs:82:14: 82:15 + StorageLive(_5); // scope 4 at $DIR/unneeded_deref.rs:83:9: 83:11 + _5 = const 5_u64; // scope 4 at $DIR/unneeded_deref.rs:83:14: 83:15 + StorageLive(_6); // scope 5 at $DIR/unneeded_deref.rs:84:9: 84:11 + _6 = const 6_u64; // scope 5 at $DIR/unneeded_deref.rs:84:14: 84:15 + StorageLive(_7); // scope 6 at $DIR/unneeded_deref.rs:85:9: 85:11 + _7 = const 7_u64; // scope 6 at $DIR/unneeded_deref.rs:85:14: 85:15 + StorageLive(_8); // scope 7 at $DIR/unneeded_deref.rs:86:9: 86:11 + _8 = const 8_u64; // scope 7 at $DIR/unneeded_deref.rs:86:14: 86:15 + StorageLive(_9); // scope 8 at $DIR/unneeded_deref.rs:87:9: 87:11 + _9 = const 9_u64; // scope 8 at $DIR/unneeded_deref.rs:87:14: 87:15 + StorageLive(_10); // scope 9 at $DIR/unneeded_deref.rs:88:9: 88:11 + _10 = &_1; // scope 9 at $DIR/unneeded_deref.rs:88:14: 88:17 + StorageLive(_11); // scope 10 at $DIR/unneeded_deref.rs:89:9: 89:11 + _11 = &_2; // scope 10 at $DIR/unneeded_deref.rs:89:14: 89:17 + StorageLive(_12); // scope 11 at $DIR/unneeded_deref.rs:90:9: 90:11 + _12 = &_3; // scope 11 at $DIR/unneeded_deref.rs:90:14: 90:17 + StorageLive(_13); // scope 12 at $DIR/unneeded_deref.rs:91:9: 91:11 + _13 = &_4; // scope 12 at $DIR/unneeded_deref.rs:91:14: 91:17 + StorageLive(_14); // scope 13 at $DIR/unneeded_deref.rs:92:9: 92:11 + _14 = &_5; // scope 13 at $DIR/unneeded_deref.rs:92:14: 92:17 + StorageLive(_15); // scope 14 at $DIR/unneeded_deref.rs:93:9: 93:11 + _15 = &_6; // scope 14 at $DIR/unneeded_deref.rs:93:14: 93:17 + StorageLive(_16); // scope 15 at $DIR/unneeded_deref.rs:94:9: 94:11 + _16 = &_7; // scope 15 at $DIR/unneeded_deref.rs:94:14: 94:17 + StorageLive(_17); // scope 16 at $DIR/unneeded_deref.rs:95:9: 95:11 + _17 = &_8; // scope 16 at $DIR/unneeded_deref.rs:95:14: 95:17 + StorageLive(_18); // scope 17 at $DIR/unneeded_deref.rs:96:9: 96:11 + _18 = &_9; // scope 17 at $DIR/unneeded_deref.rs:96:14: 96:17 + StorageLive(_19); // scope 18 at $DIR/unneeded_deref.rs:97:9: 97:11 +- _19 = (*_10); // scope 18 at $DIR/unneeded_deref.rs:97:14: 97:17 ++ _19 = _1; // scope 18 at $DIR/unneeded_deref.rs:97:14: 97:17 + StorageLive(_20); // scope 19 at $DIR/unneeded_deref.rs:98:9: 98:11 +- _20 = (*_11); // scope 19 at $DIR/unneeded_deref.rs:98:14: 98:17 ++ _20 = _2; // scope 19 at $DIR/unneeded_deref.rs:98:14: 98:17 + StorageLive(_21); // scope 20 at $DIR/unneeded_deref.rs:99:9: 99:11 +- _21 = (*_12); // scope 20 at $DIR/unneeded_deref.rs:99:14: 99:17 ++ _21 = _3; // scope 20 at $DIR/unneeded_deref.rs:99:14: 99:17 + StorageLive(_22); // scope 21 at $DIR/unneeded_deref.rs:100:9: 100:11 +- _22 = (*_13); // scope 21 at $DIR/unneeded_deref.rs:100:14: 100:17 ++ _22 = _4; // scope 21 at $DIR/unneeded_deref.rs:100:14: 100:17 + StorageLive(_23); // scope 22 at $DIR/unneeded_deref.rs:101:9: 101:11 +- _23 = (*_14); // scope 22 at $DIR/unneeded_deref.rs:101:14: 101:17 ++ _23 = _5; // scope 22 at $DIR/unneeded_deref.rs:101:14: 101:17 + StorageLive(_24); // scope 23 at $DIR/unneeded_deref.rs:102:9: 102:11 +- _24 = (*_15); // scope 23 at $DIR/unneeded_deref.rs:102:14: 102:17 ++ _24 = _6; // scope 23 at $DIR/unneeded_deref.rs:102:14: 102:17 + StorageLive(_25); // scope 24 at $DIR/unneeded_deref.rs:103:9: 103:11 +- _25 = (*_16); // scope 24 at $DIR/unneeded_deref.rs:103:14: 103:17 ++ _25 = _7; // scope 24 at $DIR/unneeded_deref.rs:103:14: 103:17 + StorageLive(_26); // scope 25 at $DIR/unneeded_deref.rs:104:9: 104:11 +- _26 = (*_17); // scope 25 at $DIR/unneeded_deref.rs:104:14: 104:17 ++ _26 = _8; // scope 25 at $DIR/unneeded_deref.rs:104:14: 104:17 + StorageLive(_27); // scope 26 at $DIR/unneeded_deref.rs:105:9: 105:11 +- _27 = (*_18); // scope 26 at $DIR/unneeded_deref.rs:105:14: 105:17 ++ _27 = _9; // scope 26 at $DIR/unneeded_deref.rs:105:14: 105:17 + StorageLive(_28); // scope 27 at $DIR/unneeded_deref.rs:106:6: 106:8 + _28 = _19; // scope 27 at $DIR/unneeded_deref.rs:106:6: 106:8 + StorageLive(_29); // scope 27 at $DIR/unneeded_deref.rs:106:10: 106:12 + _29 = _20; // scope 27 at $DIR/unneeded_deref.rs:106:10: 106:12 + StorageLive(_30); // scope 27 at $DIR/unneeded_deref.rs:106:14: 106:16 + _30 = _21; // scope 27 at $DIR/unneeded_deref.rs:106:14: 106:16 + StorageLive(_31); // scope 27 at $DIR/unneeded_deref.rs:106:18: 106:20 + _31 = _22; // scope 27 at $DIR/unneeded_deref.rs:106:18: 106:20 + StorageLive(_32); // scope 27 at $DIR/unneeded_deref.rs:106:22: 106:24 + _32 = _23; // scope 27 at $DIR/unneeded_deref.rs:106:22: 106:24 + StorageLive(_33); // scope 27 at $DIR/unneeded_deref.rs:106:26: 106:28 + _33 = _24; // scope 27 at $DIR/unneeded_deref.rs:106:26: 106:28 + StorageLive(_34); // scope 27 at $DIR/unneeded_deref.rs:106:30: 106:32 + _34 = _25; // scope 27 at $DIR/unneeded_deref.rs:106:30: 106:32 + StorageLive(_35); // scope 27 at $DIR/unneeded_deref.rs:106:34: 106:36 + _35 = _26; // scope 27 at $DIR/unneeded_deref.rs:106:34: 106:36 + StorageLive(_36); // scope 27 at $DIR/unneeded_deref.rs:106:38: 106:40 + _36 = _27; // scope 27 at $DIR/unneeded_deref.rs:106:38: 106:40 + (_0.0: u64) = move _28; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 + (_0.1: u64) = move _29; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 + (_0.2: u64) = move _30; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 + (_0.3: u64) = move _31; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 + (_0.4: u64) = move _32; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 + (_0.5: u64) = move _33; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 + (_0.6: u64) = move _34; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 + (_0.7: u64) = move _35; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 + (_0.8: u64) = move _36; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 + StorageDead(_36); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 + StorageDead(_35); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 + StorageDead(_34); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 + StorageDead(_33); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 + StorageDead(_32); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 + StorageDead(_31); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 + StorageDead(_30); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 + StorageDead(_29); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 + StorageDead(_28); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 + StorageDead(_27); // scope 26 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_26); // scope 25 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_25); // scope 24 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_24); // scope 23 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_23); // scope 22 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_22); // scope 21 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_21); // scope 20 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_20); // scope 19 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_19); // scope 18 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_18); // scope 17 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_17); // scope 16 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_16); // scope 15 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_15); // scope 14 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_14); // scope 13 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_13); // scope 12 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_12); // scope 11 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_11); // scope 10 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_10); // scope 9 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_9); // scope 8 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_8); // scope 7 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_7); // scope 6 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_6); // scope 5 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_5); // scope 4 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_4); // scope 3 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_3); // scope 2 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_2); // scope 1 at $DIR/unneeded_deref.rs:107:1: 107:2 + StorageDead(_1); // scope 0 at $DIR/unneeded_deref.rs:107:1: 107:2 + return; // scope 0 at $DIR/unneeded_deref.rs:107:2: 107:2 + } + } + From c0990991658d185240d2bb10b4956f2a68761789 Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Thu, 12 Nov 2020 19:57:23 +0100 Subject: [PATCH 02/18] separate opt/no-opt tests --- ...eeded_deref.operand_opt.UnneededDeref.diff | 100 ++--- ...deref.opt_different_bbs.UnneededDeref.diff | 64 +-- ...eref.opt_different_bbs2.UnneededDeref.diff | 56 +-- src/test/mir-opt/unneeded_deref.rs | 60 --- ...ded_deref.very_deep_opt.UnneededDeref.diff | 382 +++++++++--------- ..._opt.do_not_miscompile.UnneededDeref.diff} | 100 ++--- ...not_miscompile_mut_ref.UnneededDeref.diff} | 94 ++--- ..._not_opt_different_bbs.UnneededDeref.diff} | 74 ++-- ...t_opt.do_not_use_moved.UnneededDeref.diff} | 32 +- ...ef_do_not_opt.dont_opt.UnneededDeref.diff} | 66 +-- src/test/mir-opt/unneeded_deref_do_not_opt.rs | 64 +++ 11 files changed, 548 insertions(+), 544 deletions(-) rename src/test/mir-opt/{unneeded_deref.do_not_miscompile.UnneededDeref.diff => unneeded_deref_do_not_opt.do_not_miscompile.UnneededDeref.diff} (71%) rename src/test/mir-opt/{unneeded_deref.do_not_miscompile_mut_ref.UnneededDeref.diff => unneeded_deref_do_not_opt.do_not_miscompile_mut_ref.UnneededDeref.diff} (64%) rename src/test/mir-opt/{unneeded_deref.do_not_opt_different_bbs.UnneededDeref.diff => unneeded_deref_do_not_opt.do_not_opt_different_bbs.UnneededDeref.diff} (62%) rename src/test/mir-opt/{unneeded_deref.do_not_use_moved.UnneededDeref.diff => unneeded_deref_do_not_opt.do_not_use_moved.UnneededDeref.diff} (66%) rename src/test/mir-opt/{unneeded_deref.dont_opt.UnneededDeref.diff => unneeded_deref_do_not_opt.dont_opt.UnneededDeref.diff} (64%) create mode 100644 src/test/mir-opt/unneeded_deref_do_not_opt.rs diff --git a/src/test/mir-opt/unneeded_deref.operand_opt.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.operand_opt.UnneededDeref.diff index f0632406c7787..7cc342ded6593 100644 --- a/src/test/mir-opt/unneeded_deref.operand_opt.UnneededDeref.diff +++ b/src/test/mir-opt/unneeded_deref.operand_opt.UnneededDeref.diff @@ -2,70 +2,70 @@ + // MIR for `operand_opt` after UnneededDeref fn operand_opt(_1: Option) -> bool { - debug input => _1; // in scope 0 at $DIR/unneeded_deref.rs:142:25: 142:30 - let mut _0: bool; // return place in scope 0 at $DIR/unneeded_deref.rs:142:46: 142:50 - let _2: bool; // in scope 0 at $DIR/unneeded_deref.rs:143:9: 143:10 - let mut _3: &std::option::Option; // in scope 0 at $DIR/unneeded_deref.rs:143:13: 143:18 - let mut _5: &std::option::Option; // in scope 0 at $DIR/unneeded_deref.rs:144:13: 144:18 - let mut _6: bool; // in scope 0 at $DIR/unneeded_deref.rs:145:5: 145:6 - let mut _7: bool; // in scope 0 at $DIR/unneeded_deref.rs:145:10: 145:11 - let mut _10: isize; // in scope 0 at $DIR/unneeded_deref.rs:143:13: 143:28 - let mut _11: isize; // in scope 0 at $DIR/unneeded_deref.rs:144:13: 144:28 + debug input => _1; // in scope 0 at $DIR/unneeded_deref.rs:87:25: 87:30 + let mut _0: bool; // return place in scope 0 at $DIR/unneeded_deref.rs:87:46: 87:50 + let _2: bool; // in scope 0 at $DIR/unneeded_deref.rs:88:9: 88:10 + let mut _3: &std::option::Option; // in scope 0 at $DIR/unneeded_deref.rs:88:13: 88:18 + let mut _5: &std::option::Option; // in scope 0 at $DIR/unneeded_deref.rs:89:13: 89:18 + let mut _6: bool; // in scope 0 at $DIR/unneeded_deref.rs:90:5: 90:6 + let mut _7: bool; // in scope 0 at $DIR/unneeded_deref.rs:90:10: 90:11 + let mut _10: isize; // in scope 0 at $DIR/unneeded_deref.rs:88:13: 88:28 + let mut _11: isize; // in scope 0 at $DIR/unneeded_deref.rs:89:13: 89:28 scope 1 { - debug x => _2; // in scope 1 at $DIR/unneeded_deref.rs:143:9: 143:10 - let _4: bool; // in scope 1 at $DIR/unneeded_deref.rs:144:9: 144:10 + debug x => _2; // in scope 1 at $DIR/unneeded_deref.rs:88:9: 88:10 + let _4: bool; // in scope 1 at $DIR/unneeded_deref.rs:89:9: 89:10 scope 2 { - debug y => _4; // in scope 2 at $DIR/unneeded_deref.rs:144:9: 144:10 + debug y => _4; // in scope 2 at $DIR/unneeded_deref.rs:89:9: 89:10 } - scope 4 (inlined Option::::is_some) { // at $DIR/unneeded_deref.rs:144:13: 144:28 - debug self => _5; // in scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 - let mut _9: isize; // in scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 + scope 4 (inlined Option::::is_some) { // at $DIR/unneeded_deref.rs:89:13: 89:28 + debug self => _5; // in scope 4 at $DIR/unneeded_deref.rs:89:13: 89:28 + let mut _9: isize; // in scope 4 at $DIR/unneeded_deref.rs:89:13: 89:28 } } - scope 3 (inlined Option::::is_some) { // at $DIR/unneeded_deref.rs:143:13: 143:28 - debug self => _3; // in scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 - let mut _8: isize; // in scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 + scope 3 (inlined Option::::is_some) { // at $DIR/unneeded_deref.rs:88:13: 88:28 + debug self => _3; // in scope 3 at $DIR/unneeded_deref.rs:88:13: 88:28 + let mut _8: isize; // in scope 3 at $DIR/unneeded_deref.rs:88:13: 88:28 } bb0: { - StorageLive(_2); // scope 0 at $DIR/unneeded_deref.rs:143:9: 143:10 - StorageLive(_3); // scope 0 at $DIR/unneeded_deref.rs:143:13: 143:18 - _3 = &_1; // scope 0 at $DIR/unneeded_deref.rs:143:13: 143:18 -- _8 = discriminant((*_3)); // scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 -+ _8 = discriminant(_1); // scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 - StorageLive(_10); // scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 - _10 = move _8; // scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 - _2 = Eq(_10, const 1_isize); // scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 - StorageDead(_10); // scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 - goto -> bb1; // scope 3 at $DIR/unneeded_deref.rs:143:13: 143:28 + StorageLive(_2); // scope 0 at $DIR/unneeded_deref.rs:88:9: 88:10 + StorageLive(_3); // scope 0 at $DIR/unneeded_deref.rs:88:13: 88:18 + _3 = &_1; // scope 0 at $DIR/unneeded_deref.rs:88:13: 88:18 +- _8 = discriminant((*_3)); // scope 3 at $DIR/unneeded_deref.rs:88:13: 88:28 ++ _8 = discriminant(_1); // scope 3 at $DIR/unneeded_deref.rs:88:13: 88:28 + StorageLive(_10); // scope 3 at $DIR/unneeded_deref.rs:88:13: 88:28 + _10 = move _8; // scope 3 at $DIR/unneeded_deref.rs:88:13: 88:28 + _2 = Eq(_10, const 1_isize); // scope 3 at $DIR/unneeded_deref.rs:88:13: 88:28 + StorageDead(_10); // scope 3 at $DIR/unneeded_deref.rs:88:13: 88:28 + goto -> bb1; // scope 3 at $DIR/unneeded_deref.rs:88:13: 88:28 } bb1: { - StorageDead(_3); // scope 0 at $DIR/unneeded_deref.rs:143:27: 143:28 - StorageLive(_4); // scope 1 at $DIR/unneeded_deref.rs:144:9: 144:10 - StorageLive(_5); // scope 1 at $DIR/unneeded_deref.rs:144:13: 144:18 - _5 = &_1; // scope 1 at $DIR/unneeded_deref.rs:144:13: 144:18 -- _9 = discriminant((*_5)); // scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 -+ _9 = discriminant(_1); // scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 - StorageLive(_11); // scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 - _11 = move _9; // scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 - _4 = Eq(_11, const 1_isize); // scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 - StorageDead(_11); // scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 - goto -> bb2; // scope 4 at $DIR/unneeded_deref.rs:144:13: 144:28 + StorageDead(_3); // scope 0 at $DIR/unneeded_deref.rs:88:27: 88:28 + StorageLive(_4); // scope 1 at $DIR/unneeded_deref.rs:89:9: 89:10 + StorageLive(_5); // scope 1 at $DIR/unneeded_deref.rs:89:13: 89:18 + _5 = &_1; // scope 1 at $DIR/unneeded_deref.rs:89:13: 89:18 +- _9 = discriminant((*_5)); // scope 4 at $DIR/unneeded_deref.rs:89:13: 89:28 ++ _9 = discriminant(_1); // scope 4 at $DIR/unneeded_deref.rs:89:13: 89:28 + StorageLive(_11); // scope 4 at $DIR/unneeded_deref.rs:89:13: 89:28 + _11 = move _9; // scope 4 at $DIR/unneeded_deref.rs:89:13: 89:28 + _4 = Eq(_11, const 1_isize); // scope 4 at $DIR/unneeded_deref.rs:89:13: 89:28 + StorageDead(_11); // scope 4 at $DIR/unneeded_deref.rs:89:13: 89:28 + goto -> bb2; // scope 4 at $DIR/unneeded_deref.rs:89:13: 89:28 } bb2: { - StorageDead(_5); // scope 1 at $DIR/unneeded_deref.rs:144:27: 144:28 - StorageLive(_6); // scope 2 at $DIR/unneeded_deref.rs:145:5: 145:6 - _6 = _2; // scope 2 at $DIR/unneeded_deref.rs:145:5: 145:6 - StorageLive(_7); // scope 2 at $DIR/unneeded_deref.rs:145:10: 145:11 - _7 = _4; // scope 2 at $DIR/unneeded_deref.rs:145:10: 145:11 - _0 = Eq(move _6, move _7); // scope 2 at $DIR/unneeded_deref.rs:145:5: 145:11 - StorageDead(_7); // scope 2 at $DIR/unneeded_deref.rs:145:10: 145:11 - StorageDead(_6); // scope 2 at $DIR/unneeded_deref.rs:145:10: 145:11 - StorageDead(_4); // scope 1 at $DIR/unneeded_deref.rs:146:1: 146:2 - StorageDead(_2); // scope 0 at $DIR/unneeded_deref.rs:146:1: 146:2 - return; // scope 0 at $DIR/unneeded_deref.rs:146:2: 146:2 + StorageDead(_5); // scope 1 at $DIR/unneeded_deref.rs:89:27: 89:28 + StorageLive(_6); // scope 2 at $DIR/unneeded_deref.rs:90:5: 90:6 + _6 = _2; // scope 2 at $DIR/unneeded_deref.rs:90:5: 90:6 + StorageLive(_7); // scope 2 at $DIR/unneeded_deref.rs:90:10: 90:11 + _7 = _4; // scope 2 at $DIR/unneeded_deref.rs:90:10: 90:11 + _0 = Eq(move _6, move _7); // scope 2 at $DIR/unneeded_deref.rs:90:5: 90:11 + StorageDead(_7); // scope 2 at $DIR/unneeded_deref.rs:90:10: 90:11 + StorageDead(_6); // scope 2 at $DIR/unneeded_deref.rs:90:10: 90:11 + StorageDead(_4); // scope 1 at $DIR/unneeded_deref.rs:91:1: 91:2 + StorageDead(_2); // scope 0 at $DIR/unneeded_deref.rs:91:1: 91:2 + return; // scope 0 at $DIR/unneeded_deref.rs:91:2: 91:2 } } diff --git a/src/test/mir-opt/unneeded_deref.opt_different_bbs.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.opt_different_bbs.UnneededDeref.diff index 6142bc9acea14..6ed3cd3dc5762 100644 --- a/src/test/mir-opt/unneeded_deref.opt_different_bbs.UnneededDeref.diff +++ b/src/test/mir-opt/unneeded_deref.opt_different_bbs.UnneededDeref.diff @@ -2,57 +2,57 @@ + // MIR for `opt_different_bbs` after UnneededDeref fn opt_different_bbs(_1: bool) -> u64 { - debug input => _1; // in scope 0 at $DIR/unneeded_deref.rs:116:22: 116:27 - let mut _0: u64; // return place in scope 0 at $DIR/unneeded_deref.rs:116:38: 116:41 - let _2: u64; // in scope 0 at $DIR/unneeded_deref.rs:117:9: 117:10 - let mut _4: i32; // in scope 0 at $DIR/unneeded_deref.rs:119:13: 119:38 - let mut _5: bool; // in scope 0 at $DIR/unneeded_deref.rs:119:16: 119:21 + debug input => _1; // in scope 0 at $DIR/unneeded_deref.rs:70:22: 70:27 + let mut _0: u64; // return place in scope 0 at $DIR/unneeded_deref.rs:70:38: 70:41 + let _2: u64; // in scope 0 at $DIR/unneeded_deref.rs:71:9: 71:10 + let mut _4: i32; // in scope 0 at $DIR/unneeded_deref.rs:73:13: 73:38 + let mut _5: bool; // in scope 0 at $DIR/unneeded_deref.rs:73:16: 73:21 scope 1 { - debug x => _2; // in scope 1 at $DIR/unneeded_deref.rs:117:9: 117:10 - let _3: &u64; // in scope 1 at $DIR/unneeded_deref.rs:118:9: 118:10 + debug x => _2; // in scope 1 at $DIR/unneeded_deref.rs:71:9: 71:10 + let _3: &u64; // in scope 1 at $DIR/unneeded_deref.rs:72:9: 72:10 scope 2 { - debug y => _3; // in scope 2 at $DIR/unneeded_deref.rs:118:9: 118:10 + debug y => _3; // in scope 2 at $DIR/unneeded_deref.rs:72:9: 72:10 scope 3 { - let _6: u64; // in scope 3 at $DIR/unneeded_deref.rs:120:9: 120:10 + let _6: u64; // in scope 3 at $DIR/unneeded_deref.rs:74:9: 74:10 scope 4 { - debug z => _6; // in scope 4 at $DIR/unneeded_deref.rs:120:9: 120:10 + debug z => _6; // in scope 4 at $DIR/unneeded_deref.rs:74:9: 74:10 } } } } bb0: { - StorageLive(_2); // scope 0 at $DIR/unneeded_deref.rs:117:9: 117:10 - _2 = const 5_u64; // scope 0 at $DIR/unneeded_deref.rs:117:13: 117:14 - StorageLive(_3); // scope 1 at $DIR/unneeded_deref.rs:118:9: 118:10 - _3 = &_2; // scope 1 at $DIR/unneeded_deref.rs:118:13: 118:15 - StorageLive(_4); // scope 2 at $DIR/unneeded_deref.rs:119:13: 119:38 - StorageLive(_5); // scope 2 at $DIR/unneeded_deref.rs:119:16: 119:21 - _5 = _1; // scope 2 at $DIR/unneeded_deref.rs:119:16: 119:21 - switchInt(_5) -> [false: bb1, otherwise: bb2]; // scope 2 at $DIR/unneeded_deref.rs:119:13: 119:38 + StorageLive(_2); // scope 0 at $DIR/unneeded_deref.rs:71:9: 71:10 + _2 = const 5_u64; // scope 0 at $DIR/unneeded_deref.rs:71:13: 71:14 + StorageLive(_3); // scope 1 at $DIR/unneeded_deref.rs:72:9: 72:10 + _3 = &_2; // scope 1 at $DIR/unneeded_deref.rs:72:13: 72:15 + StorageLive(_4); // scope 2 at $DIR/unneeded_deref.rs:73:13: 73:38 + StorageLive(_5); // scope 2 at $DIR/unneeded_deref.rs:73:16: 73:21 + _5 = _1; // scope 2 at $DIR/unneeded_deref.rs:73:16: 73:21 + switchInt(_5) -> [false: bb1, otherwise: bb2]; // scope 2 at $DIR/unneeded_deref.rs:73:13: 73:38 } bb1: { - _4 = const 3_i32; // scope 2 at $DIR/unneeded_deref.rs:119:35: 119:36 - goto -> bb3; // scope 2 at $DIR/unneeded_deref.rs:119:13: 119:38 + _4 = const 3_i32; // scope 2 at $DIR/unneeded_deref.rs:73:35: 73:36 + goto -> bb3; // scope 2 at $DIR/unneeded_deref.rs:73:13: 73:38 } bb2: { - _4 = const 2_i32; // scope 2 at $DIR/unneeded_deref.rs:119:24: 119:25 - goto -> bb3; // scope 2 at $DIR/unneeded_deref.rs:119:13: 119:38 + _4 = const 2_i32; // scope 2 at $DIR/unneeded_deref.rs:73:24: 73:25 + goto -> bb3; // scope 2 at $DIR/unneeded_deref.rs:73:13: 73:38 } bb3: { - StorageDead(_5); // scope 2 at $DIR/unneeded_deref.rs:119:38: 119:39 - StorageDead(_4); // scope 2 at $DIR/unneeded_deref.rs:119:38: 119:39 - StorageLive(_6); // scope 3 at $DIR/unneeded_deref.rs:120:9: 120:10 -- _6 = (*_3); // scope 3 at $DIR/unneeded_deref.rs:120:13: 120:15 -+ _6 = _2; // scope 3 at $DIR/unneeded_deref.rs:120:13: 120:15 - _0 = _6; // scope 4 at $DIR/unneeded_deref.rs:121:5: 121:6 - StorageDead(_6); // scope 3 at $DIR/unneeded_deref.rs:122:1: 122:2 - StorageDead(_3); // scope 1 at $DIR/unneeded_deref.rs:122:1: 122:2 - StorageDead(_2); // scope 0 at $DIR/unneeded_deref.rs:122:1: 122:2 - return; // scope 0 at $DIR/unneeded_deref.rs:122:2: 122:2 + StorageDead(_5); // scope 2 at $DIR/unneeded_deref.rs:73:38: 73:39 + StorageDead(_4); // scope 2 at $DIR/unneeded_deref.rs:73:38: 73:39 + StorageLive(_6); // scope 3 at $DIR/unneeded_deref.rs:74:9: 74:10 +- _6 = (*_3); // scope 3 at $DIR/unneeded_deref.rs:74:13: 74:15 ++ _6 = _2; // scope 3 at $DIR/unneeded_deref.rs:74:13: 74:15 + _0 = _6; // scope 4 at $DIR/unneeded_deref.rs:75:5: 75:6 + StorageDead(_6); // scope 3 at $DIR/unneeded_deref.rs:76:1: 76:2 + StorageDead(_3); // scope 1 at $DIR/unneeded_deref.rs:76:1: 76:2 + StorageDead(_2); // scope 0 at $DIR/unneeded_deref.rs:76:1: 76:2 + return; // scope 0 at $DIR/unneeded_deref.rs:76:2: 76:2 } } diff --git a/src/test/mir-opt/unneeded_deref.opt_different_bbs2.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.opt_different_bbs2.UnneededDeref.diff index d274ae0fa4008..3ef7925a95f96 100644 --- a/src/test/mir-opt/unneeded_deref.opt_different_bbs2.UnneededDeref.diff +++ b/src/test/mir-opt/unneeded_deref.opt_different_bbs2.UnneededDeref.diff @@ -2,51 +2,51 @@ + // MIR for `opt_different_bbs2` after UnneededDeref fn opt_different_bbs2(_1: bool) -> u64 { - debug input => _1; // in scope 0 at $DIR/unneeded_deref.rs:125:23: 125:28 - let mut _0: u64; // return place in scope 0 at $DIR/unneeded_deref.rs:125:39: 125:42 - let _2: u64; // in scope 0 at $DIR/unneeded_deref.rs:126:9: 126:10 - let mut _5: bool; // in scope 0 at $DIR/unneeded_deref.rs:128:16: 128:21 + debug input => _1; // in scope 0 at $DIR/unneeded_deref.rs:79:23: 79:28 + let mut _0: u64; // return place in scope 0 at $DIR/unneeded_deref.rs:79:39: 79:42 + let _2: u64; // in scope 0 at $DIR/unneeded_deref.rs:80:9: 80:10 + let mut _5: bool; // in scope 0 at $DIR/unneeded_deref.rs:82:16: 82:21 scope 1 { - debug x => _2; // in scope 1 at $DIR/unneeded_deref.rs:126:9: 126:10 - let _3: &u64; // in scope 1 at $DIR/unneeded_deref.rs:127:9: 127:10 + debug x => _2; // in scope 1 at $DIR/unneeded_deref.rs:80:9: 80:10 + let _3: &u64; // in scope 1 at $DIR/unneeded_deref.rs:81:9: 81:10 scope 2 { - debug y => _3; // in scope 2 at $DIR/unneeded_deref.rs:127:9: 127:10 - let _4: u64; // in scope 2 at $DIR/unneeded_deref.rs:128:9: 128:10 + debug y => _3; // in scope 2 at $DIR/unneeded_deref.rs:81:9: 81:10 + let _4: u64; // in scope 2 at $DIR/unneeded_deref.rs:82:9: 82:10 scope 3 { - debug z => _4; // in scope 3 at $DIR/unneeded_deref.rs:128:9: 128:10 + debug z => _4; // in scope 3 at $DIR/unneeded_deref.rs:82:9: 82:10 } } } bb0: { - StorageLive(_2); // scope 0 at $DIR/unneeded_deref.rs:126:9: 126:10 - _2 = const 5_u64; // scope 0 at $DIR/unneeded_deref.rs:126:13: 126:14 - StorageLive(_3); // scope 1 at $DIR/unneeded_deref.rs:127:9: 127:10 - _3 = &_2; // scope 1 at $DIR/unneeded_deref.rs:127:13: 127:15 - StorageLive(_4); // scope 2 at $DIR/unneeded_deref.rs:128:9: 128:10 - StorageLive(_5); // scope 2 at $DIR/unneeded_deref.rs:128:16: 128:21 - _5 = _1; // scope 2 at $DIR/unneeded_deref.rs:128:16: 128:21 - switchInt(_5) -> [false: bb1, otherwise: bb2]; // scope 2 at $DIR/unneeded_deref.rs:128:13: 128:39 + StorageLive(_2); // scope 0 at $DIR/unneeded_deref.rs:80:9: 80:10 + _2 = const 5_u64; // scope 0 at $DIR/unneeded_deref.rs:80:13: 80:14 + StorageLive(_3); // scope 1 at $DIR/unneeded_deref.rs:81:9: 81:10 + _3 = &_2; // scope 1 at $DIR/unneeded_deref.rs:81:13: 81:15 + StorageLive(_4); // scope 2 at $DIR/unneeded_deref.rs:82:9: 82:10 + StorageLive(_5); // scope 2 at $DIR/unneeded_deref.rs:82:16: 82:21 + _5 = _1; // scope 2 at $DIR/unneeded_deref.rs:82:16: 82:21 + switchInt(_5) -> [false: bb1, otherwise: bb2]; // scope 2 at $DIR/unneeded_deref.rs:82:13: 82:39 } bb1: { - _4 = const 3_u64; // scope 2 at $DIR/unneeded_deref.rs:128:36: 128:37 - goto -> bb3; // scope 2 at $DIR/unneeded_deref.rs:128:13: 128:39 + _4 = const 3_u64; // scope 2 at $DIR/unneeded_deref.rs:82:36: 82:37 + goto -> bb3; // scope 2 at $DIR/unneeded_deref.rs:82:13: 82:39 } bb2: { -- _4 = (*_3); // scope 2 at $DIR/unneeded_deref.rs:128:24: 128:26 -+ _4 = _2; // scope 2 at $DIR/unneeded_deref.rs:128:24: 128:26 - goto -> bb3; // scope 2 at $DIR/unneeded_deref.rs:128:13: 128:39 +- _4 = (*_3); // scope 2 at $DIR/unneeded_deref.rs:82:24: 82:26 ++ _4 = _2; // scope 2 at $DIR/unneeded_deref.rs:82:24: 82:26 + goto -> bb3; // scope 2 at $DIR/unneeded_deref.rs:82:13: 82:39 } bb3: { - StorageDead(_5); // scope 2 at $DIR/unneeded_deref.rs:128:39: 128:40 - _0 = _4; // scope 3 at $DIR/unneeded_deref.rs:129:5: 129:6 - StorageDead(_4); // scope 2 at $DIR/unneeded_deref.rs:130:1: 130:2 - StorageDead(_3); // scope 1 at $DIR/unneeded_deref.rs:130:1: 130:2 - StorageDead(_2); // scope 0 at $DIR/unneeded_deref.rs:130:1: 130:2 - return; // scope 0 at $DIR/unneeded_deref.rs:130:2: 130:2 + StorageDead(_5); // scope 2 at $DIR/unneeded_deref.rs:82:39: 82:40 + _0 = _4; // scope 3 at $DIR/unneeded_deref.rs:83:5: 83:6 + StorageDead(_4); // scope 2 at $DIR/unneeded_deref.rs:84:1: 84:2 + StorageDead(_3); // scope 1 at $DIR/unneeded_deref.rs:84:1: 84:2 + StorageDead(_2); // scope 0 at $DIR/unneeded_deref.rs:84:1: 84:2 + return; // scope 0 at $DIR/unneeded_deref.rs:84:2: 84:2 } } diff --git a/src/test/mir-opt/unneeded_deref.rs b/src/test/mir-opt/unneeded_deref.rs index 7de50d86f8483..a49aec44d2ace 100644 --- a/src/test/mir-opt/unneeded_deref.rs +++ b/src/test/mir-opt/unneeded_deref.rs @@ -34,46 +34,6 @@ fn opt_struct(s: S) -> u64 { *b + x } -// EMIT_MIR unneeded_deref.dont_opt.UnneededDeref.diff -// do not optimize a sequence looking like this: -// _1 = &_2; -// _1 = _3; -// _4 = *_1; -// as the _1 = _3 assignment makes it not legal to replace the last statement with _4 = _2 -fn dont_opt() -> u64 { - let y = 5; - let _ref = &y; - let x = 5; - let mut _1 = &x; - _1 = _ref; - let _4 = *_1; - 0 -} - -// EMIT_MIR unneeded_deref.do_not_miscompile.UnneededDeref.diff -fn do_not_miscompile() { - let x = 42; - let a = 99; - let mut y = &x; - let z = &mut y; - *z = &a; - assert!(*y == 99); -} - -// EMIT_MIR unneeded_deref.do_not_miscompile_mut_ref.UnneededDeref.diff -// See #78192 -fn do_not_miscompile_mut_ref() { - let a = 1u32; - let b = 2u32; - - let mut c: *const u32 = &a; - let d: &u32 = &b; - - let x = unsafe { &*c }; - c = d; - let z = *x; -} - // EMIT_MIR unneeded_deref.very_deep_opt.UnneededDeref.diff fn very_deep_opt() -> (u64, u64, u64, u64, u64, u64, u64, u64, u64) { let x1 = 1; @@ -106,12 +66,6 @@ fn very_deep_opt() -> (u64, u64, u64, u64, u64, u64, u64, u64, u64) { (z1, z2, z3, z4, z5, z6, z7, z8, z9) } -// EMIT_MIR unneeded_deref.do_not_use_moved.UnneededDeref.diff -fn do_not_use_moved(x: T) { - let b = x; - let z = &b; -} - // EMIT_MIR unneeded_deref.opt_different_bbs.UnneededDeref.diff fn opt_different_bbs(input: bool) -> u64 { let x = 5; @@ -129,15 +83,6 @@ fn opt_different_bbs2(input: bool) -> u64 { z } -// EMIT_MIR unneeded_deref.do_not_opt_different_bbs.UnneededDeref.diff -// We cannot know whether z should be 5 or 33 -fn do_not_opt_different_bbs(input: bool) -> u64 { - let x = 5; - let y = if input { &x } else { &33 }; - let z = *y; - z -} - // EMIT_MIR unneeded_deref.operand_opt.UnneededDeref.diff fn operand_opt(input: Option) -> bool { let x = input.is_some(); @@ -149,13 +94,8 @@ fn main() { simple_opt(); deep_opt(); opt_struct(S { a: 0, b: 1 }); - dont_opt(); - do_not_miscompile(); - do_not_miscompile_mut_ref(); very_deep_opt(); - do_not_use_moved(String::new()); opt_different_bbs(false); opt_different_bbs2(false); - do_not_opt_different_bbs(false); operand_opt(Some(true)); } diff --git a/src/test/mir-opt/unneeded_deref.very_deep_opt.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref.very_deep_opt.UnneededDeref.diff index 48750c8dbe1ba..9c516385a5851 100644 --- a/src/test/mir-opt/unneeded_deref.very_deep_opt.UnneededDeref.diff +++ b/src/test/mir-opt/unneeded_deref.very_deep_opt.UnneededDeref.diff @@ -2,97 +2,97 @@ + // MIR for `very_deep_opt` after UnneededDeref fn very_deep_opt() -> (u64, u64, u64, u64, u64, u64, u64, u64, u64) { - let mut _0: (u64, u64, u64, u64, u64, u64, u64, u64, u64); // return place in scope 0 at $DIR/unneeded_deref.rs:78:23: 78:68 - let _1: u64; // in scope 0 at $DIR/unneeded_deref.rs:79:9: 79:11 - let mut _28: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:6: 106:8 - let mut _29: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:10: 106:12 - let mut _30: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:14: 106:16 - let mut _31: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:18: 106:20 - let mut _32: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:22: 106:24 - let mut _33: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:26: 106:28 - let mut _34: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:30: 106:32 - let mut _35: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:34: 106:36 - let mut _36: u64; // in scope 0 at $DIR/unneeded_deref.rs:106:38: 106:40 + let mut _0: (u64, u64, u64, u64, u64, u64, u64, u64, u64); // return place in scope 0 at $DIR/unneeded_deref.rs:38:23: 38:68 + let _1: u64; // in scope 0 at $DIR/unneeded_deref.rs:39:9: 39:11 + let mut _28: u64; // in scope 0 at $DIR/unneeded_deref.rs:66:6: 66:8 + let mut _29: u64; // in scope 0 at $DIR/unneeded_deref.rs:66:10: 66:12 + let mut _30: u64; // in scope 0 at $DIR/unneeded_deref.rs:66:14: 66:16 + let mut _31: u64; // in scope 0 at $DIR/unneeded_deref.rs:66:18: 66:20 + let mut _32: u64; // in scope 0 at $DIR/unneeded_deref.rs:66:22: 66:24 + let mut _33: u64; // in scope 0 at $DIR/unneeded_deref.rs:66:26: 66:28 + let mut _34: u64; // in scope 0 at $DIR/unneeded_deref.rs:66:30: 66:32 + let mut _35: u64; // in scope 0 at $DIR/unneeded_deref.rs:66:34: 66:36 + let mut _36: u64; // in scope 0 at $DIR/unneeded_deref.rs:66:38: 66:40 scope 1 { - debug x1 => _1; // in scope 1 at $DIR/unneeded_deref.rs:79:9: 79:11 - let _2: u64; // in scope 1 at $DIR/unneeded_deref.rs:80:9: 80:11 + debug x1 => _1; // in scope 1 at $DIR/unneeded_deref.rs:39:9: 39:11 + let _2: u64; // in scope 1 at $DIR/unneeded_deref.rs:40:9: 40:11 scope 2 { - debug x2 => _2; // in scope 2 at $DIR/unneeded_deref.rs:80:9: 80:11 - let _3: u64; // in scope 2 at $DIR/unneeded_deref.rs:81:9: 81:11 + debug x2 => _2; // in scope 2 at $DIR/unneeded_deref.rs:40:9: 40:11 + let _3: u64; // in scope 2 at $DIR/unneeded_deref.rs:41:9: 41:11 scope 3 { - debug x3 => _3; // in scope 3 at $DIR/unneeded_deref.rs:81:9: 81:11 - let _4: u64; // in scope 3 at $DIR/unneeded_deref.rs:82:9: 82:11 + debug x3 => _3; // in scope 3 at $DIR/unneeded_deref.rs:41:9: 41:11 + let _4: u64; // in scope 3 at $DIR/unneeded_deref.rs:42:9: 42:11 scope 4 { - debug x4 => _4; // in scope 4 at $DIR/unneeded_deref.rs:82:9: 82:11 - let _5: u64; // in scope 4 at $DIR/unneeded_deref.rs:83:9: 83:11 + debug x4 => _4; // in scope 4 at $DIR/unneeded_deref.rs:42:9: 42:11 + let _5: u64; // in scope 4 at $DIR/unneeded_deref.rs:43:9: 43:11 scope 5 { - debug x5 => _5; // in scope 5 at $DIR/unneeded_deref.rs:83:9: 83:11 - let _6: u64; // in scope 5 at $DIR/unneeded_deref.rs:84:9: 84:11 + debug x5 => _5; // in scope 5 at $DIR/unneeded_deref.rs:43:9: 43:11 + let _6: u64; // in scope 5 at $DIR/unneeded_deref.rs:44:9: 44:11 scope 6 { - debug x6 => _6; // in scope 6 at $DIR/unneeded_deref.rs:84:9: 84:11 - let _7: u64; // in scope 6 at $DIR/unneeded_deref.rs:85:9: 85:11 + debug x6 => _6; // in scope 6 at $DIR/unneeded_deref.rs:44:9: 44:11 + let _7: u64; // in scope 6 at $DIR/unneeded_deref.rs:45:9: 45:11 scope 7 { - debug x7 => _7; // in scope 7 at $DIR/unneeded_deref.rs:85:9: 85:11 - let _8: u64; // in scope 7 at $DIR/unneeded_deref.rs:86:9: 86:11 + debug x7 => _7; // in scope 7 at $DIR/unneeded_deref.rs:45:9: 45:11 + let _8: u64; // in scope 7 at $DIR/unneeded_deref.rs:46:9: 46:11 scope 8 { - debug x8 => _8; // in scope 8 at $DIR/unneeded_deref.rs:86:9: 86:11 - let _9: u64; // in scope 8 at $DIR/unneeded_deref.rs:87:9: 87:11 + debug x8 => _8; // in scope 8 at $DIR/unneeded_deref.rs:46:9: 46:11 + let _9: u64; // in scope 8 at $DIR/unneeded_deref.rs:47:9: 47:11 scope 9 { - debug x9 => _9; // in scope 9 at $DIR/unneeded_deref.rs:87:9: 87:11 - let _10: &u64; // in scope 9 at $DIR/unneeded_deref.rs:88:9: 88:11 + debug x9 => _9; // in scope 9 at $DIR/unneeded_deref.rs:47:9: 47:11 + let _10: &u64; // in scope 9 at $DIR/unneeded_deref.rs:48:9: 48:11 scope 10 { - debug y1 => _10; // in scope 10 at $DIR/unneeded_deref.rs:88:9: 88:11 - let _11: &u64; // in scope 10 at $DIR/unneeded_deref.rs:89:9: 89:11 + debug y1 => _10; // in scope 10 at $DIR/unneeded_deref.rs:48:9: 48:11 + let _11: &u64; // in scope 10 at $DIR/unneeded_deref.rs:49:9: 49:11 scope 11 { - debug y2 => _11; // in scope 11 at $DIR/unneeded_deref.rs:89:9: 89:11 - let _12: &u64; // in scope 11 at $DIR/unneeded_deref.rs:90:9: 90:11 + debug y2 => _11; // in scope 11 at $DIR/unneeded_deref.rs:49:9: 49:11 + let _12: &u64; // in scope 11 at $DIR/unneeded_deref.rs:50:9: 50:11 scope 12 { - debug y3 => _12; // in scope 12 at $DIR/unneeded_deref.rs:90:9: 90:11 - let _13: &u64; // in scope 12 at $DIR/unneeded_deref.rs:91:9: 91:11 + debug y3 => _12; // in scope 12 at $DIR/unneeded_deref.rs:50:9: 50:11 + let _13: &u64; // in scope 12 at $DIR/unneeded_deref.rs:51:9: 51:11 scope 13 { - debug y4 => _13; // in scope 13 at $DIR/unneeded_deref.rs:91:9: 91:11 - let _14: &u64; // in scope 13 at $DIR/unneeded_deref.rs:92:9: 92:11 + debug y4 => _13; // in scope 13 at $DIR/unneeded_deref.rs:51:9: 51:11 + let _14: &u64; // in scope 13 at $DIR/unneeded_deref.rs:52:9: 52:11 scope 14 { - debug y5 => _14; // in scope 14 at $DIR/unneeded_deref.rs:92:9: 92:11 - let _15: &u64; // in scope 14 at $DIR/unneeded_deref.rs:93:9: 93:11 + debug y5 => _14; // in scope 14 at $DIR/unneeded_deref.rs:52:9: 52:11 + let _15: &u64; // in scope 14 at $DIR/unneeded_deref.rs:53:9: 53:11 scope 15 { - debug y6 => _15; // in scope 15 at $DIR/unneeded_deref.rs:93:9: 93:11 - let _16: &u64; // in scope 15 at $DIR/unneeded_deref.rs:94:9: 94:11 + debug y6 => _15; // in scope 15 at $DIR/unneeded_deref.rs:53:9: 53:11 + let _16: &u64; // in scope 15 at $DIR/unneeded_deref.rs:54:9: 54:11 scope 16 { - debug y7 => _16; // in scope 16 at $DIR/unneeded_deref.rs:94:9: 94:11 - let _17: &u64; // in scope 16 at $DIR/unneeded_deref.rs:95:9: 95:11 + debug y7 => _16; // in scope 16 at $DIR/unneeded_deref.rs:54:9: 54:11 + let _17: &u64; // in scope 16 at $DIR/unneeded_deref.rs:55:9: 55:11 scope 17 { - debug y8 => _17; // in scope 17 at $DIR/unneeded_deref.rs:95:9: 95:11 - let _18: &u64; // in scope 17 at $DIR/unneeded_deref.rs:96:9: 96:11 + debug y8 => _17; // in scope 17 at $DIR/unneeded_deref.rs:55:9: 55:11 + let _18: &u64; // in scope 17 at $DIR/unneeded_deref.rs:56:9: 56:11 scope 18 { - debug y9 => _18; // in scope 18 at $DIR/unneeded_deref.rs:96:9: 96:11 - let _19: u64; // in scope 18 at $DIR/unneeded_deref.rs:97:9: 97:11 + debug y9 => _18; // in scope 18 at $DIR/unneeded_deref.rs:56:9: 56:11 + let _19: u64; // in scope 18 at $DIR/unneeded_deref.rs:57:9: 57:11 scope 19 { - debug z1 => _19; // in scope 19 at $DIR/unneeded_deref.rs:97:9: 97:11 - let _20: u64; // in scope 19 at $DIR/unneeded_deref.rs:98:9: 98:11 + debug z1 => _19; // in scope 19 at $DIR/unneeded_deref.rs:57:9: 57:11 + let _20: u64; // in scope 19 at $DIR/unneeded_deref.rs:58:9: 58:11 scope 20 { - debug z2 => _20; // in scope 20 at $DIR/unneeded_deref.rs:98:9: 98:11 - let _21: u64; // in scope 20 at $DIR/unneeded_deref.rs:99:9: 99:11 + debug z2 => _20; // in scope 20 at $DIR/unneeded_deref.rs:58:9: 58:11 + let _21: u64; // in scope 20 at $DIR/unneeded_deref.rs:59:9: 59:11 scope 21 { - debug z3 => _21; // in scope 21 at $DIR/unneeded_deref.rs:99:9: 99:11 - let _22: u64; // in scope 21 at $DIR/unneeded_deref.rs:100:9: 100:11 + debug z3 => _21; // in scope 21 at $DIR/unneeded_deref.rs:59:9: 59:11 + let _22: u64; // in scope 21 at $DIR/unneeded_deref.rs:60:9: 60:11 scope 22 { - debug z4 => _22; // in scope 22 at $DIR/unneeded_deref.rs:100:9: 100:11 - let _23: u64; // in scope 22 at $DIR/unneeded_deref.rs:101:9: 101:11 + debug z4 => _22; // in scope 22 at $DIR/unneeded_deref.rs:60:9: 60:11 + let _23: u64; // in scope 22 at $DIR/unneeded_deref.rs:61:9: 61:11 scope 23 { - debug z5 => _23; // in scope 23 at $DIR/unneeded_deref.rs:101:9: 101:11 - let _24: u64; // in scope 23 at $DIR/unneeded_deref.rs:102:9: 102:11 + debug z5 => _23; // in scope 23 at $DIR/unneeded_deref.rs:61:9: 61:11 + let _24: u64; // in scope 23 at $DIR/unneeded_deref.rs:62:9: 62:11 scope 24 { - debug z6 => _24; // in scope 24 at $DIR/unneeded_deref.rs:102:9: 102:11 - let _25: u64; // in scope 24 at $DIR/unneeded_deref.rs:103:9: 103:11 + debug z6 => _24; // in scope 24 at $DIR/unneeded_deref.rs:62:9: 62:11 + let _25: u64; // in scope 24 at $DIR/unneeded_deref.rs:63:9: 63:11 scope 25 { - debug z7 => _25; // in scope 25 at $DIR/unneeded_deref.rs:103:9: 103:11 - let _26: u64; // in scope 25 at $DIR/unneeded_deref.rs:104:9: 104:11 + debug z7 => _25; // in scope 25 at $DIR/unneeded_deref.rs:63:9: 63:11 + let _26: u64; // in scope 25 at $DIR/unneeded_deref.rs:64:9: 64:11 scope 26 { - debug z8 => _26; // in scope 26 at $DIR/unneeded_deref.rs:104:9: 104:11 - let _27: u64; // in scope 26 at $DIR/unneeded_deref.rs:105:9: 105:11 + debug z8 => _26; // in scope 26 at $DIR/unneeded_deref.rs:64:9: 64:11 + let _27: u64; // in scope 26 at $DIR/unneeded_deref.rs:65:9: 65:11 scope 27 { - debug z9 => _27; // in scope 27 at $DIR/unneeded_deref.rs:105:9: 105:11 + debug z9 => _27; // in scope 27 at $DIR/unneeded_deref.rs:65:9: 65:11 } } } @@ -122,133 +122,133 @@ } bb0: { - StorageLive(_1); // scope 0 at $DIR/unneeded_deref.rs:79:9: 79:11 - _1 = const 1_u64; // scope 0 at $DIR/unneeded_deref.rs:79:14: 79:15 - StorageLive(_2); // scope 1 at $DIR/unneeded_deref.rs:80:9: 80:11 - _2 = const 2_u64; // scope 1 at $DIR/unneeded_deref.rs:80:14: 80:15 - StorageLive(_3); // scope 2 at $DIR/unneeded_deref.rs:81:9: 81:11 - _3 = const 3_u64; // scope 2 at $DIR/unneeded_deref.rs:81:14: 81:15 - StorageLive(_4); // scope 3 at $DIR/unneeded_deref.rs:82:9: 82:11 - _4 = const 4_u64; // scope 3 at $DIR/unneeded_deref.rs:82:14: 82:15 - StorageLive(_5); // scope 4 at $DIR/unneeded_deref.rs:83:9: 83:11 - _5 = const 5_u64; // scope 4 at $DIR/unneeded_deref.rs:83:14: 83:15 - StorageLive(_6); // scope 5 at $DIR/unneeded_deref.rs:84:9: 84:11 - _6 = const 6_u64; // scope 5 at $DIR/unneeded_deref.rs:84:14: 84:15 - StorageLive(_7); // scope 6 at $DIR/unneeded_deref.rs:85:9: 85:11 - _7 = const 7_u64; // scope 6 at $DIR/unneeded_deref.rs:85:14: 85:15 - StorageLive(_8); // scope 7 at $DIR/unneeded_deref.rs:86:9: 86:11 - _8 = const 8_u64; // scope 7 at $DIR/unneeded_deref.rs:86:14: 86:15 - StorageLive(_9); // scope 8 at $DIR/unneeded_deref.rs:87:9: 87:11 - _9 = const 9_u64; // scope 8 at $DIR/unneeded_deref.rs:87:14: 87:15 - StorageLive(_10); // scope 9 at $DIR/unneeded_deref.rs:88:9: 88:11 - _10 = &_1; // scope 9 at $DIR/unneeded_deref.rs:88:14: 88:17 - StorageLive(_11); // scope 10 at $DIR/unneeded_deref.rs:89:9: 89:11 - _11 = &_2; // scope 10 at $DIR/unneeded_deref.rs:89:14: 89:17 - StorageLive(_12); // scope 11 at $DIR/unneeded_deref.rs:90:9: 90:11 - _12 = &_3; // scope 11 at $DIR/unneeded_deref.rs:90:14: 90:17 - StorageLive(_13); // scope 12 at $DIR/unneeded_deref.rs:91:9: 91:11 - _13 = &_4; // scope 12 at $DIR/unneeded_deref.rs:91:14: 91:17 - StorageLive(_14); // scope 13 at $DIR/unneeded_deref.rs:92:9: 92:11 - _14 = &_5; // scope 13 at $DIR/unneeded_deref.rs:92:14: 92:17 - StorageLive(_15); // scope 14 at $DIR/unneeded_deref.rs:93:9: 93:11 - _15 = &_6; // scope 14 at $DIR/unneeded_deref.rs:93:14: 93:17 - StorageLive(_16); // scope 15 at $DIR/unneeded_deref.rs:94:9: 94:11 - _16 = &_7; // scope 15 at $DIR/unneeded_deref.rs:94:14: 94:17 - StorageLive(_17); // scope 16 at $DIR/unneeded_deref.rs:95:9: 95:11 - _17 = &_8; // scope 16 at $DIR/unneeded_deref.rs:95:14: 95:17 - StorageLive(_18); // scope 17 at $DIR/unneeded_deref.rs:96:9: 96:11 - _18 = &_9; // scope 17 at $DIR/unneeded_deref.rs:96:14: 96:17 - StorageLive(_19); // scope 18 at $DIR/unneeded_deref.rs:97:9: 97:11 -- _19 = (*_10); // scope 18 at $DIR/unneeded_deref.rs:97:14: 97:17 -+ _19 = _1; // scope 18 at $DIR/unneeded_deref.rs:97:14: 97:17 - StorageLive(_20); // scope 19 at $DIR/unneeded_deref.rs:98:9: 98:11 -- _20 = (*_11); // scope 19 at $DIR/unneeded_deref.rs:98:14: 98:17 -+ _20 = _2; // scope 19 at $DIR/unneeded_deref.rs:98:14: 98:17 - StorageLive(_21); // scope 20 at $DIR/unneeded_deref.rs:99:9: 99:11 -- _21 = (*_12); // scope 20 at $DIR/unneeded_deref.rs:99:14: 99:17 -+ _21 = _3; // scope 20 at $DIR/unneeded_deref.rs:99:14: 99:17 - StorageLive(_22); // scope 21 at $DIR/unneeded_deref.rs:100:9: 100:11 -- _22 = (*_13); // scope 21 at $DIR/unneeded_deref.rs:100:14: 100:17 -+ _22 = _4; // scope 21 at $DIR/unneeded_deref.rs:100:14: 100:17 - StorageLive(_23); // scope 22 at $DIR/unneeded_deref.rs:101:9: 101:11 -- _23 = (*_14); // scope 22 at $DIR/unneeded_deref.rs:101:14: 101:17 -+ _23 = _5; // scope 22 at $DIR/unneeded_deref.rs:101:14: 101:17 - StorageLive(_24); // scope 23 at $DIR/unneeded_deref.rs:102:9: 102:11 -- _24 = (*_15); // scope 23 at $DIR/unneeded_deref.rs:102:14: 102:17 -+ _24 = _6; // scope 23 at $DIR/unneeded_deref.rs:102:14: 102:17 - StorageLive(_25); // scope 24 at $DIR/unneeded_deref.rs:103:9: 103:11 -- _25 = (*_16); // scope 24 at $DIR/unneeded_deref.rs:103:14: 103:17 -+ _25 = _7; // scope 24 at $DIR/unneeded_deref.rs:103:14: 103:17 - StorageLive(_26); // scope 25 at $DIR/unneeded_deref.rs:104:9: 104:11 -- _26 = (*_17); // scope 25 at $DIR/unneeded_deref.rs:104:14: 104:17 -+ _26 = _8; // scope 25 at $DIR/unneeded_deref.rs:104:14: 104:17 - StorageLive(_27); // scope 26 at $DIR/unneeded_deref.rs:105:9: 105:11 -- _27 = (*_18); // scope 26 at $DIR/unneeded_deref.rs:105:14: 105:17 -+ _27 = _9; // scope 26 at $DIR/unneeded_deref.rs:105:14: 105:17 - StorageLive(_28); // scope 27 at $DIR/unneeded_deref.rs:106:6: 106:8 - _28 = _19; // scope 27 at $DIR/unneeded_deref.rs:106:6: 106:8 - StorageLive(_29); // scope 27 at $DIR/unneeded_deref.rs:106:10: 106:12 - _29 = _20; // scope 27 at $DIR/unneeded_deref.rs:106:10: 106:12 - StorageLive(_30); // scope 27 at $DIR/unneeded_deref.rs:106:14: 106:16 - _30 = _21; // scope 27 at $DIR/unneeded_deref.rs:106:14: 106:16 - StorageLive(_31); // scope 27 at $DIR/unneeded_deref.rs:106:18: 106:20 - _31 = _22; // scope 27 at $DIR/unneeded_deref.rs:106:18: 106:20 - StorageLive(_32); // scope 27 at $DIR/unneeded_deref.rs:106:22: 106:24 - _32 = _23; // scope 27 at $DIR/unneeded_deref.rs:106:22: 106:24 - StorageLive(_33); // scope 27 at $DIR/unneeded_deref.rs:106:26: 106:28 - _33 = _24; // scope 27 at $DIR/unneeded_deref.rs:106:26: 106:28 - StorageLive(_34); // scope 27 at $DIR/unneeded_deref.rs:106:30: 106:32 - _34 = _25; // scope 27 at $DIR/unneeded_deref.rs:106:30: 106:32 - StorageLive(_35); // scope 27 at $DIR/unneeded_deref.rs:106:34: 106:36 - _35 = _26; // scope 27 at $DIR/unneeded_deref.rs:106:34: 106:36 - StorageLive(_36); // scope 27 at $DIR/unneeded_deref.rs:106:38: 106:40 - _36 = _27; // scope 27 at $DIR/unneeded_deref.rs:106:38: 106:40 - (_0.0: u64) = move _28; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 - (_0.1: u64) = move _29; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 - (_0.2: u64) = move _30; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 - (_0.3: u64) = move _31; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 - (_0.4: u64) = move _32; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 - (_0.5: u64) = move _33; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 - (_0.6: u64) = move _34; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 - (_0.7: u64) = move _35; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 - (_0.8: u64) = move _36; // scope 27 at $DIR/unneeded_deref.rs:106:5: 106:41 - StorageDead(_36); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 - StorageDead(_35); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 - StorageDead(_34); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 - StorageDead(_33); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 - StorageDead(_32); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 - StorageDead(_31); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 - StorageDead(_30); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 - StorageDead(_29); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 - StorageDead(_28); // scope 27 at $DIR/unneeded_deref.rs:106:40: 106:41 - StorageDead(_27); // scope 26 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_26); // scope 25 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_25); // scope 24 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_24); // scope 23 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_23); // scope 22 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_22); // scope 21 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_21); // scope 20 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_20); // scope 19 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_19); // scope 18 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_18); // scope 17 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_17); // scope 16 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_16); // scope 15 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_15); // scope 14 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_14); // scope 13 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_13); // scope 12 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_12); // scope 11 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_11); // scope 10 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_10); // scope 9 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_9); // scope 8 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_8); // scope 7 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_7); // scope 6 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_6); // scope 5 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_5); // scope 4 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_4); // scope 3 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_3); // scope 2 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_2); // scope 1 at $DIR/unneeded_deref.rs:107:1: 107:2 - StorageDead(_1); // scope 0 at $DIR/unneeded_deref.rs:107:1: 107:2 - return; // scope 0 at $DIR/unneeded_deref.rs:107:2: 107:2 + StorageLive(_1); // scope 0 at $DIR/unneeded_deref.rs:39:9: 39:11 + _1 = const 1_u64; // scope 0 at $DIR/unneeded_deref.rs:39:14: 39:15 + StorageLive(_2); // scope 1 at $DIR/unneeded_deref.rs:40:9: 40:11 + _2 = const 2_u64; // scope 1 at $DIR/unneeded_deref.rs:40:14: 40:15 + StorageLive(_3); // scope 2 at $DIR/unneeded_deref.rs:41:9: 41:11 + _3 = const 3_u64; // scope 2 at $DIR/unneeded_deref.rs:41:14: 41:15 + StorageLive(_4); // scope 3 at $DIR/unneeded_deref.rs:42:9: 42:11 + _4 = const 4_u64; // scope 3 at $DIR/unneeded_deref.rs:42:14: 42:15 + StorageLive(_5); // scope 4 at $DIR/unneeded_deref.rs:43:9: 43:11 + _5 = const 5_u64; // scope 4 at $DIR/unneeded_deref.rs:43:14: 43:15 + StorageLive(_6); // scope 5 at $DIR/unneeded_deref.rs:44:9: 44:11 + _6 = const 6_u64; // scope 5 at $DIR/unneeded_deref.rs:44:14: 44:15 + StorageLive(_7); // scope 6 at $DIR/unneeded_deref.rs:45:9: 45:11 + _7 = const 7_u64; // scope 6 at $DIR/unneeded_deref.rs:45:14: 45:15 + StorageLive(_8); // scope 7 at $DIR/unneeded_deref.rs:46:9: 46:11 + _8 = const 8_u64; // scope 7 at $DIR/unneeded_deref.rs:46:14: 46:15 + StorageLive(_9); // scope 8 at $DIR/unneeded_deref.rs:47:9: 47:11 + _9 = const 9_u64; // scope 8 at $DIR/unneeded_deref.rs:47:14: 47:15 + StorageLive(_10); // scope 9 at $DIR/unneeded_deref.rs:48:9: 48:11 + _10 = &_1; // scope 9 at $DIR/unneeded_deref.rs:48:14: 48:17 + StorageLive(_11); // scope 10 at $DIR/unneeded_deref.rs:49:9: 49:11 + _11 = &_2; // scope 10 at $DIR/unneeded_deref.rs:49:14: 49:17 + StorageLive(_12); // scope 11 at $DIR/unneeded_deref.rs:50:9: 50:11 + _12 = &_3; // scope 11 at $DIR/unneeded_deref.rs:50:14: 50:17 + StorageLive(_13); // scope 12 at $DIR/unneeded_deref.rs:51:9: 51:11 + _13 = &_4; // scope 12 at $DIR/unneeded_deref.rs:51:14: 51:17 + StorageLive(_14); // scope 13 at $DIR/unneeded_deref.rs:52:9: 52:11 + _14 = &_5; // scope 13 at $DIR/unneeded_deref.rs:52:14: 52:17 + StorageLive(_15); // scope 14 at $DIR/unneeded_deref.rs:53:9: 53:11 + _15 = &_6; // scope 14 at $DIR/unneeded_deref.rs:53:14: 53:17 + StorageLive(_16); // scope 15 at $DIR/unneeded_deref.rs:54:9: 54:11 + _16 = &_7; // scope 15 at $DIR/unneeded_deref.rs:54:14: 54:17 + StorageLive(_17); // scope 16 at $DIR/unneeded_deref.rs:55:9: 55:11 + _17 = &_8; // scope 16 at $DIR/unneeded_deref.rs:55:14: 55:17 + StorageLive(_18); // scope 17 at $DIR/unneeded_deref.rs:56:9: 56:11 + _18 = &_9; // scope 17 at $DIR/unneeded_deref.rs:56:14: 56:17 + StorageLive(_19); // scope 18 at $DIR/unneeded_deref.rs:57:9: 57:11 +- _19 = (*_10); // scope 18 at $DIR/unneeded_deref.rs:57:14: 57:17 ++ _19 = _1; // scope 18 at $DIR/unneeded_deref.rs:57:14: 57:17 + StorageLive(_20); // scope 19 at $DIR/unneeded_deref.rs:58:9: 58:11 +- _20 = (*_11); // scope 19 at $DIR/unneeded_deref.rs:58:14: 58:17 ++ _20 = _2; // scope 19 at $DIR/unneeded_deref.rs:58:14: 58:17 + StorageLive(_21); // scope 20 at $DIR/unneeded_deref.rs:59:9: 59:11 +- _21 = (*_12); // scope 20 at $DIR/unneeded_deref.rs:59:14: 59:17 ++ _21 = _3; // scope 20 at $DIR/unneeded_deref.rs:59:14: 59:17 + StorageLive(_22); // scope 21 at $DIR/unneeded_deref.rs:60:9: 60:11 +- _22 = (*_13); // scope 21 at $DIR/unneeded_deref.rs:60:14: 60:17 ++ _22 = _4; // scope 21 at $DIR/unneeded_deref.rs:60:14: 60:17 + StorageLive(_23); // scope 22 at $DIR/unneeded_deref.rs:61:9: 61:11 +- _23 = (*_14); // scope 22 at $DIR/unneeded_deref.rs:61:14: 61:17 ++ _23 = _5; // scope 22 at $DIR/unneeded_deref.rs:61:14: 61:17 + StorageLive(_24); // scope 23 at $DIR/unneeded_deref.rs:62:9: 62:11 +- _24 = (*_15); // scope 23 at $DIR/unneeded_deref.rs:62:14: 62:17 ++ _24 = _6; // scope 23 at $DIR/unneeded_deref.rs:62:14: 62:17 + StorageLive(_25); // scope 24 at $DIR/unneeded_deref.rs:63:9: 63:11 +- _25 = (*_16); // scope 24 at $DIR/unneeded_deref.rs:63:14: 63:17 ++ _25 = _7; // scope 24 at $DIR/unneeded_deref.rs:63:14: 63:17 + StorageLive(_26); // scope 25 at $DIR/unneeded_deref.rs:64:9: 64:11 +- _26 = (*_17); // scope 25 at $DIR/unneeded_deref.rs:64:14: 64:17 ++ _26 = _8; // scope 25 at $DIR/unneeded_deref.rs:64:14: 64:17 + StorageLive(_27); // scope 26 at $DIR/unneeded_deref.rs:65:9: 65:11 +- _27 = (*_18); // scope 26 at $DIR/unneeded_deref.rs:65:14: 65:17 ++ _27 = _9; // scope 26 at $DIR/unneeded_deref.rs:65:14: 65:17 + StorageLive(_28); // scope 27 at $DIR/unneeded_deref.rs:66:6: 66:8 + _28 = _19; // scope 27 at $DIR/unneeded_deref.rs:66:6: 66:8 + StorageLive(_29); // scope 27 at $DIR/unneeded_deref.rs:66:10: 66:12 + _29 = _20; // scope 27 at $DIR/unneeded_deref.rs:66:10: 66:12 + StorageLive(_30); // scope 27 at $DIR/unneeded_deref.rs:66:14: 66:16 + _30 = _21; // scope 27 at $DIR/unneeded_deref.rs:66:14: 66:16 + StorageLive(_31); // scope 27 at $DIR/unneeded_deref.rs:66:18: 66:20 + _31 = _22; // scope 27 at $DIR/unneeded_deref.rs:66:18: 66:20 + StorageLive(_32); // scope 27 at $DIR/unneeded_deref.rs:66:22: 66:24 + _32 = _23; // scope 27 at $DIR/unneeded_deref.rs:66:22: 66:24 + StorageLive(_33); // scope 27 at $DIR/unneeded_deref.rs:66:26: 66:28 + _33 = _24; // scope 27 at $DIR/unneeded_deref.rs:66:26: 66:28 + StorageLive(_34); // scope 27 at $DIR/unneeded_deref.rs:66:30: 66:32 + _34 = _25; // scope 27 at $DIR/unneeded_deref.rs:66:30: 66:32 + StorageLive(_35); // scope 27 at $DIR/unneeded_deref.rs:66:34: 66:36 + _35 = _26; // scope 27 at $DIR/unneeded_deref.rs:66:34: 66:36 + StorageLive(_36); // scope 27 at $DIR/unneeded_deref.rs:66:38: 66:40 + _36 = _27; // scope 27 at $DIR/unneeded_deref.rs:66:38: 66:40 + (_0.0: u64) = move _28; // scope 27 at $DIR/unneeded_deref.rs:66:5: 66:41 + (_0.1: u64) = move _29; // scope 27 at $DIR/unneeded_deref.rs:66:5: 66:41 + (_0.2: u64) = move _30; // scope 27 at $DIR/unneeded_deref.rs:66:5: 66:41 + (_0.3: u64) = move _31; // scope 27 at $DIR/unneeded_deref.rs:66:5: 66:41 + (_0.4: u64) = move _32; // scope 27 at $DIR/unneeded_deref.rs:66:5: 66:41 + (_0.5: u64) = move _33; // scope 27 at $DIR/unneeded_deref.rs:66:5: 66:41 + (_0.6: u64) = move _34; // scope 27 at $DIR/unneeded_deref.rs:66:5: 66:41 + (_0.7: u64) = move _35; // scope 27 at $DIR/unneeded_deref.rs:66:5: 66:41 + (_0.8: u64) = move _36; // scope 27 at $DIR/unneeded_deref.rs:66:5: 66:41 + StorageDead(_36); // scope 27 at $DIR/unneeded_deref.rs:66:40: 66:41 + StorageDead(_35); // scope 27 at $DIR/unneeded_deref.rs:66:40: 66:41 + StorageDead(_34); // scope 27 at $DIR/unneeded_deref.rs:66:40: 66:41 + StorageDead(_33); // scope 27 at $DIR/unneeded_deref.rs:66:40: 66:41 + StorageDead(_32); // scope 27 at $DIR/unneeded_deref.rs:66:40: 66:41 + StorageDead(_31); // scope 27 at $DIR/unneeded_deref.rs:66:40: 66:41 + StorageDead(_30); // scope 27 at $DIR/unneeded_deref.rs:66:40: 66:41 + StorageDead(_29); // scope 27 at $DIR/unneeded_deref.rs:66:40: 66:41 + StorageDead(_28); // scope 27 at $DIR/unneeded_deref.rs:66:40: 66:41 + StorageDead(_27); // scope 26 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_26); // scope 25 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_25); // scope 24 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_24); // scope 23 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_23); // scope 22 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_22); // scope 21 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_21); // scope 20 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_20); // scope 19 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_19); // scope 18 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_18); // scope 17 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_17); // scope 16 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_16); // scope 15 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_15); // scope 14 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_14); // scope 13 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_13); // scope 12 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_12); // scope 11 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_11); // scope 10 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_10); // scope 9 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_9); // scope 8 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_8); // scope 7 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_7); // scope 6 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_6); // scope 5 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_5); // scope 4 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_4); // scope 3 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_3); // scope 2 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_2); // scope 1 at $DIR/unneeded_deref.rs:67:1: 67:2 + StorageDead(_1); // scope 0 at $DIR/unneeded_deref.rs:67:1: 67:2 + return; // scope 0 at $DIR/unneeded_deref.rs:67:2: 67:2 } } diff --git a/src/test/mir-opt/unneeded_deref.do_not_miscompile.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref_do_not_opt.do_not_miscompile.UnneededDeref.diff similarity index 71% rename from src/test/mir-opt/unneeded_deref.do_not_miscompile.UnneededDeref.diff rename to src/test/mir-opt/unneeded_deref_do_not_opt.do_not_miscompile.UnneededDeref.diff index 61576bfeca37a..0a43a9b0164f0 100644 --- a/src/test/mir-opt/unneeded_deref.do_not_miscompile.UnneededDeref.diff +++ b/src/test/mir-opt/unneeded_deref_do_not_opt.do_not_miscompile.UnneededDeref.diff @@ -2,69 +2,69 @@ + // MIR for `do_not_miscompile` after UnneededDeref fn do_not_miscompile() -> () { - let mut _0: (); // return place in scope 0 at $DIR/unneeded_deref.rs:54:24: 54:24 - let _1: i32; // in scope 0 at $DIR/unneeded_deref.rs:55:9: 55:10 - let mut _5: &i32; // in scope 0 at $DIR/unneeded_deref.rs:59:10: 59:12 - let _6: &i32; // in scope 0 at $DIR/unneeded_deref.rs:59:10: 59:12 - let _7: (); // in scope 0 at $DIR/unneeded_deref.rs:60:5: 60:23 - let mut _8: bool; // in scope 0 at $DIR/unneeded_deref.rs:60:5: 60:23 - let mut _9: bool; // in scope 0 at $DIR/unneeded_deref.rs:60:13: 60:21 - let mut _10: i32; // in scope 0 at $DIR/unneeded_deref.rs:60:13: 60:15 + let mut _0: (); // return place in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:20:24: 20:24 + let _1: i32; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:21:9: 21:10 + let mut _5: &i32; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:25:10: 25:12 + let _6: &i32; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:25:10: 25:12 + let _7: (); // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:26:5: 26:23 + let mut _8: bool; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:26:5: 26:23 + let mut _9: bool; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:26:13: 26:21 + let mut _10: i32; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:26:13: 26:15 let mut _11: !; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL scope 1 { - debug x => _1; // in scope 1 at $DIR/unneeded_deref.rs:55:9: 55:10 - let _2: i32; // in scope 1 at $DIR/unneeded_deref.rs:56:9: 56:10 + debug x => _1; // in scope 1 at $DIR/unneeded_deref_do_not_opt.rs:21:9: 21:10 + let _2: i32; // in scope 1 at $DIR/unneeded_deref_do_not_opt.rs:22:9: 22:10 scope 2 { - debug a => _2; // in scope 2 at $DIR/unneeded_deref.rs:56:9: 56:10 - let mut _3: &i32; // in scope 2 at $DIR/unneeded_deref.rs:57:9: 57:14 + debug a => _2; // in scope 2 at $DIR/unneeded_deref_do_not_opt.rs:22:9: 22:10 + let mut _3: &i32; // in scope 2 at $DIR/unneeded_deref_do_not_opt.rs:23:9: 23:14 scope 3 { - debug y => _3; // in scope 3 at $DIR/unneeded_deref.rs:57:9: 57:14 - let _4: &mut &i32; // in scope 3 at $DIR/unneeded_deref.rs:58:9: 58:10 + debug y => _3; // in scope 3 at $DIR/unneeded_deref_do_not_opt.rs:23:9: 23:14 + let _4: &mut &i32; // in scope 3 at $DIR/unneeded_deref_do_not_opt.rs:24:9: 24:10 scope 4 { - debug z => _4; // in scope 4 at $DIR/unneeded_deref.rs:58:9: 58:10 + debug z => _4; // in scope 4 at $DIR/unneeded_deref_do_not_opt.rs:24:9: 24:10 } } } } bb0: { - StorageLive(_1); // scope 0 at $DIR/unneeded_deref.rs:55:9: 55:10 - _1 = const 42_i32; // scope 0 at $DIR/unneeded_deref.rs:55:13: 55:15 - StorageLive(_2); // scope 1 at $DIR/unneeded_deref.rs:56:9: 56:10 - _2 = const 99_i32; // scope 1 at $DIR/unneeded_deref.rs:56:13: 56:15 - StorageLive(_3); // scope 2 at $DIR/unneeded_deref.rs:57:9: 57:14 - _3 = &_1; // scope 2 at $DIR/unneeded_deref.rs:57:17: 57:19 - StorageLive(_4); // scope 3 at $DIR/unneeded_deref.rs:58:9: 58:10 - _4 = &mut _3; // scope 3 at $DIR/unneeded_deref.rs:58:13: 58:19 - StorageLive(_5); // scope 4 at $DIR/unneeded_deref.rs:59:10: 59:12 - StorageLive(_6); // scope 4 at $DIR/unneeded_deref.rs:59:10: 59:12 - _6 = &_2; // scope 4 at $DIR/unneeded_deref.rs:59:10: 59:12 - _5 = _6; // scope 4 at $DIR/unneeded_deref.rs:59:10: 59:12 - (*_4) = move _5; // scope 4 at $DIR/unneeded_deref.rs:59:5: 59:12 - StorageDead(_5); // scope 4 at $DIR/unneeded_deref.rs:59:11: 59:12 - StorageDead(_6); // scope 4 at $DIR/unneeded_deref.rs:59:12: 59:13 - StorageLive(_7); // scope 4 at $DIR/unneeded_deref.rs:60:5: 60:23 - StorageLive(_8); // scope 4 at $DIR/unneeded_deref.rs:60:5: 60:23 - StorageLive(_9); // scope 4 at $DIR/unneeded_deref.rs:60:13: 60:21 - StorageLive(_10); // scope 4 at $DIR/unneeded_deref.rs:60:13: 60:15 - _10 = (*_3); // scope 4 at $DIR/unneeded_deref.rs:60:13: 60:15 - _9 = Eq(move _10, const 99_i32); // scope 4 at $DIR/unneeded_deref.rs:60:13: 60:21 - StorageDead(_10); // scope 4 at $DIR/unneeded_deref.rs:60:20: 60:21 - _8 = Not(move _9); // scope 4 at $DIR/unneeded_deref.rs:60:5: 60:23 - StorageDead(_9); // scope 4 at $DIR/unneeded_deref.rs:60:22: 60:23 - switchInt(_8) -> [false: bb1, otherwise: bb2]; // scope 4 at $DIR/unneeded_deref.rs:60:5: 60:23 + StorageLive(_1); // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:21:9: 21:10 + _1 = const 42_i32; // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:21:13: 21:15 + StorageLive(_2); // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:22:9: 22:10 + _2 = const 99_i32; // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:22:13: 22:15 + StorageLive(_3); // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:23:9: 23:14 + _3 = &_1; // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:23:17: 23:19 + StorageLive(_4); // scope 3 at $DIR/unneeded_deref_do_not_opt.rs:24:9: 24:10 + _4 = &mut _3; // scope 3 at $DIR/unneeded_deref_do_not_opt.rs:24:13: 24:19 + StorageLive(_5); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:25:10: 25:12 + StorageLive(_6); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:25:10: 25:12 + _6 = &_2; // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:25:10: 25:12 + _5 = _6; // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:25:10: 25:12 + (*_4) = move _5; // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:25:5: 25:12 + StorageDead(_5); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:25:11: 25:12 + StorageDead(_6); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:25:12: 25:13 + StorageLive(_7); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:26:5: 26:23 + StorageLive(_8); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:26:5: 26:23 + StorageLive(_9); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:26:13: 26:21 + StorageLive(_10); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:26:13: 26:15 + _10 = (*_3); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:26:13: 26:15 + _9 = Eq(move _10, const 99_i32); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:26:13: 26:21 + StorageDead(_10); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:26:20: 26:21 + _8 = Not(move _9); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:26:5: 26:23 + StorageDead(_9); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:26:22: 26:23 + switchInt(_8) -> [false: bb1, otherwise: bb2]; // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:26:5: 26:23 } bb1: { - _7 = const (); // scope 4 at $DIR/unneeded_deref.rs:60:5: 60:23 - StorageDead(_8); // scope 4 at $DIR/unneeded_deref.rs:60:22: 60:23 - StorageDead(_7); // scope 4 at $DIR/unneeded_deref.rs:60:22: 60:23 - _0 = const (); // scope 0 at $DIR/unneeded_deref.rs:54:24: 61:2 - StorageDead(_4); // scope 3 at $DIR/unneeded_deref.rs:61:1: 61:2 - StorageDead(_3); // scope 2 at $DIR/unneeded_deref.rs:61:1: 61:2 - StorageDead(_2); // scope 1 at $DIR/unneeded_deref.rs:61:1: 61:2 - StorageDead(_1); // scope 0 at $DIR/unneeded_deref.rs:61:1: 61:2 - return; // scope 0 at $DIR/unneeded_deref.rs:61:2: 61:2 + _7 = const (); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:26:5: 26:23 + StorageDead(_8); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:26:22: 26:23 + StorageDead(_7); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:26:22: 26:23 + _0 = const (); // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:20:24: 27:2 + StorageDead(_4); // scope 3 at $DIR/unneeded_deref_do_not_opt.rs:27:1: 27:2 + StorageDead(_3); // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:27:1: 27:2 + StorageDead(_2); // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:27:1: 27:2 + StorageDead(_1); // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:27:1: 27:2 + return; // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:27:2: 27:2 } bb2: { @@ -77,7 +77,7 @@ // + ty: &str // + val: Value(Slice { data: Allocation { bytes: [97, 115, 115, 101, 114, 116, 105, 111, 110, 32, 102, 97, 105, 108, 101, 100, 58, 32, 42, 121, 32, 61, 61, 32, 57, 57], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [67108863], len: Size { raw: 26 } }, size: Size { raw: 26 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 26 }) // mir::Constant - // + span: $DIR/unneeded_deref.rs:1:1: 1:1 + // + span: $DIR/unneeded_deref_do_not_opt.rs:1:1: 1:1 // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [97, 115, 115, 101, 114, 116, 105, 111, 110, 32, 102, 97, 105, 108, 101, 100, 58, 32, 42, 121, 32, 61, 61, 32, 57, 57], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [67108863], len: Size { raw: 26 } }, size: Size { raw: 26 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 26 }) } } } diff --git a/src/test/mir-opt/unneeded_deref.do_not_miscompile_mut_ref.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref_do_not_opt.do_not_miscompile_mut_ref.UnneededDeref.diff similarity index 64% rename from src/test/mir-opt/unneeded_deref.do_not_miscompile_mut_ref.UnneededDeref.diff rename to src/test/mir-opt/unneeded_deref_do_not_opt.do_not_miscompile_mut_ref.UnneededDeref.diff index f740736247c41..beddd2fe3010e 100644 --- a/src/test/mir-opt/unneeded_deref.do_not_miscompile_mut_ref.UnneededDeref.diff +++ b/src/test/mir-opt/unneeded_deref_do_not_opt.do_not_miscompile_mut_ref.UnneededDeref.diff @@ -2,28 +2,28 @@ + // MIR for `do_not_miscompile_mut_ref` after UnneededDeref fn do_not_miscompile_mut_ref() -> () { - let mut _0: (); // return place in scope 0 at $DIR/unneeded_deref.rs:65:32: 65:32 - let _1: u32; // in scope 0 at $DIR/unneeded_deref.rs:66:9: 66:10 - let _4: &u32; // in scope 0 at $DIR/unneeded_deref.rs:69:29: 69:31 - let _6: &u32; // in scope 0 at $DIR/unneeded_deref.rs:70:19: 70:21 - let mut _8: *const u32; // in scope 0 at $DIR/unneeded_deref.rs:73:9: 73:10 + let mut _0: (); // return place in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:31:32: 31:32 + let _1: u32; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:32:9: 32:10 + let _4: &u32; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:35:29: 35:31 + let _6: &u32; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:36:19: 36:21 + let mut _8: *const u32; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:39:9: 39:10 scope 1 { - debug a => _1; // in scope 1 at $DIR/unneeded_deref.rs:66:9: 66:10 - let _2: u32; // in scope 1 at $DIR/unneeded_deref.rs:67:9: 67:10 + debug a => _1; // in scope 1 at $DIR/unneeded_deref_do_not_opt.rs:32:9: 32:10 + let _2: u32; // in scope 1 at $DIR/unneeded_deref_do_not_opt.rs:33:9: 33:10 scope 2 { - debug b => _2; // in scope 2 at $DIR/unneeded_deref.rs:67:9: 67:10 - let mut _3: *const u32; // in scope 2 at $DIR/unneeded_deref.rs:69:9: 69:14 + debug b => _2; // in scope 2 at $DIR/unneeded_deref_do_not_opt.rs:33:9: 33:10 + let mut _3: *const u32; // in scope 2 at $DIR/unneeded_deref_do_not_opt.rs:35:9: 35:14 scope 3 { - debug c => _3; // in scope 3 at $DIR/unneeded_deref.rs:69:9: 69:14 - let _5: &u32; // in scope 3 at $DIR/unneeded_deref.rs:70:9: 70:10 + debug c => _3; // in scope 3 at $DIR/unneeded_deref_do_not_opt.rs:35:9: 35:14 + let _5: &u32; // in scope 3 at $DIR/unneeded_deref_do_not_opt.rs:36:9: 36:10 scope 4 { - debug d => _5; // in scope 4 at $DIR/unneeded_deref.rs:70:9: 70:10 - let _7: &u32; // in scope 4 at $DIR/unneeded_deref.rs:72:9: 72:10 + debug d => _5; // in scope 4 at $DIR/unneeded_deref_do_not_opt.rs:36:9: 36:10 + let _7: &u32; // in scope 4 at $DIR/unneeded_deref_do_not_opt.rs:38:9: 38:10 scope 5 { - debug x => _7; // in scope 5 at $DIR/unneeded_deref.rs:72:9: 72:10 - let _9: u32; // in scope 5 at $DIR/unneeded_deref.rs:74:9: 74:10 + debug x => _7; // in scope 5 at $DIR/unneeded_deref_do_not_opt.rs:38:9: 38:10 + let _9: u32; // in scope 5 at $DIR/unneeded_deref_do_not_opt.rs:40:9: 40:10 scope 7 { - debug z => _9; // in scope 7 at $DIR/unneeded_deref.rs:74:9: 74:10 + debug z => _9; // in scope 7 at $DIR/unneeded_deref_do_not_opt.rs:40:9: 40:10 } } scope 6 { @@ -34,37 +34,37 @@ } bb0: { - StorageLive(_1); // scope 0 at $DIR/unneeded_deref.rs:66:9: 66:10 - _1 = const 1_u32; // scope 0 at $DIR/unneeded_deref.rs:66:13: 66:17 - StorageLive(_2); // scope 1 at $DIR/unneeded_deref.rs:67:9: 67:10 - _2 = const 2_u32; // scope 1 at $DIR/unneeded_deref.rs:67:13: 67:17 - StorageLive(_3); // scope 2 at $DIR/unneeded_deref.rs:69:9: 69:14 - StorageLive(_4); // scope 2 at $DIR/unneeded_deref.rs:69:29: 69:31 - _4 = &_1; // scope 2 at $DIR/unneeded_deref.rs:69:29: 69:31 -- _3 = &raw const (*_4); // scope 2 at $DIR/unneeded_deref.rs:69:29: 69:31 -+ _3 = &raw const _1; // scope 2 at $DIR/unneeded_deref.rs:69:29: 69:31 - StorageDead(_4); // scope 2 at $DIR/unneeded_deref.rs:69:31: 69:32 - StorageLive(_5); // scope 3 at $DIR/unneeded_deref.rs:70:9: 70:10 - StorageLive(_6); // scope 3 at $DIR/unneeded_deref.rs:70:19: 70:21 - _6 = &_2; // scope 3 at $DIR/unneeded_deref.rs:70:19: 70:21 - _5 = _6; // scope 3 at $DIR/unneeded_deref.rs:70:19: 70:21 - StorageDead(_6); // scope 3 at $DIR/unneeded_deref.rs:70:21: 70:22 - StorageLive(_7); // scope 4 at $DIR/unneeded_deref.rs:72:9: 72:10 - _7 = &(*_3); // scope 6 at $DIR/unneeded_deref.rs:72:22: 72:25 - StorageLive(_8); // scope 5 at $DIR/unneeded_deref.rs:73:9: 73:10 - _8 = &raw const (*_5); // scope 5 at $DIR/unneeded_deref.rs:73:9: 73:10 - _3 = move _8; // scope 5 at $DIR/unneeded_deref.rs:73:5: 73:10 - StorageDead(_8); // scope 5 at $DIR/unneeded_deref.rs:73:9: 73:10 - StorageLive(_9); // scope 5 at $DIR/unneeded_deref.rs:74:9: 74:10 - _9 = (*_7); // scope 5 at $DIR/unneeded_deref.rs:74:13: 74:15 - _0 = const (); // scope 0 at $DIR/unneeded_deref.rs:65:32: 75:2 - StorageDead(_9); // scope 5 at $DIR/unneeded_deref.rs:75:1: 75:2 - StorageDead(_7); // scope 4 at $DIR/unneeded_deref.rs:75:1: 75:2 - StorageDead(_5); // scope 3 at $DIR/unneeded_deref.rs:75:1: 75:2 - StorageDead(_3); // scope 2 at $DIR/unneeded_deref.rs:75:1: 75:2 - StorageDead(_2); // scope 1 at $DIR/unneeded_deref.rs:75:1: 75:2 - StorageDead(_1); // scope 0 at $DIR/unneeded_deref.rs:75:1: 75:2 - return; // scope 0 at $DIR/unneeded_deref.rs:75:2: 75:2 + StorageLive(_1); // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:32:9: 32:10 + _1 = const 1_u32; // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:32:13: 32:17 + StorageLive(_2); // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:33:9: 33:10 + _2 = const 2_u32; // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:33:13: 33:17 + StorageLive(_3); // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:35:9: 35:14 + StorageLive(_4); // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:35:29: 35:31 + _4 = &_1; // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:35:29: 35:31 +- _3 = &raw const (*_4); // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:35:29: 35:31 ++ _3 = &raw const _1; // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:35:29: 35:31 + StorageDead(_4); // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:35:31: 35:32 + StorageLive(_5); // scope 3 at $DIR/unneeded_deref_do_not_opt.rs:36:9: 36:10 + StorageLive(_6); // scope 3 at $DIR/unneeded_deref_do_not_opt.rs:36:19: 36:21 + _6 = &_2; // scope 3 at $DIR/unneeded_deref_do_not_opt.rs:36:19: 36:21 + _5 = _6; // scope 3 at $DIR/unneeded_deref_do_not_opt.rs:36:19: 36:21 + StorageDead(_6); // scope 3 at $DIR/unneeded_deref_do_not_opt.rs:36:21: 36:22 + StorageLive(_7); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:38:9: 38:10 + _7 = &(*_3); // scope 6 at $DIR/unneeded_deref_do_not_opt.rs:38:22: 38:25 + StorageLive(_8); // scope 5 at $DIR/unneeded_deref_do_not_opt.rs:39:9: 39:10 + _8 = &raw const (*_5); // scope 5 at $DIR/unneeded_deref_do_not_opt.rs:39:9: 39:10 + _3 = move _8; // scope 5 at $DIR/unneeded_deref_do_not_opt.rs:39:5: 39:10 + StorageDead(_8); // scope 5 at $DIR/unneeded_deref_do_not_opt.rs:39:9: 39:10 + StorageLive(_9); // scope 5 at $DIR/unneeded_deref_do_not_opt.rs:40:9: 40:10 + _9 = (*_7); // scope 5 at $DIR/unneeded_deref_do_not_opt.rs:40:13: 40:15 + _0 = const (); // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:31:32: 41:2 + StorageDead(_9); // scope 5 at $DIR/unneeded_deref_do_not_opt.rs:41:1: 41:2 + StorageDead(_7); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:41:1: 41:2 + StorageDead(_5); // scope 3 at $DIR/unneeded_deref_do_not_opt.rs:41:1: 41:2 + StorageDead(_3); // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:41:1: 41:2 + StorageDead(_2); // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:41:1: 41:2 + StorageDead(_1); // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:41:1: 41:2 + return; // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:41:2: 41:2 } } diff --git a/src/test/mir-opt/unneeded_deref.do_not_opt_different_bbs.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref_do_not_opt.do_not_opt_different_bbs.UnneededDeref.diff similarity index 62% rename from src/test/mir-opt/unneeded_deref.do_not_opt_different_bbs.UnneededDeref.diff rename to src/test/mir-opt/unneeded_deref_do_not_opt.do_not_opt_different_bbs.UnneededDeref.diff index e605567785301..39175f537d7a6 100644 --- a/src/test/mir-opt/unneeded_deref.do_not_opt_different_bbs.UnneededDeref.diff +++ b/src/test/mir-opt/unneeded_deref_do_not_opt.do_not_opt_different_bbs.UnneededDeref.diff @@ -2,63 +2,63 @@ + // MIR for `do_not_opt_different_bbs` after UnneededDeref fn do_not_opt_different_bbs(_1: bool) -> u64 { - debug input => _1; // in scope 0 at $DIR/unneeded_deref.rs:134:29: 134:34 - let mut _0: u64; // return place in scope 0 at $DIR/unneeded_deref.rs:134:45: 134:48 - let _2: u64; // in scope 0 at $DIR/unneeded_deref.rs:135:9: 135:10 - let mut _4: bool; // in scope 0 at $DIR/unneeded_deref.rs:136:16: 136:21 - let _5: &u64; // in scope 0 at $DIR/unneeded_deref.rs:136:36: 136:39 - let _6: u64; // in scope 0 at $DIR/unneeded_deref.rs:136:37: 136:39 + debug input => _1; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:51:29: 51:34 + let mut _0: u64; // return place in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:51:45: 51:48 + let _2: u64; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:52:9: 52:10 + let mut _4: bool; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:53:16: 53:21 + let _5: &u64; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:53:36: 53:39 + let _6: u64; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:53:37: 53:39 scope 1 { - debug x => _2; // in scope 1 at $DIR/unneeded_deref.rs:135:9: 135:10 - let _3: &u64; // in scope 1 at $DIR/unneeded_deref.rs:136:9: 136:10 - let mut _8: &u64; // in scope 1 at $DIR/unneeded_deref.rs:136:36: 136:39 + debug x => _2; // in scope 1 at $DIR/unneeded_deref_do_not_opt.rs:52:9: 52:10 + let _3: &u64; // in scope 1 at $DIR/unneeded_deref_do_not_opt.rs:53:9: 53:10 + let mut _8: &u64; // in scope 1 at $DIR/unneeded_deref_do_not_opt.rs:53:36: 53:39 scope 2 { - debug y => _3; // in scope 2 at $DIR/unneeded_deref.rs:136:9: 136:10 - let _7: u64; // in scope 2 at $DIR/unneeded_deref.rs:137:9: 137:10 + debug y => _3; // in scope 2 at $DIR/unneeded_deref_do_not_opt.rs:53:9: 53:10 + let _7: u64; // in scope 2 at $DIR/unneeded_deref_do_not_opt.rs:54:9: 54:10 scope 3 { - debug z => _7; // in scope 3 at $DIR/unneeded_deref.rs:137:9: 137:10 + debug z => _7; // in scope 3 at $DIR/unneeded_deref_do_not_opt.rs:54:9: 54:10 } } } bb0: { - StorageLive(_2); // scope 0 at $DIR/unneeded_deref.rs:135:9: 135:10 - _2 = const 5_u64; // scope 0 at $DIR/unneeded_deref.rs:135:13: 135:14 - StorageLive(_3); // scope 1 at $DIR/unneeded_deref.rs:136:9: 136:10 - StorageLive(_4); // scope 1 at $DIR/unneeded_deref.rs:136:16: 136:21 - _4 = _1; // scope 1 at $DIR/unneeded_deref.rs:136:16: 136:21 - switchInt(_4) -> [false: bb1, otherwise: bb2]; // scope 1 at $DIR/unneeded_deref.rs:136:13: 136:41 + StorageLive(_2); // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:52:9: 52:10 + _2 = const 5_u64; // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:52:13: 52:14 + StorageLive(_3); // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:53:9: 53:10 + StorageLive(_4); // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:53:16: 53:21 + _4 = _1; // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:53:16: 53:21 + switchInt(_4) -> [false: bb1, otherwise: bb2]; // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:53:13: 53:41 } bb1: { - StorageLive(_5); // scope 1 at $DIR/unneeded_deref.rs:136:36: 136:39 - _8 = const do_not_opt_different_bbs::promoted[0]; // scope 1 at $DIR/unneeded_deref.rs:136:36: 136:39 + StorageLive(_5); // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:53:36: 53:39 + _8 = const do_not_opt_different_bbs::promoted[0]; // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:53:36: 53:39 // ty::Const // + ty: &u64 - // + val: Unevaluated(WithOptConstParam { did: DefId(0:17 ~ unneeded_deref[317d]::do_not_opt_different_bbs), const_param_did: None }, [], Some(promoted[0])) + // + val: Unevaluated(WithOptConstParam { did: DefId(0:8 ~ unneeded_deref_do_not_opt[317d]::do_not_opt_different_bbs), const_param_did: None }, [], Some(promoted[0])) // mir::Constant - // + span: $DIR/unneeded_deref.rs:136:36: 136:39 - // + literal: Const { ty: &u64, val: Unevaluated(WithOptConstParam { did: DefId(0:17 ~ unneeded_deref[317d]::do_not_opt_different_bbs), const_param_did: None }, [], Some(promoted[0])) } - _5 = _8; // scope 1 at $DIR/unneeded_deref.rs:136:36: 136:39 - _3 = _5; // scope 1 at $DIR/unneeded_deref.rs:136:36: 136:39 - StorageDead(_5); // scope 1 at $DIR/unneeded_deref.rs:136:40: 136:41 - goto -> bb3; // scope 1 at $DIR/unneeded_deref.rs:136:13: 136:41 + // + span: $DIR/unneeded_deref_do_not_opt.rs:53:36: 53:39 + // + literal: Const { ty: &u64, val: Unevaluated(WithOptConstParam { did: DefId(0:8 ~ unneeded_deref_do_not_opt[317d]::do_not_opt_different_bbs), const_param_did: None }, [], Some(promoted[0])) } + _5 = _8; // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:53:36: 53:39 + _3 = _5; // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:53:36: 53:39 + StorageDead(_5); // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:53:40: 53:41 + goto -> bb3; // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:53:13: 53:41 } bb2: { - _3 = &_2; // scope 1 at $DIR/unneeded_deref.rs:136:24: 136:26 - goto -> bb3; // scope 1 at $DIR/unneeded_deref.rs:136:13: 136:41 + _3 = &_2; // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:53:24: 53:26 + goto -> bb3; // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:53:13: 53:41 } bb3: { - StorageDead(_4); // scope 1 at $DIR/unneeded_deref.rs:136:41: 136:42 - StorageLive(_7); // scope 2 at $DIR/unneeded_deref.rs:137:9: 137:10 - _7 = (*_3); // scope 2 at $DIR/unneeded_deref.rs:137:13: 137:15 - _0 = _7; // scope 3 at $DIR/unneeded_deref.rs:138:5: 138:6 - StorageDead(_7); // scope 2 at $DIR/unneeded_deref.rs:139:1: 139:2 - StorageDead(_3); // scope 1 at $DIR/unneeded_deref.rs:139:1: 139:2 - StorageDead(_2); // scope 0 at $DIR/unneeded_deref.rs:139:1: 139:2 - return; // scope 0 at $DIR/unneeded_deref.rs:139:2: 139:2 + StorageDead(_4); // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:53:41: 53:42 + StorageLive(_7); // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:54:9: 54:10 + _7 = (*_3); // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:54:13: 54:15 + _0 = _7; // scope 3 at $DIR/unneeded_deref_do_not_opt.rs:55:5: 55:6 + StorageDead(_7); // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:56:1: 56:2 + StorageDead(_3); // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:56:1: 56:2 + StorageDead(_2); // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:56:1: 56:2 + return; // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:56:2: 56:2 } } diff --git a/src/test/mir-opt/unneeded_deref.do_not_use_moved.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref_do_not_opt.do_not_use_moved.UnneededDeref.diff similarity index 66% rename from src/test/mir-opt/unneeded_deref.do_not_use_moved.UnneededDeref.diff rename to src/test/mir-opt/unneeded_deref_do_not_opt.do_not_use_moved.UnneededDeref.diff index 1ece5aca01beb..7d880e6040fe0 100644 --- a/src/test/mir-opt/unneeded_deref.do_not_use_moved.UnneededDeref.diff +++ b/src/test/mir-opt/unneeded_deref_do_not_opt.do_not_use_moved.UnneededDeref.diff @@ -2,34 +2,34 @@ + // MIR for `do_not_use_moved` after UnneededDeref fn do_not_use_moved(_1: T) -> () { - debug x => _1; // in scope 0 at $DIR/unneeded_deref.rs:110:24: 110:25 - let mut _0: (); // return place in scope 0 at $DIR/unneeded_deref.rs:110:30: 110:30 - let _2: T; // in scope 0 at $DIR/unneeded_deref.rs:111:9: 111:10 + debug x => _1; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:44:24: 44:25 + let mut _0: (); // return place in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:44:30: 44:30 + let _2: T; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:45:9: 45:10 scope 1 { - debug b => _2; // in scope 1 at $DIR/unneeded_deref.rs:111:9: 111:10 - let _3: &T; // in scope 1 at $DIR/unneeded_deref.rs:112:9: 112:10 + debug b => _2; // in scope 1 at $DIR/unneeded_deref_do_not_opt.rs:45:9: 45:10 + let _3: &T; // in scope 1 at $DIR/unneeded_deref_do_not_opt.rs:46:9: 46:10 scope 2 { - debug z => _3; // in scope 2 at $DIR/unneeded_deref.rs:112:9: 112:10 + debug z => _3; // in scope 2 at $DIR/unneeded_deref_do_not_opt.rs:46:9: 46:10 } } bb0: { - StorageLive(_2); // scope 0 at $DIR/unneeded_deref.rs:111:9: 111:10 - _2 = move _1; // scope 0 at $DIR/unneeded_deref.rs:111:13: 111:14 - StorageLive(_3); // scope 1 at $DIR/unneeded_deref.rs:112:9: 112:10 - _3 = &_2; // scope 1 at $DIR/unneeded_deref.rs:112:13: 112:15 - _0 = const (); // scope 0 at $DIR/unneeded_deref.rs:110:30: 113:2 - StorageDead(_3); // scope 1 at $DIR/unneeded_deref.rs:113:1: 113:2 - drop(_2) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/unneeded_deref.rs:113:1: 113:2 + StorageLive(_2); // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:45:9: 45:10 + _2 = move _1; // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:45:13: 45:14 + StorageLive(_3); // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:46:9: 46:10 + _3 = &_2; // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:46:13: 46:15 + _0 = const (); // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:44:30: 47:2 + StorageDead(_3); // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:47:1: 47:2 + drop(_2) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:47:1: 47:2 } bb1: { - StorageDead(_2); // scope 0 at $DIR/unneeded_deref.rs:113:1: 113:2 - return; // scope 0 at $DIR/unneeded_deref.rs:113:2: 113:2 + StorageDead(_2); // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:47:1: 47:2 + return; // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:47:2: 47:2 } bb2 (cleanup): { - resume; // scope 0 at $DIR/unneeded_deref.rs:110:1: 113:2 + resume; // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:44:1: 47:2 } } diff --git a/src/test/mir-opt/unneeded_deref.dont_opt.UnneededDeref.diff b/src/test/mir-opt/unneeded_deref_do_not_opt.dont_opt.UnneededDeref.diff similarity index 64% rename from src/test/mir-opt/unneeded_deref.dont_opt.UnneededDeref.diff rename to src/test/mir-opt/unneeded_deref_do_not_opt.dont_opt.UnneededDeref.diff index 5e63e68a2800b..fb3083e5f2ce7 100644 --- a/src/test/mir-opt/unneeded_deref.dont_opt.UnneededDeref.diff +++ b/src/test/mir-opt/unneeded_deref_do_not_opt.dont_opt.UnneededDeref.diff @@ -2,23 +2,23 @@ + // MIR for `dont_opt` after UnneededDeref fn dont_opt() -> u64 { - let mut _0: u64; // return place in scope 0 at $DIR/unneeded_deref.rs:43:18: 43:21 - let _1: i32; // in scope 0 at $DIR/unneeded_deref.rs:44:9: 44:10 - let mut _5: &i32; // in scope 0 at $DIR/unneeded_deref.rs:48:10: 48:14 + let mut _0: u64; // return place in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:9:18: 9:21 + let _1: i32; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:10:9: 10:10 + let mut _5: &i32; // in scope 0 at $DIR/unneeded_deref_do_not_opt.rs:14:10: 14:14 scope 1 { - debug y => _1; // in scope 1 at $DIR/unneeded_deref.rs:44:9: 44:10 - let _2: &i32; // in scope 1 at $DIR/unneeded_deref.rs:45:9: 45:13 + debug y => _1; // in scope 1 at $DIR/unneeded_deref_do_not_opt.rs:10:9: 10:10 + let _2: &i32; // in scope 1 at $DIR/unneeded_deref_do_not_opt.rs:11:9: 11:13 scope 2 { - debug _ref => _2; // in scope 2 at $DIR/unneeded_deref.rs:45:9: 45:13 - let _3: i32; // in scope 2 at $DIR/unneeded_deref.rs:46:9: 46:10 + debug _ref => _2; // in scope 2 at $DIR/unneeded_deref_do_not_opt.rs:11:9: 11:13 + let _3: i32; // in scope 2 at $DIR/unneeded_deref_do_not_opt.rs:12:9: 12:10 scope 3 { - debug x => _3; // in scope 3 at $DIR/unneeded_deref.rs:46:9: 46:10 - let mut _4: &i32; // in scope 3 at $DIR/unneeded_deref.rs:47:9: 47:15 + debug x => _3; // in scope 3 at $DIR/unneeded_deref_do_not_opt.rs:12:9: 12:10 + let mut _4: &i32; // in scope 3 at $DIR/unneeded_deref_do_not_opt.rs:13:9: 13:15 scope 4 { - debug _1 => _4; // in scope 4 at $DIR/unneeded_deref.rs:47:9: 47:15 - let _6: i32; // in scope 4 at $DIR/unneeded_deref.rs:49:9: 49:11 + debug _1 => _4; // in scope 4 at $DIR/unneeded_deref_do_not_opt.rs:13:9: 13:15 + let _6: i32; // in scope 4 at $DIR/unneeded_deref_do_not_opt.rs:15:9: 15:11 scope 5 { - debug _4 => _6; // in scope 5 at $DIR/unneeded_deref.rs:49:9: 49:11 + debug _4 => _6; // in scope 5 at $DIR/unneeded_deref_do_not_opt.rs:15:9: 15:11 } } } @@ -26,27 +26,27 @@ } bb0: { - StorageLive(_1); // scope 0 at $DIR/unneeded_deref.rs:44:9: 44:10 - _1 = const 5_i32; // scope 0 at $DIR/unneeded_deref.rs:44:13: 44:14 - StorageLive(_2); // scope 1 at $DIR/unneeded_deref.rs:45:9: 45:13 - _2 = &_1; // scope 1 at $DIR/unneeded_deref.rs:45:16: 45:18 - StorageLive(_3); // scope 2 at $DIR/unneeded_deref.rs:46:9: 46:10 - _3 = const 5_i32; // scope 2 at $DIR/unneeded_deref.rs:46:13: 46:14 - StorageLive(_4); // scope 3 at $DIR/unneeded_deref.rs:47:9: 47:15 - _4 = &_3; // scope 3 at $DIR/unneeded_deref.rs:47:18: 47:20 - StorageLive(_5); // scope 4 at $DIR/unneeded_deref.rs:48:10: 48:14 - _5 = _2; // scope 4 at $DIR/unneeded_deref.rs:48:10: 48:14 - _4 = move _5; // scope 4 at $DIR/unneeded_deref.rs:48:5: 48:14 - StorageDead(_5); // scope 4 at $DIR/unneeded_deref.rs:48:13: 48:14 - StorageLive(_6); // scope 4 at $DIR/unneeded_deref.rs:49:9: 49:11 - _6 = (*_4); // scope 4 at $DIR/unneeded_deref.rs:49:14: 49:17 - _0 = const 0_u64; // scope 5 at $DIR/unneeded_deref.rs:50:5: 50:6 - StorageDead(_6); // scope 4 at $DIR/unneeded_deref.rs:51:1: 51:2 - StorageDead(_4); // scope 3 at $DIR/unneeded_deref.rs:51:1: 51:2 - StorageDead(_3); // scope 2 at $DIR/unneeded_deref.rs:51:1: 51:2 - StorageDead(_2); // scope 1 at $DIR/unneeded_deref.rs:51:1: 51:2 - StorageDead(_1); // scope 0 at $DIR/unneeded_deref.rs:51:1: 51:2 - return; // scope 0 at $DIR/unneeded_deref.rs:51:2: 51:2 + StorageLive(_1); // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:10:9: 10:10 + _1 = const 5_i32; // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:10:13: 10:14 + StorageLive(_2); // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:11:9: 11:13 + _2 = &_1; // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:11:16: 11:18 + StorageLive(_3); // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:12:9: 12:10 + _3 = const 5_i32; // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:12:13: 12:14 + StorageLive(_4); // scope 3 at $DIR/unneeded_deref_do_not_opt.rs:13:9: 13:15 + _4 = &_3; // scope 3 at $DIR/unneeded_deref_do_not_opt.rs:13:18: 13:20 + StorageLive(_5); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:14:10: 14:14 + _5 = _2; // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:14:10: 14:14 + _4 = move _5; // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:14:5: 14:14 + StorageDead(_5); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:14:13: 14:14 + StorageLive(_6); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:15:9: 15:11 + _6 = (*_4); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:15:14: 15:17 + _0 = const 0_u64; // scope 5 at $DIR/unneeded_deref_do_not_opt.rs:16:5: 16:6 + StorageDead(_6); // scope 4 at $DIR/unneeded_deref_do_not_opt.rs:17:1: 17:2 + StorageDead(_4); // scope 3 at $DIR/unneeded_deref_do_not_opt.rs:17:1: 17:2 + StorageDead(_3); // scope 2 at $DIR/unneeded_deref_do_not_opt.rs:17:1: 17:2 + StorageDead(_2); // scope 1 at $DIR/unneeded_deref_do_not_opt.rs:17:1: 17:2 + StorageDead(_1); // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:17:1: 17:2 + return; // scope 0 at $DIR/unneeded_deref_do_not_opt.rs:17:2: 17:2 } } diff --git a/src/test/mir-opt/unneeded_deref_do_not_opt.rs b/src/test/mir-opt/unneeded_deref_do_not_opt.rs new file mode 100644 index 0000000000000..76d1b03e0c9a4 --- /dev/null +++ b/src/test/mir-opt/unneeded_deref_do_not_opt.rs @@ -0,0 +1,64 @@ +// compile-flags: -O -Zunsound-mir-opts + +// EMIT_MIR unneeded_deref_do_not_opt.dont_opt.UnneededDeref.diff +// do not optimize a sequence looking like this: +// _1 = &_2; +// _1 = _3; +// _4 = *_1; +// as the _1 = _3 assignment makes it not legal to replace the last statement with _4 = _2 +fn dont_opt() -> u64 { + let y = 5; + let _ref = &y; + let x = 5; + let mut _1 = &x; + _1 = _ref; + let _4 = *_1; + 0 +} + +// EMIT_MIR unneeded_deref_do_not_opt.do_not_miscompile.UnneededDeref.diff +fn do_not_miscompile() { + let x = 42; + let a = 99; + let mut y = &x; + let z = &mut y; + *z = &a; + assert!(*y == 99); +} + +// EMIT_MIR unneeded_deref_do_not_opt.do_not_miscompile_mut_ref.UnneededDeref.diff +// See #78192 +fn do_not_miscompile_mut_ref() { + let a = 1u32; + let b = 2u32; + + let mut c: *const u32 = &a; + let d: &u32 = &b; + + let x = unsafe { &*c }; + c = d; + let z = *x; +} + +// EMIT_MIR unneeded_deref_do_not_opt.do_not_use_moved.UnneededDeref.diff +fn do_not_use_moved(x: T) { + let b = x; + let z = &b; +} + +// EMIT_MIR unneeded_deref_do_not_opt.do_not_opt_different_bbs.UnneededDeref.diff +// We cannot know whether z should be 5 or 33 +fn do_not_opt_different_bbs(input: bool) -> u64 { + let x = 5; + let y = if input { &x } else { &33 }; + let z = *y; + z +} + +fn main() { + dont_opt(); + do_not_miscompile(); + do_not_miscompile_mut_ref(); + do_not_use_moved(String::new()); + do_not_opt_different_bbs(false); +} From ef1dd41b72703b4a5b61821d2ec8688c09d5e77d Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Thu, 12 Nov 2020 20:33:46 +0100 Subject: [PATCH 03/18] Perf: avoid cloning state --- compiler/rustc_mir/src/transform/unneeded_deref.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir/src/transform/unneeded_deref.rs b/compiler/rustc_mir/src/transform/unneeded_deref.rs index f631303aa11ce..9c9ed738d44f0 100644 --- a/compiler/rustc_mir/src/transform/unneeded_deref.rs +++ b/compiler/rustc_mir/src/transform/unneeded_deref.rs @@ -51,7 +51,7 @@ struct UnneededDerefVisitor<'a, 'tcx> { refs: FxHashMap>, optimizations: &'a mut FxHashMap<(Location, Place<'tcx>), Place<'tcx>>, results: &'a Results<'tcx, AvailableLocals>, - state: Option>>, + state: *const Dual>, } impl<'a, 'tcx> Visitor<'tcx> for UnneededDerefVisitor<'a, 'tcx> { @@ -59,7 +59,9 @@ impl<'a, 'tcx> Visitor<'tcx> for UnneededDerefVisitor<'a, 'tcx> { let analysis = &self.results.analysis; let _: Option<_> = try { debug!("Visiting place {:?}", place); - let state = self.state.as_ref()?; + // SAFETY: We only use self.state here which is always called from statement_before_primary_effect, + // which guarantees that self.state is still alive. + let state = unsafe{self.state.as_ref().unwrap()}; match place.as_ref() { PlaceRef { projection: [ProjectionElem::Deref], .. } => { @@ -112,7 +114,7 @@ impl<'a, 'tcx> UnneededDerefVisitor<'a, 'tcx> { refs, optimizations: &mut optimizations, results: &results, - state: None, + state: std::ptr::null(), }; results.visit_reachable_with(body, &mut _self); @@ -129,7 +131,7 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx> for UnneededDerefVisitor<'a, 'tcx> { stmt: &'mir Statement<'tcx>, location: Location, ) { - self.state = Some(state.clone()); + self.state = state; let analysis = &self.results.analysis; debug!("state: {:?} before statement {:?}", analysis.debug_state(state), stmt); let _: Option<_> = try { From 086b98f73a33ae16235040452346376e05916e7d Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Thu, 12 Nov 2020 21:38:01 +0100 Subject: [PATCH 04/18] return pointer had wrong index --- compiler/rustc_mir/src/dataflow/impls/available_locals.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs index 5da53fdbfa351..d3524f1b90de6 100644 --- a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs +++ b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs @@ -156,7 +156,7 @@ impl LocalWithLocationMap { ); // return pointer - map.entry(body.local_decls.next_index()) + map.entry(body.local_decls.indices().next().unwrap()) .or_insert(SmallVec::with_capacity(2)) .push((0usize.into(), None)); From 20e1973748ac8f1ebd4c8f3225c889f46a9d6926 Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Thu, 12 Nov 2020 21:51:16 +0100 Subject: [PATCH 05/18] perf: preparing a AvailableLocals analysis is currently pretty expensive so do it as late as possible --- compiler/rustc_mir/src/transform/unneeded_deref.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_mir/src/transform/unneeded_deref.rs b/compiler/rustc_mir/src/transform/unneeded_deref.rs index 9c9ed738d44f0..7b91b42cb2a71 100644 --- a/compiler/rustc_mir/src/transform/unneeded_deref.rs +++ b/compiler/rustc_mir/src/transform/unneeded_deref.rs @@ -96,8 +96,6 @@ impl<'a, 'tcx> UnneededDerefVisitor<'a, 'tcx> { body: &'a Body<'tcx>, tcx: TyCtxt<'tcx>, ) -> FxHashMap<(Location, Place<'tcx>), Place<'tcx>> { - let analysis = AvailableLocals::new(body); - let mut ref_finder = RefFinder::new(); ref_finder.visit_body(body); let refs = ref_finder.refs; @@ -108,6 +106,7 @@ impl<'a, 'tcx> UnneededDerefVisitor<'a, 'tcx> { return optimizations; } + let analysis = AvailableLocals::new(body); let results = analysis.into_engine(tcx, body).iterate_to_fixpoint(); let mut _self = UnneededDerefVisitor { From 191eb30a3fe364cbe3fd077dce278acdeb6a158d Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Thu, 12 Nov 2020 22:28:33 +0100 Subject: [PATCH 06/18] perf: there is no need to add entries for vars and temps If we need them, they will be added in the visitor that goes through assigns --- .../src/dataflow/impls/available_locals.rs | 41 ++++++++++++------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs index d3524f1b90de6..3994eba5b2cf3 100644 --- a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs +++ b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs @@ -62,11 +62,14 @@ impl<'a, 'tcx> AvailableLocals { /// Returns whether the given local is available at the given state pub fn is_available(&self, local: Local, state: &'a State) -> bool { - self.local_with_location_map.local_with_locations(local).any( - |place_taken_ref_local_with_location| { + let locations_opt = self.local_with_location_map.local_with_locations(local); + if let Some(mut locations) = locations_opt { + locations.any(|place_taken_ref_local_with_location| { state.0.contains(place_taken_ref_local_with_location) - }, - ) + }) + } else { + false + } } fn transfer_function(&'a self, available: &'a mut T) -> TransferFunction<'a, T> @@ -160,7 +163,7 @@ impl LocalWithLocationMap { .or_insert(SmallVec::with_capacity(2)) .push((0usize.into(), None)); - for arg in body.args_iter().chain(body.vars_and_temps_iter()) { + for arg in body.args_iter() { map.entry(arg).or_insert(SmallVec::with_capacity(2)).push((0usize.into(), None)); } @@ -196,10 +199,10 @@ impl LocalWithLocationMap { fn local_with_locations( &self, local: Local, - ) -> impl Iterator + '_ { + ) -> Option + '_> { debug!("Looking for {:?} in {:?}", local, self.0); - let locations = self.0.get(&local).unwrap(); - return locations.iter().map(move |(location_idx, _)| *location_idx); + let locations = self.0.get(&local)?; + return Some(locations.iter().map(move |(location_idx, _)| *location_idx)); } fn len(&self) -> usize { @@ -261,9 +264,13 @@ where T: GenKill, { fn invalidate_local(&mut self, local_invalidated: Local, _location: Location) { - for x in self.local_with_location_map.local_with_locations(local_invalidated) { - debug!("Invalidating {:?} which corresponds to {:?}", x, local_invalidated); - self.available.kill(x); + if let Some(locations) = + self.local_with_location_map.local_with_locations(local_invalidated) + { + for x in locations { + debug!("Invalidating {:?} which corresponds to {:?}", x, local_invalidated); + self.available.kill(x); + } } } @@ -278,9 +285,15 @@ where let all_participating_alive = rvalue.participating_locals(location).all(|participating_local| { - self.local_with_location_map - .local_with_locations(participating_local) - .any(|participating_local_idx| self.available.is_alive(participating_local_idx)) + let location_opt = + self.local_with_location_map.local_with_locations(participating_local); + if let Some(mut locations) = location_opt { + locations.any(|participating_local_idx| { + self.available.is_alive(participating_local_idx) + }) + } else { + false + } }); if all_participating_alive { let index = From ee5f9d1638f9b87d215c38a4c6920b5b631f882b Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Thu, 12 Nov 2020 22:54:12 +0100 Subject: [PATCH 07/18] no need to call super_place --- compiler/rustc_mir/src/transform/unneeded_deref.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir/src/transform/unneeded_deref.rs b/compiler/rustc_mir/src/transform/unneeded_deref.rs index 7b91b42cb2a71..ee75ecb114627 100644 --- a/compiler/rustc_mir/src/transform/unneeded_deref.rs +++ b/compiler/rustc_mir/src/transform/unneeded_deref.rs @@ -55,13 +55,13 @@ struct UnneededDerefVisitor<'a, 'tcx> { } impl<'a, 'tcx> Visitor<'tcx> for UnneededDerefVisitor<'a, 'tcx> { - fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) { + fn visit_place(&mut self, place: &Place<'tcx>, _context: PlaceContext, location: Location) { let analysis = &self.results.analysis; let _: Option<_> = try { debug!("Visiting place {:?}", place); - // SAFETY: We only use self.state here which is always called from statement_before_primary_effect, + // SAFETY: We only use self.state here which is always called from statement_before_primary_effect, // which guarantees that self.state is still alive. - let state = unsafe{self.state.as_ref().unwrap()}; + let state = unsafe { self.state.as_ref().unwrap() }; match place.as_ref() { PlaceRef { projection: [ProjectionElem::Deref], .. } => { @@ -87,7 +87,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnneededDerefVisitor<'a, 'tcx> { _ => None?, } }; - self.super_place(place, context, location); + // We explicitly do not call super_place as we don't need to explore the graph deeper } } From 78b013ce8a80019c5546ac5034581cf0de9cc9dd Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Thu, 12 Nov 2020 23:09:04 +0100 Subject: [PATCH 08/18] Mark Place::as_ref as inlineable It actually had no gain on my benchmark, but LLVM did decide to inline it when it now can --- compiler/rustc_middle/src/mir/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index c1ed623058d43..263280c1b4a3c 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1736,6 +1736,7 @@ impl<'tcx> Place<'tcx> { self.as_ref().as_local() } + #[inline] pub fn as_ref(&self) -> PlaceRef<'tcx> { PlaceRef { local: self.local, projection: &self.projection } } From 6cef14f6311267b8d23d3aab383e09aee51ad4b4 Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Fri, 13 Nov 2020 22:58:35 +0100 Subject: [PATCH 09/18] Skip going through participating locals It's only important that the place referenced and the local we store it in is available at the time we try to apply the deref optimization --- compiler/rustc_middle/src/mir/tcx.rs | 16 ----- .../src/dataflow/impls/available_locals.rs | 51 ++++++-------- .../rustc_mir/src/transform/unneeded_deref.rs | 68 ++++++++----------- 3 files changed, 49 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 866040945a8fc..f0bfdae261c64 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -7,7 +7,6 @@ use crate::mir::*; use crate::ty::subst::Subst; use crate::ty::{self, Ty, TyCtxt}; use rustc_hir as hir; -use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_target::abi::VariantIdx; #[derive(Copy, Clone, Debug, TypeFoldable)] @@ -209,21 +208,6 @@ impl<'tcx> Rvalue<'tcx> { _ => RvalueInitializationState::Deep, } } - - /// Returns all locals that participate in the Rvalue - pub fn participating_locals(&self, location: Location) -> impl Iterator { - struct LocalVisitor(Vec); - - impl<'tcx> Visitor<'tcx> for LocalVisitor { - fn visit_local(&mut self, local: &Local, _: PlaceContext, _: Location) { - self.0.push(*local); - } - } - - let mut visitor = LocalVisitor(vec![]); - visitor.visit_rvalue(self, location); - visitor.0.into_iter() - } } impl<'tcx> Operand<'tcx> { diff --git a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs index 3994eba5b2cf3..08dd00bb6a28f 100644 --- a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs +++ b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs @@ -1,18 +1,18 @@ use std::{fmt, hash::BuildHasherDefault}; +use crate::dataflow::{ + fmt::DebugWithAdapter, fmt::DebugWithContext, lattice, lattice::Dual, AnalysisDomain, Forward, + GenKill, GenKillAnalysis, +}; use rustc_data_structures::fx::FxIndexMap; use rustc_index::{bit_set::BitSet, vec::Idx}; + use rustc_middle::{ mir::{self, Body, Local, Location}, mir::{visit::Visitor, BorrowKind, Operand, Place, Rvalue, Statement, StatementKind}, }; use smallvec::SmallVec; -use crate::dataflow::{ - fmt::DebugWithAdapter, fmt::DebugWithContext, lattice, lattice::Dual, AnalysisDomain, Forward, - GenKill, GenKillAnalysis, -}; - /// Dataflow analysis for availability of locals. A local is available at a given program point, /// if the value of the local can freely be used at the given program point. /// Consider the following example: @@ -60,16 +60,17 @@ impl<'a, 'tcx> AvailableLocals { DebugWithAdapter { this: state, ctxt: &self.local_with_location_map } } + pub fn get_local_with_location_index( + &self, + local: Local, + location: Location, + ) -> LocalWithLocationIndex { + self.local_with_location_map.local_with_specific_location(local, Some(location)) + } + /// Returns whether the given local is available at the given state - pub fn is_available(&self, local: Local, state: &'a State) -> bool { - let locations_opt = self.local_with_location_map.local_with_locations(local); - if let Some(mut locations) = locations_opt { - locations.any(|place_taken_ref_local_with_location| { - state.0.contains(place_taken_ref_local_with_location) - }) - } else { - false - } + pub fn is_available(&self, local: Local, state: &'a State) -> Option { + self.local_with_location_map.local_with_locations(local)?.find(|idx| state.0.contains(*idx)) } fn transfer_function(&'a self, available: &'a mut T) -> TransferFunction<'a, T> @@ -283,24 +284,10 @@ where _ => {} } - let all_participating_alive = - rvalue.participating_locals(location).all(|participating_local| { - let location_opt = - self.local_with_location_map.local_with_locations(participating_local); - if let Some(mut locations) = location_opt { - locations.any(|participating_local_idx| { - self.available.is_alive(participating_local_idx) - }) - } else { - false - } - }); - if all_participating_alive { - let index = - self.local_with_location_map.local_with_specific_location(local, Some(location)); - debug!("Inserting {:?} which corresponds to {:?}", index, (local, Some(location))); - self.available.gen(index); - } + let index = + self.local_with_location_map.local_with_specific_location(local, Some(location)); + debug!("Inserting {:?} which corresponds to {:?}", index, (local, Some(location))); + self.available.gen(index); } } diff --git a/compiler/rustc_mir/src/transform/unneeded_deref.rs b/compiler/rustc_mir/src/transform/unneeded_deref.rs index ee75ecb114627..97713fe104353 100644 --- a/compiler/rustc_mir/src/transform/unneeded_deref.rs +++ b/compiler/rustc_mir/src/transform/unneeded_deref.rs @@ -48,7 +48,7 @@ impl<'tcx> MirPass<'tcx> for UnneededDeref { } struct UnneededDerefVisitor<'a, 'tcx> { - refs: FxHashMap>, + refs: FxHashMap, (LocalWithLocationIndex, LocalWithLocationIndex))>, optimizations: &'a mut FxHashMap<(Location, Place<'tcx>), Place<'tcx>>, results: &'a Results<'tcx, AvailableLocals>, state: *const Dual>, @@ -56,26 +56,31 @@ struct UnneededDerefVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for UnneededDerefVisitor<'a, 'tcx> { fn visit_place(&mut self, place: &Place<'tcx>, _context: PlaceContext, location: Location) { - let analysis = &self.results.analysis; let _: Option<_> = try { debug!("Visiting place {:?}", place); // SAFETY: We only use self.state here which is always called from statement_before_primary_effect, // which guarantees that self.state is still alive. - let state = unsafe { self.state.as_ref().unwrap() }; + let state = unsafe { &*self.state }; match place.as_ref() { PlaceRef { projection: [ProjectionElem::Deref], .. } => { + let place_derefed = place; debug!("Refs {:?}", self.refs); - let place_taken_ref_of = self.refs.get(&place.local)?; + // See if we have recorded an earlier assignment where we took the reference of the place we are now dereferencing + let (place_taken_ref_of, (lhs_idx, place_taken_ref_of_location)) = + self.refs.get(&place_derefed.local)?; + + // We found a reference. Let's check if it is still valid let place_taken_ref_of_available = - analysis.is_available(place_taken_ref_of.local, state); + state.0.contains(*place_taken_ref_of_location); debug!( "{:?} has availability {:?}", place_taken_ref_of.local, place_taken_ref_of_available ); if place_taken_ref_of_available { - let place_available = analysis.is_available(place.local, state); + // And then check if the place we are dereferencing is still valid + let place_available = state.0.contains(*lhs_idx); debug!("{:?} has availability {:?}", place.local, place_available); if place_available { self.optimizations @@ -84,7 +89,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnneededDerefVisitor<'a, 'tcx> { } } - _ => None?, + _ => {}, } }; // We explicitly do not call super_place as we don't need to explore the graph deeper @@ -96,18 +101,10 @@ impl<'a, 'tcx> UnneededDerefVisitor<'a, 'tcx> { body: &'a Body<'tcx>, tcx: TyCtxt<'tcx>, ) -> FxHashMap<(Location, Place<'tcx>), Place<'tcx>> { - let mut ref_finder = RefFinder::new(); - ref_finder.visit_body(body); - let refs = ref_finder.refs; - let mut optimizations = FxHashMap::default(); - - // There is point in looking for derefs, if we haven't seen any refs - if refs.is_empty() { - return optimizations; - } - let analysis = AvailableLocals::new(body); let results = analysis.into_engine(tcx, body).iterate_to_fixpoint(); + let refs = FxHashMap::default(); + let mut optimizations = FxHashMap::default(); let mut _self = UnneededDerefVisitor { refs, @@ -135,6 +132,22 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx> for UnneededDerefVisitor<'a, 'tcx> { debug!("state: {:?} before statement {:?}", analysis.debug_state(state), stmt); let _: Option<_> = try { match &stmt.kind { + StatementKind::Assign(box ( + lhs, + Rvalue::Ref(_, BorrowKind::Shared, place_taken_ref_of), + )) => { + let analysis = &self.results.analysis; + // Only insert if the place that is referenced is available + if let Some(place_taken_ref_of_idx) = + analysis.is_available(place_taken_ref_of.local, state) + { + let lhs_idx = analysis.get_local_with_location_index(lhs.local, location); + self.refs.insert( + lhs.local, + (place_taken_ref_of.clone(), (lhs_idx, place_taken_ref_of_idx)), + ); + } + } StatementKind::Assign(box (_, rvalue)) => match rvalue { rvalue => self.visit_rvalue(rvalue, location), }, @@ -144,27 +157,6 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx> for UnneededDerefVisitor<'a, 'tcx> { } } -struct RefFinder<'tcx> { - refs: FxHashMap>, -} - -impl<'tcx> RefFinder<'tcx> { - fn new() -> Self { - Self { refs: FxHashMap::>::default() } - } -} - -impl<'tcx> Visitor<'tcx> for RefFinder<'tcx> { - fn visit_assign(&mut self, lhs: &Place<'tcx>, rvalue: &Rvalue<'tcx>, _: Location) { - match rvalue { - Rvalue::Ref(_, BorrowKind::Shared, place_taken_ref_of) => { - self.refs.insert(lhs.local, place_taken_ref_of.clone()); - } - _ => {} - } - } -} - struct ApplyOpts<'tcx> { optimizations: FxHashMap<(Location, Place<'tcx>), Place<'tcx>>, tcx: TyCtxt<'tcx>, From b19b5fa171fe22da7ac32e8232d8b67950d62d56 Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Fri, 13 Nov 2020 23:49:58 +0100 Subject: [PATCH 10/18] It is cheaper to manually find the assignments, rather than through a visitor --- compiler/rustc_middle/src/mir/mod.rs | 7 +++++ .../src/dataflow/impls/available_locals.rs | 26 ++++++++----------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 263280c1b4a3c..e4751bd7c77d7 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1485,6 +1485,13 @@ pub enum StatementKind<'tcx> { } impl<'tcx> StatementKind<'tcx> { + pub fn as_assign(&self) -> Option<&(Place<'tcx>, Rvalue<'tcx>)> { + match self { + StatementKind::Assign(x) => Some(x), + _ => None, + } + } + pub fn as_assign_mut(&mut self) -> Option<&mut Box<(Place<'tcx>, Rvalue<'tcx>)>> { match self { StatementKind::Assign(x) => Some(x), diff --git a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs index 08dd00bb6a28f..1053623a43cf5 100644 --- a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs +++ b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs @@ -168,8 +168,17 @@ impl LocalWithLocationMap { map.entry(arg).or_insert(SmallVec::with_capacity(2)).push((0usize.into(), None)); } - let mut builder = LocalWithLocationMapBuilder(&mut map); - builder.visit_body(body); + // visit all assignments which are all different "versions" of the locals + for (bb, bbd) in body.basic_blocks().iter_enumerated() { + for (stmt_idx, stmt) in bbd.statements.iter().enumerate() { + if let Some((lhs, _)) = stmt.kind.as_assign() { + let location = Location { block: bb, statement_index: stmt_idx }; + map.entry(lhs.local) + .or_insert(SmallVec::with_capacity(2)) + .push((0usize.into(), Some(location))); + } + } + } // set indices let mut idx = LocalWithLocationIndex::from(0usize); @@ -215,19 +224,6 @@ impl LocalWithLocationMap { } } -struct LocalWithLocationMapBuilder<'a>( - &'a mut FxIndexMap); 2]>>, -); - -impl<'a, 'tcx> Visitor<'tcx> for LocalWithLocationMapBuilder<'a> { - fn visit_assign(&mut self, place: &Place<'tcx>, _: &Rvalue<'tcx>, location: Location) { - self.0 - .entry(place.local) - .or_insert(SmallVec::with_capacity(2)) - .push((0usize.into(), Some(location))); - } -} - rustc_index::newtype_index! { pub struct LocalWithLocationIndex { DEBUG_FORMAT = "ll_{}" From f1e4b0973d208c4b583c6acb76f998536e28782a Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Sat, 14 Nov 2020 00:08:10 +0100 Subject: [PATCH 11/18] Only walk through what we need --- .../src/dataflow/impls/available_locals.rs | 64 ++++++++----------- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs index 1053623a43cf5..0232b6f508c33 100644 --- a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs +++ b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs @@ -9,7 +9,7 @@ use rustc_index::{bit_set::BitSet, vec::Idx}; use rustc_middle::{ mir::{self, Body, Local, Location}, - mir::{visit::Visitor, BorrowKind, Operand, Place, Rvalue, Statement, StatementKind}, + mir::{visit::Visitor, BorrowKind, Operand, Rvalue, Statement, StatementKind}, }; use smallvec::SmallVec; @@ -291,44 +291,36 @@ impl<'a, 'tcx, T> Visitor<'tcx> for TransferFunction<'a, T> where T: GenKill, { - fn visit_assign( - &mut self, - assigned_place: &Place<'tcx>, - rvalue: &Rvalue<'tcx>, - location: Location, - ) { - if let Some(assigned_local) = assigned_place.as_local() { - let disallowed_place_opt = match rvalue { - Rvalue::Ref(_, BorrowKind::Mut { .. } | BorrowKind::Shallow, ref_of) => { - Some(ref_of) - } - Rvalue::AddressOf(_, ref_of) => Some(ref_of), - _ => None, - }; - - if let Some(disallowed_place) = disallowed_place_opt { - // It is difficult to reason about availability of mutable places or raw pointers, so throw out any - // availability information about the local taken a reference of. - debug!( - "Found disallowed reference of `{:?}`. Invalidating {:?} and {:?}", - disallowed_place, disallowed_place.local, assigned_local - ); - self.invalidate_local(disallowed_place.local, location); - self.invalidate_local(assigned_local, location) - } else { - self.add_available(assigned_local, rvalue.clone(), location); - } - } - - self.super_assign(assigned_place, rvalue, location); - } - fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { - match statement.kind { + match &statement.kind { StatementKind::StorageDead(dead) => { - self.invalidate_local(dead, location); + self.invalidate_local(*dead, location); } - _ => self.super_statement(statement, location), + StatementKind::Assign(box (assigned_place, rvalue)) => { + if let Some(assigned_local) = assigned_place.as_local() { + let disallowed_place_opt = match rvalue { + Rvalue::Ref(_, BorrowKind::Mut { .. } | BorrowKind::Shallow, ref_of) => { + Some(ref_of) + } + Rvalue::AddressOf(_, ref_of) => Some(ref_of), + _ => None, + }; + + if let Some(disallowed_place) = disallowed_place_opt { + // It is difficult to reason about availability of mutable places or raw pointers, so throw out any + // availability information about the local taken a reference of. + debug!( + "Found disallowed reference of `{:?}`. Invalidating {:?} and {:?}", + disallowed_place, disallowed_place.local, assigned_local + ); + self.invalidate_local(disallowed_place.local, location); + self.invalidate_local(assigned_local, location) + } else { + self.add_available(assigned_local, rvalue.clone(), location); + } + } + } + _ => {} } } } From 54b95af5ea367a4018f16db3d7a207bd7eba7be2 Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Sat, 14 Nov 2020 00:11:31 +0100 Subject: [PATCH 12/18] do not clone rvalue --- compiler/rustc_mir/src/dataflow/impls/available_locals.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs index 0232b6f508c33..018fdc86b71b3 100644 --- a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs +++ b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs @@ -271,7 +271,7 @@ where } } - fn add_available(&mut self, local: Local, rvalue: Rvalue<'tcx>, location: Location) { + fn add_available(&mut self, local: Local, rvalue: &Rvalue<'tcx>, location: Location) { self.invalidate_local(local, location); // If rvalue is a move into the assigned local, then the local being moved should be invalidated @@ -316,7 +316,7 @@ where self.invalidate_local(disallowed_place.local, location); self.invalidate_local(assigned_local, location) } else { - self.add_available(assigned_local, rvalue.clone(), location); + self.add_available(assigned_local, rvalue, location); } } } From ed574a001b7fda2e6f3f6bc2532b93a816a9c872 Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Sat, 14 Nov 2020 13:21:12 +0100 Subject: [PATCH 13/18] tidy --- compiler/rustc_mir/src/transform/unneeded_deref.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir/src/transform/unneeded_deref.rs b/compiler/rustc_mir/src/transform/unneeded_deref.rs index 97713fe104353..755b38dd313b2 100644 --- a/compiler/rustc_mir/src/transform/unneeded_deref.rs +++ b/compiler/rustc_mir/src/transform/unneeded_deref.rs @@ -89,7 +89,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnneededDerefVisitor<'a, 'tcx> { } } - _ => {}, + _ => {} } }; // We explicitly do not call super_place as we don't need to explore the graph deeper From a04643713c5d376b8d786a9607e33874f88e3bd9 Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Sun, 15 Nov 2020 18:17:43 +0100 Subject: [PATCH 14/18] set indices on the fly --- .../src/dataflow/impls/available_locals.rs | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs index 018fdc86b71b3..ca06295ede475 100644 --- a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs +++ b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs @@ -159,13 +159,19 @@ impl LocalWithLocationMap { BuildHasherDefault::default(), ); + let mut idx = LocalWithLocationIndex::from(0usize); + // return pointer map.entry(body.local_decls.indices().next().unwrap()) - .or_insert(SmallVec::with_capacity(2)) - .push((0usize.into(), None)); + .or_insert(SmallVec::with_capacity(LOCAL_WITH_LOCATION_SMALLVEC_CAP)) + .push((idx, None)); + idx.increment_by(1); for arg in body.args_iter() { - map.entry(arg).or_insert(SmallVec::with_capacity(2)).push((0usize.into(), None)); + map.entry(arg) + .or_insert(SmallVec::with_capacity(LOCAL_WITH_LOCATION_SMALLVEC_CAP)) + .push((idx, None)); + idx.increment_by(1); } // visit all assignments which are all different "versions" of the locals @@ -175,20 +181,12 @@ impl LocalWithLocationMap { let location = Location { block: bb, statement_index: stmt_idx }; map.entry(lhs.local) .or_insert(SmallVec::with_capacity(2)) - .push((0usize.into(), Some(location))); + .push((idx, Some(location))); + idx.increment_by(1); } } } - // set indices - let mut idx = LocalWithLocationIndex::from(0usize); - for x in map.values_mut() { - for (idx_to_set, _) in x.iter_mut() { - *idx_to_set = idx; - idx.increment_by(1); - } - } - Self(map) } From cc5588b0a48daef9e848e588a0809811db2df3c7 Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Sun, 15 Nov 2020 18:22:46 +0100 Subject: [PATCH 15/18] skip adding locals with projections to map --- .../src/dataflow/impls/available_locals.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs index ca06295ede475..41af20abae10b 100644 --- a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs +++ b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs @@ -178,11 +178,14 @@ impl LocalWithLocationMap { for (bb, bbd) in body.basic_blocks().iter_enumerated() { for (stmt_idx, stmt) in bbd.statements.iter().enumerate() { if let Some((lhs, _)) = stmt.kind.as_assign() { - let location = Location { block: bb, statement_index: stmt_idx }; - map.entry(lhs.local) - .or_insert(SmallVec::with_capacity(2)) - .push((idx, Some(location))); - idx.increment_by(1); + // We don't handle projections for locals, so let's only add a local with no projections + if lhs.as_local().is_some() { + let location = Location { block: bb, statement_index: stmt_idx }; + map.entry(lhs.local) + .or_insert(SmallVec::with_capacity(2)) + .push((idx, Some(location))); + idx.increment_by(1); + } } } } From 6cce57bf9fe47428d8f6d16a32ebc89d47265135 Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Sun, 15 Nov 2020 19:51:57 +0100 Subject: [PATCH 16/18] remove unneeded invalidation --- compiler/rustc_mir/src/dataflow/impls/available_locals.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs index 41af20abae10b..c719a6aaa41b2 100644 --- a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs +++ b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs @@ -315,7 +315,6 @@ where disallowed_place, disallowed_place.local, assigned_local ); self.invalidate_local(disallowed_place.local, location); - self.invalidate_local(assigned_local, location) } else { self.add_available(assigned_local, rvalue, location); } From 88cf9cc584609e3807d6deb3993ee784135ab2ce Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Sun, 15 Nov 2020 20:01:50 +0100 Subject: [PATCH 17/18] eliminate unsafe with a separate visitor --- .../rustc_mir/src/transform/unneeded_deref.rs | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_mir/src/transform/unneeded_deref.rs b/compiler/rustc_mir/src/transform/unneeded_deref.rs index 755b38dd313b2..ef230cd84ef6a 100644 --- a/compiler/rustc_mir/src/transform/unneeded_deref.rs +++ b/compiler/rustc_mir/src/transform/unneeded_deref.rs @@ -48,19 +48,22 @@ impl<'tcx> MirPass<'tcx> for UnneededDeref { } struct UnneededDerefVisitor<'a, 'tcx> { - refs: FxHashMap, (LocalWithLocationIndex, LocalWithLocationIndex))>, + refs: &'a mut FxHashMap, (LocalWithLocationIndex, LocalWithLocationIndex))>, optimizations: &'a mut FxHashMap<(Location, Place<'tcx>), Place<'tcx>>, results: &'a Results<'tcx, AvailableLocals>, - state: *const Dual>, } -impl<'a, 'tcx> Visitor<'tcx> for UnneededDerefVisitor<'a, 'tcx> { +struct FindOptVisitor<'a, 'tcx> { + refs: &'a mut FxHashMap, (LocalWithLocationIndex, LocalWithLocationIndex))>, + optimizations: &'a mut FxHashMap<(Location, Place<'tcx>), Place<'tcx>>, + state: &'a Dual>, +} + +impl<'a, 'tcx> Visitor<'tcx> for FindOptVisitor<'a, 'tcx> { fn visit_place(&mut self, place: &Place<'tcx>, _context: PlaceContext, location: Location) { let _: Option<_> = try { debug!("Visiting place {:?}", place); - // SAFETY: We only use self.state here which is always called from statement_before_primary_effect, - // which guarantees that self.state is still alive. - let state = unsafe { &*self.state }; + let state = self.state; match place.as_ref() { PlaceRef { projection: [ProjectionElem::Deref], .. } => { @@ -103,14 +106,13 @@ impl<'a, 'tcx> UnneededDerefVisitor<'a, 'tcx> { ) -> FxHashMap<(Location, Place<'tcx>), Place<'tcx>> { let analysis = AvailableLocals::new(body); let results = analysis.into_engine(tcx, body).iterate_to_fixpoint(); - let refs = FxHashMap::default(); + let mut refs = FxHashMap::default(); let mut optimizations = FxHashMap::default(); let mut _self = UnneededDerefVisitor { - refs, + refs: &mut refs, optimizations: &mut optimizations, results: &results, - state: std::ptr::null(), }; results.visit_reachable_with(body, &mut _self); @@ -127,7 +129,6 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx> for UnneededDerefVisitor<'a, 'tcx> { stmt: &'mir Statement<'tcx>, location: Location, ) { - self.state = state; let analysis = &self.results.analysis; debug!("state: {:?} before statement {:?}", analysis.debug_state(state), stmt); let _: Option<_> = try { @@ -149,7 +150,14 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx> for UnneededDerefVisitor<'a, 'tcx> { } } StatementKind::Assign(box (_, rvalue)) => match rvalue { - rvalue => self.visit_rvalue(rvalue, location), + rvalue => { + let mut _self = FindOptVisitor { + refs: self.refs, + optimizations: &mut self.optimizations, + state: state, + }; + _self.visit_rvalue(rvalue, location); + } }, _ => {} } From 7102506ba2560c652b3be7493ebed69ca51531ba Mon Sep 17 00:00:00 2001 From: Simon Vandel Sillesen Date: Sun, 15 Nov 2020 21:45:09 +0100 Subject: [PATCH 18/18] Fix unwrap panic --- .../src/dataflow/impls/available_locals.rs | 26 +++++++++---------- .../rustc_mir/src/transform/unneeded_deref.rs | 13 ++++++---- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs index c719a6aaa41b2..3daa41fbd5ba7 100644 --- a/compiler/rustc_mir/src/dataflow/impls/available_locals.rs +++ b/compiler/rustc_mir/src/dataflow/impls/available_locals.rs @@ -64,7 +64,7 @@ impl<'a, 'tcx> AvailableLocals { &self, local: Local, location: Location, - ) -> LocalWithLocationIndex { + ) -> Option { self.local_with_location_map.local_with_specific_location(local, Some(location)) } @@ -103,7 +103,9 @@ impl AnalysisDomain<'tcx> for AvailableLocals { // only the function parameters are available for arg in body.args_iter() { - state.0.insert(self.local_with_location_map.local_with_specific_location(arg, None)); + if let Some(l) = self.local_with_location_map.local_with_specific_location(arg, None) { + state.0.insert(l); + } } } } @@ -197,14 +199,10 @@ impl LocalWithLocationMap { &self, local: Local, location: Option, - ) -> LocalWithLocationIndex { + ) -> Option { debug!("Looking for {:?} in {:?}", (local, location), self.0); - let locations = self.0.get(&local).unwrap(); - *locations - .iter() - .find(|(_, l)| *l == location) - .map(|(location_idx, _)| location_idx) - .unwrap() + let locations = self.0.get(&local)?; + locations.iter().find(|(_, l)| *l == location).map(|(location_idx, _)| *location_idx) } fn local_with_locations( @@ -281,10 +279,12 @@ where _ => {} } - let index = - self.local_with_location_map.local_with_specific_location(local, Some(location)); - debug!("Inserting {:?} which corresponds to {:?}", index, (local, Some(location))); - self.available.gen(index); + if let Some(index) = + self.local_with_location_map.local_with_specific_location(local, Some(location)) + { + debug!("Inserting {:?} which corresponds to {:?}", index, (local, Some(location))); + self.available.gen(index); + }; } } diff --git a/compiler/rustc_mir/src/transform/unneeded_deref.rs b/compiler/rustc_mir/src/transform/unneeded_deref.rs index ef230cd84ef6a..f1b00a5eb36b4 100644 --- a/compiler/rustc_mir/src/transform/unneeded_deref.rs +++ b/compiler/rustc_mir/src/transform/unneeded_deref.rs @@ -142,11 +142,14 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx> for UnneededDerefVisitor<'a, 'tcx> { if let Some(place_taken_ref_of_idx) = analysis.is_available(place_taken_ref_of.local, state) { - let lhs_idx = analysis.get_local_with_location_index(lhs.local, location); - self.refs.insert( - lhs.local, - (place_taken_ref_of.clone(), (lhs_idx, place_taken_ref_of_idx)), - ); + if let Some(lhs_idx) = + analysis.get_local_with_location_index(lhs.local, location) + { + self.refs.insert( + lhs.local, + (place_taken_ref_of.clone(), (lhs_idx, place_taken_ref_of_idx)), + ); + }; } } StatementKind::Assign(box (_, rvalue)) => match rvalue {