diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index fd8a2a6bc3544..a919cf9227880 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1162,12 +1162,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let opt_assignment_rhs_span = self.find_assignments(local).first().map(|&location| { if let Some(mir::Statement { - source_info: _, kind: mir::StatementKind::Assign(box ( _, mir::Rvalue::Use(mir::Operand::Copy(place)), )), + .. }) = self.body[location.block].statements.get(location.statement_index) { self.body.local_decls[place.local].source_info.span diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs index 4c8585192a1b1..be71e2258633a 100644 --- a/compiler/rustc_codegen_gcc/src/debuginfo.rs +++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs @@ -26,14 +26,17 @@ impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> { &mut self, _dbg_var: Self::DIVariable, _dbg_loc: Self::DILocation, - _variable_alloca: Self::Value, + is_declared: bool, + val: Self::Value, _direct_offset: Size, _indirect_offsets: &[Size], _fragment: Option>, ) { // FIXME(tempdragon): Not sure if this is correct, probably wrong but still keep it here. #[cfg(feature = "master")] - _variable_alloca.set_location(_dbg_loc); + if is_declared { + val.set_location(_dbg_loc); + } } fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs b/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs index 408429152223d..52d04625749b9 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs @@ -35,3 +35,6 @@ declare_constant!(DW_OP_plus_uconst: u64); /// Double-checked by a static assertion in `RustWrapper.cpp`. #[allow(non_upper_case_globals)] pub(crate) const DW_OP_LLVM_fragment: u64 = 0x1000; +// It describes the actual value of a source variable which might not exist in registers or in memory. +#[allow(non_upper_case_globals)] +pub(crate) const DW_OP_stack_value: u64 = 0x9f; diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 5ca2505cec43b..2e360f8b79111 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -160,21 +160,25 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> { &mut self, dbg_var: &'ll DIVariable, dbg_loc: &'ll DILocation, - variable_alloca: Self::Value, + is_declared: bool, + val: Self::Value, direct_offset: Size, indirect_offsets: &[Size], fragment: Option>, ) { - use dwarf_const::{DW_OP_LLVM_fragment, DW_OP_deref, DW_OP_plus_uconst}; + use dwarf_const::{DW_OP_LLVM_fragment, DW_OP_deref, DW_OP_plus_uconst, DW_OP_stack_value}; // Convert the direct and indirect offsets and fragment byte range to address ops. let mut addr_ops = SmallVec::<[u64; 8]>::new(); + let mut need_stack_value = false; if direct_offset.bytes() > 0 { + need_stack_value = true; addr_ops.push(DW_OP_plus_uconst); addr_ops.push(direct_offset.bytes() as u64); } for &offset in indirect_offsets { + need_stack_value = true; addr_ops.push(DW_OP_deref); if offset.bytes() > 0 { addr_ops.push(DW_OP_plus_uconst); @@ -182,6 +186,7 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> { } } if let Some(fragment) = fragment { + need_stack_value = true; // `DW_OP_LLVM_fragment` takes as arguments the fragment's // offset and size, both of them in bits. addr_ops.push(DW_OP_LLVM_fragment); @@ -189,17 +194,33 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> { addr_ops.push((fragment.end - fragment.start).bits() as u64); } - unsafe { - // FIXME(eddyb) replace `llvm.dbg.declare` with `llvm.dbg.addr`. - llvm::LLVMRustDIBuilderInsertDeclareAtEnd( - DIB(self.cx()), - variable_alloca, - dbg_var, - addr_ops.as_ptr(), - addr_ops.len() as c_uint, - dbg_loc, - self.llbb(), - ); + if is_declared { + unsafe { + llvm::LLVMRustDIBuilderInsertDeclareAtEnd( + DIB(self.cx()), + val, + dbg_var, + addr_ops.as_ptr(), + addr_ops.len() as c_uint, + dbg_loc, + self.llbb(), + ); + } + } else { + if need_stack_value { + addr_ops.push(DW_OP_stack_value); + } + unsafe { + llvm::LLVMRustDIBuilderInsertDbgValueAtEnd( + DIB(self.cx()), + val, + dbg_var, + addr_ops.as_ptr(), + addr_ops.len() as c_uint, + dbg_loc, + self.llbb(), + ); + } } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 91ada856d5977..13a1783c55dc2 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2314,6 +2314,16 @@ unsafe extern "C" { InsertAtEnd: &'a BasicBlock, ); + pub(crate) fn LLVMRustDIBuilderInsertDbgValueAtEnd<'a>( + Builder: &DIBuilder<'a>, + Val: &'a Value, + VarInfo: &'a DIVariable, + AddrOps: *const u64, + AddrOpsCount: c_uint, + DL: &'a DILocation, + InsertAtEnd: &'a BasicBlock, + ); + pub(crate) fn LLVMRustDIBuilderCreateEnumerator<'a>( Builder: &DIBuilder<'a>, Name: *const c_char, diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 1d5fbfc0896d2..f8e7e2e70e781 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1323,6 +1323,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { for statement in &data.statements { self.codegen_statement(bx, statement); } + self.codegen_stmt_debuginfos(bx, &data.after_last_stmt_debuginfos); let merging_succ = self.codegen_terminator(bx, bb, data.terminator()); if let MergingSucc::False = merging_succ { diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 025f5fb54f428..2bac3fa402256 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -253,6 +253,52 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { spill_slot } + pub(crate) fn debug_new_value_to_local( + &self, + bx: &mut Bx, + local: mir::Local, + base: PlaceValue, + layout: TyAndLayout<'tcx>, + projection: &[mir::PlaceElem<'tcx>], + ) { + let full_debug_info = bx.sess().opts.debuginfo == DebugInfo::Full; + if !full_debug_info { + return; + } + + let vars = match &self.per_local_var_debug_info { + Some(per_local) => &per_local[local], + None => return, + }; + + for var in vars.iter().cloned() { + self.debug_new_value_to_local_as_var(bx, base, layout, projection, var); + } + } + + fn debug_new_value_to_local_as_var( + &self, + bx: &mut Bx, + base: PlaceValue, + layout: TyAndLayout<'tcx>, + projection: &[mir::PlaceElem<'tcx>], + var: PerLocalVarDebugInfo<'tcx, Bx::DIVariable>, + ) { + let Some(dbg_var) = var.dbg_var else { return }; + let Some(dbg_loc) = self.dbg_loc(var.source_info) else { return }; + let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } = + calculate_debuginfo_offset(bx, projection, layout); + bx.dbg_var_addr( + dbg_var, + dbg_loc, + false, + base.llval, + direct_offset, + &indirect_offsets, + var.fragment, + ); + } + /// Apply debuginfo and/or name, after creating the `alloca` for a local, /// or initializing the local with an operand (whichever applies). pub(crate) fn debug_introduce_local(&self, bx: &mut Bx, local: mir::Local) { @@ -421,6 +467,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.dbg_var_addr( dbg_var, dbg_loc, + true, alloca.val.llval, Size::ZERO, &[Size::ZERO], @@ -430,6 +477,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.dbg_var_addr( dbg_var, dbg_loc, + true, base.val.llval, direct_offset, &indirect_offsets, @@ -455,7 +503,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let base = FunctionCx::spill_operand_to_stack(operand, Some(name), bx); bx.clear_dbg_loc(); - bx.dbg_var_addr(dbg_var, dbg_loc, base.val.llval, Size::ZERO, &[], fragment); + bx.dbg_var_addr(dbg_var, dbg_loc, true, base.val.llval, Size::ZERO, &[], fragment); } } } diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index cd55a838a7561..5c389e090b0e5 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -1,13 +1,17 @@ -use rustc_middle::mir::{self, NonDivergingIntrinsic}; -use rustc_middle::span_bug; +use rustc_middle::mir::{self, NonDivergingIntrinsic, StmtDebugInfo}; +use rustc_middle::{bug, span_bug}; use tracing::instrument; use super::{FunctionCx, LocalRef}; +use crate::common::TypeKind; +use crate::mir::operand::OperandValue; +use crate::mir::place::PlaceRef; use crate::traits::*; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { #[instrument(level = "debug", skip(self, bx))] pub(crate) fn codegen_statement(&mut self, bx: &mut Bx, statement: &mir::Statement<'tcx>) { + self.codegen_stmt_debuginfos(bx, &statement.debuginfos); self.set_debug_loc(bx, statement.source_info); match statement.kind { mir::StatementKind::Assign(box (ref place, ref rvalue)) => { @@ -96,4 +100,68 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { | mir::StatementKind::Nop => {} } } + + pub(crate) fn codegen_stmt_debuginfo(&mut self, bx: &mut Bx, debuginfo: &StmtDebugInfo<'tcx>) { + match debuginfo { + StmtDebugInfo::AssignRef(dest, place) => { + let place_ref = match self.locals[place.local] { + LocalRef::Place(place_ref) | LocalRef::UnsizedPlace(place_ref) => { + Some(place_ref) + } + LocalRef::Operand(operand_ref) => match operand_ref.val { + OperandValue::Ref(_place_value) => { + todo!("supports OperandValue::Ref") + } + OperandValue::Immediate(v) => { + // FIXME: add ref to layout? + Some(PlaceRef::new_sized(v, operand_ref.layout)) + } + OperandValue::Pair(_, _) => None, + OperandValue::ZeroSized => None, + }, + LocalRef::PendingOperand => None, + } + .filter(|place_ref| { + // Drop unsupported projections. + // FIXME: Add a test case. + place.projection.iter().all(|p| p.can_use_in_debuginfo()) && + // Only pointers can calculate addresses. + bx.type_kind(bx.val_ty(place_ref.val.llval)) == TypeKind::Pointer + }); + let (val, layout, projection) = + match (place_ref, place.is_indirect_first_projection()) { + (Some(place_ref), false) => { + (place_ref.val, place_ref.layout, place.projection.as_slice()) + } + (Some(place_ref), true) => { + let projected_ty = + place_ref.layout.ty.builtin_deref(true).unwrap_or_else(|| { + bug!("deref of non-pointer {:?}", place_ref) + }); + let layout = bx.cx().layout_of(projected_ty); + (place_ref.val, layout, &place.projection[1..]) + } + _ => { + // If the address cannot be computed, use poison to indicate that the value has been optimized out. + let ty = self.monomorphize(self.mir.local_decls[*dest].ty); + let layout = bx.cx().layout_of(ty); + let to_backend_ty = bx.cx().immediate_backend_type(layout); + let place_ref = + PlaceRef::new_sized(bx.cx().const_poison(to_backend_ty), layout); + (place_ref.val, layout, [].as_slice()) + } + }; + self.debug_new_value_to_local(bx, *dest, val, layout, projection); + } + } + } + pub(crate) fn codegen_stmt_debuginfos( + &mut self, + bx: &mut Bx, + debuginfos: &[StmtDebugInfo<'tcx>], + ) { + for debuginfo in debuginfos { + self.codegen_stmt_debuginfo(bx, debuginfo); + } + } } diff --git a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs index b9d4950e0ad36..7cc3535d19779 100644 --- a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs @@ -71,7 +71,8 @@ pub trait DebugInfoBuilderMethods: BackendTypes { &mut self, dbg_var: Self::DIVariable, dbg_loc: Self::DILocation, - variable_alloca: Self::Value, + is_declared: bool, + val: Self::Value, direct_offset: Size, // NB: each offset implies a deref (i.e. they're steps in a pointer chain). indirect_offsets: &[Size], diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 90aa9188c8300..cb25ab33481eb 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -58,6 +58,7 @@ using namespace llvm::object; // This opcode is an LLVM detail that could hypothetically change (?), so // verify that the hard-coded value in `dwarf_const.rs` still agrees with LLVM. static_assert(dwarf::DW_OP_LLVM_fragment == 0x1000); +static_assert(dwarf::DW_OP_stack_value == 0x9f); // LLVMAtomicOrdering is already an enum - don't create another // one. @@ -1241,6 +1242,18 @@ LLVMRustDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Builder, LLVMValueRef V, DebugLoc(cast(unwrap(DL))), unwrap(InsertAtEnd)); } +extern "C" void +LLVMRustDIBuilderInsertDbgValueAtEnd(LLVMDIBuilderRef Builder, LLVMValueRef V, + LLVMMetadataRef VarInfo, uint64_t *AddrOps, + unsigned AddrOpsCount, LLVMMetadataRef DL, + LLVMBasicBlockRef InsertAtEnd) { + unwrap(Builder)->insertDbgValueIntrinsic( + unwrap(V), unwrap(VarInfo), + unwrap(Builder)->createExpression( + llvm::ArrayRef(AddrOps, AddrOpsCount)), + DebugLoc(cast(unwrap(DL))), unwrap(InsertAtEnd)); +} + extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(LLVMDIBuilderRef Builder, const char *Name, size_t NameLen, const uint64_t Value[2], diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 9f39908c3b2f8..d5ab888f90c5f 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -4,8 +4,8 @@ use std::borrow::Cow; use std::fmt::{self, Debug, Formatter}; -use std::iter; use std::ops::{Index, IndexMut}; +use std::{iter, mem}; pub use basic_blocks::{BasicBlocks, SwitchTargetValue}; use either::Either; @@ -1336,10 +1336,15 @@ impl BasicBlock { /// /// See [`BasicBlock`] for documentation on what basic blocks are at a high level. #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +#[non_exhaustive] pub struct BasicBlockData<'tcx> { /// List of statements in this block. pub statements: Vec>, + /// All debuginfos happen before the statement. + /// Put debuginfos here when the last statement is eliminated. + pub after_last_stmt_debuginfos: Vec>, + /// Terminator for this block. /// /// N.B., this should generally ONLY be `None` during construction. @@ -1367,7 +1372,12 @@ impl<'tcx> BasicBlockData<'tcx> { terminator: Option>, is_cleanup: bool, ) -> BasicBlockData<'tcx> { - BasicBlockData { statements, terminator, is_cleanup } + BasicBlockData { + statements, + after_last_stmt_debuginfos: Vec::new(), + terminator, + is_cleanup, + } } /// Accessor for terminator. @@ -1402,6 +1412,34 @@ impl<'tcx> BasicBlockData<'tcx> { self.terminator().successors() } } + + pub fn retain_statements(&mut self, mut f: F) + where + F: FnMut(&Statement<'tcx>) -> bool, + { + let mut debuginfos = Vec::new(); + self.statements.retain_mut(|stmt| { + let retain = f(stmt); + if retain { + stmt.debuginfos.splice(0..0, mem::take(&mut debuginfos)); + } else { + debuginfos.extend_from_slice(&stmt.debuginfos); + } + retain + }); + self.after_last_stmt_debuginfos.extend_from_slice(&debuginfos); + } + + pub fn strip_nops(&mut self) { + self.retain_statements(|stmt| !matches!(stmt.kind, StatementKind::Nop)) + } + + pub fn drop_debuginfo(&mut self) { + self.after_last_stmt_debuginfos = Vec::new(); + for stmt in self.statements.iter_mut() { + stmt.debuginfos = Vec::new(); + } + } } /////////////////////////////////////////////////////////////////////////// @@ -1706,10 +1744,10 @@ mod size_asserts { use super::*; // tidy-alphabetical-start - static_assert_size!(BasicBlockData<'_>, 128); + static_assert_size!(BasicBlockData<'_>, 152); static_assert_size!(LocalDecl<'_>, 40); static_assert_size!(SourceScopeData<'_>, 64); - static_assert_size!(Statement<'_>, 32); + static_assert_size!(Statement<'_>, 56); static_assert_size!(Terminator<'_>, 96); static_assert_size!(VarDebugInfo<'_>, 88); // tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 6b262a2750059..863b52eef9c2d 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -778,6 +778,9 @@ where let mut current_location = Location { block, statement_index: 0 }; for statement in &data.statements { extra_data(PassWhere::BeforeLocation(current_location), w)?; + for debuginfo in statement.debuginfos.iter() { + writeln!(w, "{INDENT}{INDENT}// DBG: {debuginfo:?}")?; + } let indented_body = format!("{INDENT}{INDENT}{statement:?};"); if options.include_extra_comments { writeln!( @@ -812,6 +815,9 @@ where // Terminator at the bottom. extra_data(PassWhere::BeforeLocation(current_location), w)?; + for debuginfo in data.after_last_stmt_debuginfos.iter() { + writeln!(w, "{INDENT}{INDENT}// DBG: {debuginfo:?}")?; + } if data.terminator.is_some() { let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind); if options.include_extra_comments { diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index d16477adb7767..ae09018f686de 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -11,20 +11,31 @@ use crate::ty::CoroutineArgsExt; /// A statement in a basic block, including information about its source code. #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +#[non_exhaustive] pub struct Statement<'tcx> { pub source_info: SourceInfo, pub kind: StatementKind<'tcx>, + pub debuginfos: Vec>, } impl<'tcx> Statement<'tcx> { /// Changes a statement to a nop. This is both faster than deleting instructions and avoids /// invalidating statement indices in `Location`s. - pub fn make_nop(&mut self) { - self.kind = StatementKind::Nop + pub fn make_nop(&mut self, drop_debuginfo: bool) { + if matches!(self.kind, StatementKind::Nop) { + return; + } + let replaced_stmt = std::mem::replace(&mut self.kind, StatementKind::Nop); + if !drop_debuginfo { + let Some(debuginfo) = replaced_stmt.as_debuginfo() else { + bug!("debuginfo is not yet supported.") + }; + self.debuginfos.push(debuginfo); + } } pub fn new(source_info: SourceInfo, kind: StatementKind<'tcx>) -> Self { - Statement { source_info, kind } + Statement { source_info, kind, debuginfos: Vec::new() } } } @@ -62,6 +73,17 @@ impl<'tcx> StatementKind<'tcx> { _ => None, } } + + pub fn as_debuginfo(&self) -> Option> { + match self { + StatementKind::Assign(box (place, Rvalue::Ref(_, _, ref_place))) + if let Some(local) = place.as_local() => + { + Some(StmtDebugInfo::AssignRef(local, *ref_place)) + } + _ => None, + } + } } /////////////////////////////////////////////////////////////////////////// @@ -938,3 +960,8 @@ impl RawPtrKind { } } } + +#[derive(Debug, Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +pub enum StmtDebugInfo<'tcx> { + AssignRef(Local, Place<'tcx>), +} diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 929ebe1aee181..3e9c7a50311d9 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -95,6 +95,22 @@ macro_rules! make_mir_visitor { self.super_source_scope_data(scope_data); } + fn visit_statement_debuginfos( + &mut self, + stmt_debuginfo: & $($mutability)? [StmtDebugInfo<'tcx>], + location: Location + ) { + self.super_statement_debuginfos(stmt_debuginfo, location); + } + + fn visit_statement_debuginfo( + &mut self, + stmt_debuginfo: & $($mutability)? StmtDebugInfo<'tcx>, + location: Location + ) { + self.super_statement_debuginfo(stmt_debuginfo, location); + } + fn visit_statement( &mut self, statement: & $($mutability)? Statement<'tcx>, @@ -301,6 +317,7 @@ macro_rules! make_mir_visitor { { let BasicBlockData { statements, + after_last_stmt_debuginfos, terminator, is_cleanup: _ } = data; @@ -312,8 +329,9 @@ macro_rules! make_mir_visitor { index += 1; } + let location = Location { block, statement_index: index }; + self.visit_statement_debuginfos(after_last_stmt_debuginfos, location); if let Some(terminator) = terminator { - let location = Location { block, statement_index: index }; self.visit_terminator(terminator, location); } } @@ -376,14 +394,46 @@ macro_rules! make_mir_visitor { } } + fn super_statement_debuginfos( + &mut self, + stmt_debuginfo: & $($mutability)? [StmtDebugInfo<'tcx>], + location: Location + ) { + for debuginfo in stmt_debuginfo { + self.visit_statement_debuginfo(debuginfo, location); + } + } + + fn super_statement_debuginfo( + &mut self, + stmt_debuginfo: & $($mutability)? StmtDebugInfo<'tcx>, + location: Location + ) { + match stmt_debuginfo { + StmtDebugInfo::AssignRef(local, place) => { + self.visit_local( + $(& $mutability)? *local, + PlaceContext::NonUse(NonUseContext::VarDebugInfo), + location + ); + self.visit_place( + place, + PlaceContext::NonUse(NonUseContext::VarDebugInfo), + location + ); + }, + } + } + fn super_statement( &mut self, statement: & $($mutability)? Statement<'tcx>, location: Location ) { - let Statement { source_info, kind } = statement; + let Statement { source_info, kind, debuginfos } = statement; self.visit_source_info(source_info); + self.visit_statement_debuginfos(debuginfos, location); match kind { StatementKind::Assign(box (place, rvalue)) => { self.visit_assign(place, rvalue, location); diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index 6ec1b03a34e68..db46f779d3c8f 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -205,6 +205,7 @@ impl DefUse { /// All of the caveats of `MaybeLiveLocals` apply. pub struct MaybeTransitiveLiveLocals<'a> { always_live: &'a DenseBitSet, + debuginfo_locals: &'a DenseBitSet, } impl<'a> MaybeTransitiveLiveLocals<'a> { @@ -212,8 +213,46 @@ impl<'a> MaybeTransitiveLiveLocals<'a> { /// considered live. /// /// This should include at least all locals that are ever borrowed. - pub fn new(always_live: &'a DenseBitSet) -> Self { - MaybeTransitiveLiveLocals { always_live } + pub fn new( + always_live: &'a DenseBitSet, + debuginfo_locals: &'a DenseBitSet, + ) -> Self { + MaybeTransitiveLiveLocals { always_live, debuginfo_locals } + } + + pub fn can_be_removed_if_dead<'tcx>( + stmt_kind: &StatementKind<'tcx>, + always_live: &DenseBitSet, + debuginfo_locals: &'a DenseBitSet, + ) -> Option> { + // Compute the place that we are storing to, if any + let destination = match stmt_kind { + StatementKind::Assign(box (place, rvalue)) => (rvalue.is_safe_to_remove() + && (!debuginfo_locals.contains(place.local) + || (place.as_local().is_some() && matches!(rvalue, mir::Rvalue::Ref(..))))) + .then_some(*place), + StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => { + (!debuginfo_locals.contains(place.local)).then_some(**place) + } + StatementKind::FakeRead(_) + | StatementKind::StorageLive(_) + | StatementKind::StorageDead(_) + | StatementKind::Retag(..) + | StatementKind::AscribeUserType(..) + | StatementKind::PlaceMention(..) + | StatementKind::Coverage(..) + | StatementKind::Intrinsic(..) + | StatementKind::ConstEvalCounter + | StatementKind::BackwardIncompatibleDropHint { .. } + | StatementKind::Nop => None, + }; + if let Some(destination) = destination + && !destination.is_indirect() + && !always_live.contains(destination.local) + { + return Some(destination); + } + None } } @@ -238,32 +277,12 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> { statement: &mir::Statement<'tcx>, location: Location, ) { - // Compute the place that we are storing to, if any - let destination = match &statement.kind { - StatementKind::Assign(assign) => assign.1.is_safe_to_remove().then_some(assign.0), - StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => { - Some(**place) - } - StatementKind::FakeRead(_) - | StatementKind::StorageLive(_) - | StatementKind::StorageDead(_) - | StatementKind::Retag(..) - | StatementKind::AscribeUserType(..) - | StatementKind::PlaceMention(..) - | StatementKind::Coverage(..) - | StatementKind::Intrinsic(..) - | StatementKind::ConstEvalCounter - | StatementKind::BackwardIncompatibleDropHint { .. } - | StatementKind::Nop => None, - }; - if let Some(destination) = destination { - if !destination.is_indirect() - && !state.contains(destination.local) - && !self.always_live.contains(destination.local) - { - // This store is dead - return; - } + if let Some(destination) = + Self::can_be_removed_if_dead(&statement.kind, &self.always_live, &self.debuginfo_locals) + && !state.contains(destination.local) + { + // This store is dead + return; } TransferFunction(state).visit_statement(statement, location); } diff --git a/compiler/rustc_mir_transform/src/check_enums.rs b/compiler/rustc_mir_transform/src/check_enums.rs index e06e0c6122e8d..240da87ab278b 100644 --- a/compiler/rustc_mir_transform/src/check_enums.rs +++ b/compiler/rustc_mir_transform/src/check_enums.rs @@ -230,11 +230,11 @@ fn split_block( let block_data = &mut basic_blocks[location.block]; // Drain every statement after this one and move the current terminator to a new basic block. - let new_block = BasicBlockData { - statements: block_data.statements.split_off(location.statement_index), - terminator: block_data.terminator.take(), - is_cleanup: block_data.is_cleanup, - }; + let new_block = BasicBlockData::new_stmts( + block_data.statements.split_off(location.statement_index), + block_data.terminator.take(), + block_data.is_cleanup, + ); basic_blocks.push(new_block) } @@ -270,10 +270,9 @@ fn insert_discr_cast_to_u128<'tcx>( let mu_array = local_decls.push(LocalDecl::with_source_info(mu_array_ty, source_info)).into(); let rvalue = Rvalue::Cast(CastKind::Transmute, source_op, mu_array_ty); - block_data.statements.push(Statement { - source_info, - kind: StatementKind::Assign(Box::new((mu_array, rvalue))), - }); + block_data + .statements + .push(Statement::new(source_info, StatementKind::Assign(Box::new((mu_array, rvalue))))); // Index into the array of MaybeUninit to get something that is actually // as wide as the discriminant. @@ -294,10 +293,10 @@ fn insert_discr_cast_to_u128<'tcx>( let op_as_int = local_decls.push(LocalDecl::with_source_info(operand_int_ty, source_info)).into(); let rvalue = Rvalue::Cast(CastKind::Transmute, source_op, operand_int_ty); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new((op_as_int, rvalue))), - }); + StatementKind::Assign(Box::new((op_as_int, rvalue))), + )); (CastKind::IntToInt, Operand::Copy(op_as_int)) }; @@ -306,10 +305,10 @@ fn insert_discr_cast_to_u128<'tcx>( let rvalue = Rvalue::Cast(cast_kind, discr_ty_bits, discr.ty); let discr_in_discr_ty = local_decls.push(LocalDecl::with_source_info(discr.ty, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new((discr_in_discr_ty, rvalue))), - }); + StatementKind::Assign(Box::new((discr_in_discr_ty, rvalue))), + )); // Cast the discriminant to a u128 (base for comparisions of enum discriminants). let const_u128 = Ty::new_uint(tcx, ty::UintTy::U128); @@ -317,7 +316,7 @@ fn insert_discr_cast_to_u128<'tcx>( let discr = local_decls.push(LocalDecl::with_source_info(const_u128, source_info)).into(); block_data .statements - .push(Statement { source_info, kind: StatementKind::Assign(Box::new((discr, rvalue))) }); + .push(Statement::new(source_info, StatementKind::Assign(Box::new((discr, rvalue))))); discr } @@ -390,9 +389,9 @@ fn insert_uninhabited_enum_check<'tcx>( ) { let is_ok: Place<'_> = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new(( + StatementKind::Assign(Box::new(( is_ok, Rvalue::Use(Operand::Constant(Box::new(ConstOperand { span: source_info.span, @@ -400,7 +399,7 @@ fn insert_uninhabited_enum_check<'tcx>( const_: Const::Val(ConstValue::from_bool(false), tcx.types.bool), }))), ))), - }); + )); block_data.terminator = Some(Terminator { source_info, @@ -463,19 +462,19 @@ fn insert_niche_check<'tcx>( let discr_diff: Place<'_> = local_decls.push(LocalDecl::with_source_info(tcx.types.u128, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new(( + StatementKind::Assign(Box::new(( discr_diff, Rvalue::BinaryOp(BinOp::Sub, Box::new((Operand::Copy(discr), start_const))), ))), - }); + )); let is_ok: Place<'_> = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new(( + StatementKind::Assign(Box::new(( is_ok, Rvalue::BinaryOp( // This is a `WrappingRange`, so make sure to get the wrapping right. @@ -483,7 +482,7 @@ fn insert_niche_check<'tcx>( Box::new((Operand::Copy(discr_diff), end_start_diff_const)), ), ))), - }); + )); block_data.terminator = Some(Terminator { source_info, diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index 4be67b873f737..b0bf7f484bedf 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -36,7 +36,9 @@ impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck { CoverageKind::BlockMarker { .. } | CoverageKind::SpanMarker { .. }, ) | StatementKind::FakeRead(..) - | StatementKind::BackwardIncompatibleDropHint { .. } => statement.make_nop(), + | StatementKind::BackwardIncompatibleDropHint { .. } => { + statement.make_nop(true) + } StatementKind::Assign(box ( _, Rvalue::Cast( diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs index cddeefca68174..fd46dd9cc50e5 100644 --- a/compiler/rustc_mir_transform/src/copy_prop.rs +++ b/compiler/rustc_mir_transform/src/copy_prop.rs @@ -52,7 +52,7 @@ impl<'tcx> crate::MirPass<'tcx> for CopyProp { Replacer { tcx, copy_classes: ssa.copy_classes(), fully_moved, storage_to_remove } .visit_body_preserves_cfg(body); - crate::simplify::remove_unused_definitions(body); + crate::simplify::remove_unused_definitions(body, false); } fn is_required(&self) -> bool { @@ -138,7 +138,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> { if let StatementKind::StorageLive(l) | StatementKind::StorageDead(l) = stmt.kind && self.storage_to_remove.contains(l) { - stmt.make_nop(); + stmt.make_nop(true); return; } @@ -150,7 +150,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> { *rhs && lhs == rhs { - stmt.make_nop(); + stmt.make_nop(true); } } } diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 761d5461a996f..879008fd213b3 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -412,7 +412,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { if let StatementKind::StorageLive(l) | StatementKind::StorageDead(l) = s.kind && self.remap.contains(l) { - s.make_nop(); + s.make_nop(true); } } diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs index eea2b0990d730..d8d78546b939b 100644 --- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs +++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs @@ -22,21 +22,21 @@ use rustc_mir_dataflow::impls::{ LivenessTransferFunction, MaybeTransitiveLiveLocals, borrowed_locals, }; +use crate::simplify::remove_unused_definitions; use crate::util::is_within_packed; /// Performs the optimization on the body /// /// The `borrowed` set must be a `DenseBitSet` of all the locals that are ever borrowed in this /// body. It can be generated via the [`borrowed_locals`] function. -fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { +fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { let borrowed_locals = borrowed_locals(body); // If the user requests complete debuginfo, mark the locals that appear in it as live, so // we don't remove assignments to them. - let mut always_live = debuginfo_locals(body); - always_live.union(&borrowed_locals); + let debuginfo_locals = debuginfo_locals(body); - let mut live = MaybeTransitiveLiveLocals::new(&always_live) + let mut live = MaybeTransitiveLiveLocals::new(&borrowed_locals, &debuginfo_locals) .iterate_to_fixpoint(tcx, body, None) .into_results_cursor(body); @@ -75,47 +75,28 @@ fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { } for (statement_index, statement) in bb_data.statements.iter().enumerate().rev() { - let loc = Location { block: bb, statement_index }; - if let StatementKind::Assign(assign) = &statement.kind { - if !assign.1.is_safe_to_remove() { - continue; - } - } - match &statement.kind { - StatementKind::Assign(box (place, _)) - | StatementKind::SetDiscriminant { place: box place, .. } - | StatementKind::Deinit(box place) => { - if !place.is_indirect() && !always_live.contains(place.local) { - live.seek_before_primary_effect(loc); - if !live.get().contains(place.local) { - patch.push(loc); - } - } - } - StatementKind::Retag(_, _) - | StatementKind::StorageLive(_) - | StatementKind::StorageDead(_) - | StatementKind::Coverage(_) - | StatementKind::Intrinsic(_) - | StatementKind::ConstEvalCounter - | StatementKind::PlaceMention(_) - | StatementKind::BackwardIncompatibleDropHint { .. } - | StatementKind::Nop => {} - - StatementKind::FakeRead(_) | StatementKind::AscribeUserType(_, _) => { - bug!("{:?} not found in this MIR phase!", statement.kind) + if let Some(destination) = MaybeTransitiveLiveLocals::can_be_removed_if_dead( + &statement.kind, + &borrowed_locals, + &debuginfo_locals, + ) { + let loc = Location { block: bb, statement_index }; + live.seek_before_primary_effect(loc); + if !live.get().contains(destination.local) { + patch.push((loc, !debuginfo_locals.contains(destination.local))); } } } } if patch.is_empty() && call_operands_to_move.is_empty() { - return; + return false; } + let eliminated = !patch.is_empty(); let bbs = body.basic_blocks.as_mut_preserves_cfg(); - for Location { block, statement_index } in patch { - bbs[block].statements[statement_index].make_nop(); + for (Location { block, statement_index }, drop_debuginfo) in patch { + bbs[block].statements[statement_index].make_nop(drop_debuginfo); } for (block, argument_index) in call_operands_to_move { let TerminatorKind::Call { ref mut args, .. } = bbs[block].terminator_mut().kind else { @@ -125,6 +106,8 @@ fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let Operand::Copy(place) = *arg else { bug!() }; *arg = Operand::Move(place); } + + eliminated } pub(super) enum DeadStoreElimination { @@ -145,7 +128,10 @@ impl<'tcx> crate::MirPass<'tcx> for DeadStoreElimination { } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - eliminate(tcx, body); + if eliminate(tcx, body) { + // Remove unnecessary StorageLive and StorageDead annotations. + remove_unused_definitions(body, true); + } } fn is_required(&self) -> bool { diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 4c94a6c524e00..5e8f8de86bb12 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -308,7 +308,7 @@ impl<'tcx> MutVisitor<'tcx> for Merger<'tcx> { StatementKind::StorageDead(local) | StatementKind::StorageLive(local) if self.merged_locals.contains(*local) => { - statement.make_nop(); + statement.make_nop(true); return; } _ => (), @@ -323,7 +323,7 @@ impl<'tcx> MutVisitor<'tcx> for Merger<'tcx> { // (this includes the original statement we wanted to eliminate). if dest == place { debug!("{:?} turned into self-assignment, deleting", location); - statement.make_nop(); + statement.make_nop(true); } } _ => {} diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index b17b7f450009c..37c534f3f6373 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1846,7 +1846,7 @@ impl<'tcx> MutVisitor<'tcx> for StorageRemover<'tcx> { StatementKind::StorageLive(l) | StatementKind::StorageDead(l) if self.reused_locals.contains(l) => { - stmt.make_nop() + stmt.make_nop(true) } _ => self.super_statement(stmt, loc), } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 7852bb7ae2f4e..c627c2d5dd72c 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -993,6 +993,10 @@ fn inline_call<'tcx, I: Inliner<'tcx>>( // people working on rust can build with or without debuginfo while // still getting consistent results from the mir-opt tests. caller_body.var_debug_info.append(&mut callee_body.var_debug_info); + } else { + for bb in callee_body.basic_blocks_mut() { + bb.drop_debuginfo(); + } } caller_body.basic_blocks_mut().append(callee_body.basic_blocks_mut()); diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 1a91d6bd7da98..1b90e9158f6b8 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -156,7 +156,7 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt { patch.add_statement(location, stmt); } - st.make_nop(); + st.make_nop(true); } } diff --git a/compiler/rustc_mir_transform/src/nrvo.rs b/compiler/rustc_mir_transform/src/nrvo.rs index 965002aae04c7..23f7cdbdd67f4 100644 --- a/compiler/rustc_mir_transform/src/nrvo.rs +++ b/compiler/rustc_mir_transform/src/nrvo.rs @@ -54,7 +54,7 @@ impl<'tcx> crate::MirPass<'tcx> for RenameReturnPlace { // Clean up the `NOP`s we inserted for statements made useless by our renaming. for block_data in body.basic_blocks.as_mut_preserves_cfg() { - block_data.statements.retain(|stmt| stmt.kind != mir::StatementKind::Nop); + block_data.retain_statements(|stmt| stmt.kind != mir::StatementKind::Nop); } // Overwrite the debuginfo of `_0` with that of the renamed local. diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index 4e8f30e077b0a..ce4f1eaeb9afc 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -1052,7 +1052,7 @@ fn promote_candidates<'tcx>( // Eliminate assignments to, and drops of promoted temps. let promoted = |index: Local| temps[index] == TempState::PromotedOut; for block in body.basic_blocks_mut() { - block.statements.retain(|statement| match &statement.kind { + block.retain_statements(|statement| match &statement.kind { StatementKind::Assign(box (place, _)) => { if let Some(index) = place.as_local() { !promoted(index) diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs index 368d5340ac34f..7530972c3ce9f 100644 --- a/compiler/rustc_mir_transform/src/ref_prop.rs +++ b/compiler/rustc_mir_transform/src/ref_prop.rs @@ -99,7 +99,7 @@ fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { replacer.visit_body_preserves_cfg(body); if replacer.any_replacement { - crate::simplify::remove_unused_definitions(body); + crate::simplify::remove_unused_definitions(body, true); } replacer.any_replacement @@ -409,7 +409,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> { StatementKind::StorageLive(l) | StatementKind::StorageDead(l) if self.storage_to_remove.contains(l) => { - stmt.make_nop(); + stmt.make_nop(true); } // Do not remove assignments as they may still be useful for debuginfo. _ => self.super_statement(stmt, loc), diff --git a/compiler/rustc_mir_transform/src/remove_place_mention.rs b/compiler/rustc_mir_transform/src/remove_place_mention.rs index cb598ceb4dfea..d56b51bb496e4 100644 --- a/compiler/rustc_mir_transform/src/remove_place_mention.rs +++ b/compiler/rustc_mir_transform/src/remove_place_mention.rs @@ -14,7 +14,7 @@ impl<'tcx> crate::MirPass<'tcx> for RemovePlaceMention { fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) { trace!("Running RemovePlaceMention on {:?}", body.source); for data in body.basic_blocks.as_mut_preserves_cfg() { - data.statements.retain(|statement| match statement.kind { + data.retain_statements(|statement| match statement.kind { StatementKind::PlaceMention(..) | StatementKind::Nop => false, _ => true, }) diff --git a/compiler/rustc_mir_transform/src/remove_storage_markers.rs b/compiler/rustc_mir_transform/src/remove_storage_markers.rs index 1ae33c0096875..cb97d2c865ac9 100644 --- a/compiler/rustc_mir_transform/src/remove_storage_markers.rs +++ b/compiler/rustc_mir_transform/src/remove_storage_markers.rs @@ -14,7 +14,7 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveStorageMarkers { fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { trace!("Running RemoveStorageMarkers on {:?}", body.source); for data in body.basic_blocks.as_mut_preserves_cfg() { - data.statements.retain(|statement| match statement.kind { + data.retain_statements(|statement| match statement.kind { StatementKind::StorageLive(..) | StatementKind::StorageDead(..) | StatementKind::Nop => false, diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index c4dc8638b26ab..90c1b3520b96e 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -141,7 +141,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> { && let ty = place_for_ty.ty(self.local_decls, self.tcx).ty && self.known_to_be_zst(ty) { - statement.make_nop(); + statement.make_nop(true); } else { self.super_statement(statement, loc); } diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index db933da641371..c431951fb7b70 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -35,7 +35,9 @@ //! pre-"runtime" MIR! use rustc_index::{Idx, IndexSlice, IndexVec}; -use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; +use rustc_middle::mir::visit::{ + MutVisitor, MutatingUseContext, NonUseContext, PlaceContext, Visitor, +}; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; use rustc_span::DUMMY_SP; @@ -308,7 +310,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { fn strip_nops(&mut self) { for blk in self.basic_blocks.iter_mut() { - blk.statements.retain(|stmt| !matches!(stmt.kind, StatementKind::Nop)) + blk.strip_nops(); } } } @@ -414,7 +416,7 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyLocals { trace!("running SimplifyLocals on {:?}", body.source); // First, we're going to get a count of *actual* uses for every `Local`. - let mut used_locals = UsedLocals::new(body); + let mut used_locals = UsedLocals::new(body, false); // Next, we're going to remove any `Local` with zero actual uses. When we remove those // `Locals`, we're also going to subtract any uses of other `Locals` from the `used_locals` @@ -442,9 +444,9 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyLocals { } } -pub(super) fn remove_unused_definitions<'tcx>(body: &mut Body<'tcx>) { +pub(super) fn remove_unused_definitions<'tcx>(body: &mut Body<'tcx>, allow_debuginfo: bool) { // First, we're going to get a count of *actual* uses for every `Local`. - let mut used_locals = UsedLocals::new(body); + let mut used_locals = UsedLocals::new(body, allow_debuginfo); // Next, we're going to remove any `Local` with zero actual uses. When we remove those // `Locals`, we're also going to subtract any uses of other `Locals` from the `used_locals` @@ -483,15 +485,19 @@ struct UsedLocals { increment: bool, arg_count: u32, use_count: IndexVec, + debuginfo_use: IndexVec, + allow_debuginfo: bool, } impl UsedLocals { /// Determines which locals are used & unused in the given body. - fn new(body: &Body<'_>) -> Self { + fn new(body: &Body<'_>, allow_debuginfo: bool) -> Self { let mut this = Self { increment: true, arg_count: body.arg_count.try_into().unwrap(), use_count: IndexVec::from_elem(0, &body.local_decls), + debuginfo_use: IndexVec::from_elem(false, &body.local_decls), + allow_debuginfo, }; this.visit_body(body); this @@ -501,8 +507,22 @@ impl UsedLocals { /// /// Return place and arguments are always considered used. fn is_used(&self, local: Local) -> bool { - trace!("is_used({:?}): use_count: {:?}", local, self.use_count[local]); - local.as_u32() <= self.arg_count || self.use_count[local] != 0 + trace!( + "is_used({:?}): use_count: {:?}, debuginfo_use: {}", + local, self.use_count[local], self.debuginfo_use[local] + ); + local.as_u32() <= self.arg_count || self.use_count[local] != 0 || self.debuginfo_use[local] + } + + fn is_only_debuginfo_used(&self, local: Local) -> bool { + self.allow_debuginfo + && local.as_u32() > self.arg_count + && self.use_count[local] == 0 + && self.debuginfo_use[local] + } + + fn is_debuginfo_used(&self, local: Local) -> bool { + self.debuginfo_use[local] } /// Updates the use counts to reflect the removal of given statement. @@ -514,6 +534,12 @@ impl UsedLocals { self.visit_statement(statement, location); } + fn statement_debuginfo_updated(&mut self, statement: &Statement<'_>) { + // The location of the statement is irrelevant. + let location = Location::START; + self.visit_statement_debuginfos(&statement.debuginfos, location); + } + /// Visits a left-hand side of an assignment. fn visit_lhs(&mut self, place: &Place<'_>, location: Location) { if place.is_indirect() { @@ -544,12 +570,16 @@ impl<'tcx> Visitor<'tcx> for UsedLocals { self.super_statement(statement, location); } - StatementKind::ConstEvalCounter | StatementKind::Nop => {} - - StatementKind::StorageLive(_local) | StatementKind::StorageDead(_local) => {} + StatementKind::ConstEvalCounter + | StatementKind::Nop + | StatementKind::StorageLive(..) + | StatementKind::StorageDead(..) => { + self.visit_statement_debuginfos(&statement.debuginfos, location); + } StatementKind::Assign(box (ref place, ref rvalue)) => { if rvalue.is_safe_to_remove() { + self.visit_statement_debuginfos(&statement.debuginfos, location); self.visit_lhs(place, location); self.visit_rvalue(rvalue, location); } else { @@ -560,18 +590,22 @@ impl<'tcx> Visitor<'tcx> for UsedLocals { StatementKind::SetDiscriminant { ref place, variant_index: _ } | StatementKind::Deinit(ref place) | StatementKind::BackwardIncompatibleDropHint { ref place, reason: _ } => { + self.visit_statement_debuginfos(&statement.debuginfos, location); self.visit_lhs(place, location); } } } - fn visit_local(&mut self, local: Local, _ctx: PlaceContext, _location: Location) { + fn visit_local(&mut self, local: Local, ctx: PlaceContext, _location: Location) { + if ctx == PlaceContext::NonUse(NonUseContext::VarDebugInfo) { + self.debuginfo_use[local] = true; + return; + } if self.increment { self.use_count[local] += 1; } else { - assert_ne!(self.use_count[local], 0); self.use_count[local] -= 1; - } + }; } } @@ -588,30 +622,40 @@ fn remove_unused_definitions_helper(used_locals: &mut UsedLocals, body: &mut Bod for data in body.basic_blocks.as_mut_preserves_cfg() { // Remove unnecessary StorageLive and StorageDead annotations. - data.statements.retain(|statement| { - let keep = match &statement.kind { + for statement in data.statements.iter_mut() { + let drop_debuginfo = match &statement.kind { StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => { - used_locals.is_used(*local) + if used_locals.is_used(*local) + && !used_locals.is_only_debuginfo_used(*local) + { + continue; + } + true } - StatementKind::Assign(box (place, _)) => used_locals.is_used(place.local), - - StatementKind::SetDiscriminant { place, .. } - | StatementKind::BackwardIncompatibleDropHint { place, reason: _ } - | StatementKind::Deinit(place) => used_locals.is_used(place.local), - StatementKind::Nop => false, - _ => true, + StatementKind::Assign(box (place, _)) + | StatementKind::SetDiscriminant { box place, .. } + | StatementKind::BackwardIncompatibleDropHint { box place, .. } + | StatementKind::Deinit(box place) => { + if used_locals.is_used(place.local) + && !(used_locals.is_only_debuginfo_used(place.local) + && statement.kind.as_debuginfo().is_some()) + { + continue; + } + !used_locals.is_debuginfo_used(place.local) + } + _ => continue, }; - - if !keep { - trace!("removing statement {:?}", statement); - modified = true; - used_locals.statement_removed(statement); - } - - keep - }); + trace!("removing statement {:?}", statement); + modified = true; + used_locals.statement_removed(statement); + statement.make_nop(drop_debuginfo); + used_locals.statement_debuginfo_updated(statement); + } + data.strip_nops(); } } + // cleanup unused local } struct LocalUpdater<'tcx> { diff --git a/compiler/rustc_mir_transform/src/simplify_branches.rs b/compiler/rustc_mir_transform/src/simplify_branches.rs index 886f4d6e50900..fecbb09b2b67b 100644 --- a/compiler/rustc_mir_transform/src/simplify_branches.rs +++ b/compiler/rustc_mir_transform/src/simplify_branches.rs @@ -28,7 +28,7 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition { && let Some(constant) = c.const_.try_eval_bool(tcx, typing_env) { if constant { - stmt.make_nop(); + stmt.make_nop(true); } else { block.statements.clear(); block.terminator_mut().kind = TerminatorKind::Unreachable; diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index c60eb566521c5..4597439e269ff 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -76,7 +76,7 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral { // delete comparison statement if it the value being switched on was moved, which means // it can not be user later on if opt.can_remove_bin_op_stmt { - bb.statements[opt.bin_op_stmt_idx].make_nop(); + bb.statements[opt.bin_op_stmt_idx].make_nop(true); } else { // if the integer being compared to a const integral is being moved into the // comparison, e.g `_2 = Eq(move _3, const 'x');` @@ -136,7 +136,7 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral { } for (idx, bb_idx) in storage_deads_to_remove { - body.basic_blocks_mut()[bb_idx].statements[idx].make_nop(); + body.basic_blocks_mut()[bb_idx].statements[idx].make_nop(true); } for (idx, stmt) in storage_deads_to_insert { diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index 7c6ccc89c4f30..69be045dbd983 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -334,7 +334,7 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { for (_, _, fl) in final_locals { self.patch.add_statement(location, StatementKind::StorageLive(fl)); } - statement.make_nop(); + statement.make_nop(true); } return; } @@ -343,7 +343,7 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { for (_, _, fl) in final_locals { self.patch.add_statement(location, StatementKind::StorageDead(fl)); } - statement.make_nop(); + statement.make_nop(true); } return; } @@ -353,7 +353,7 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { self.patch .add_statement(location, StatementKind::Deinit(Box::new(fl.into()))); } - statement.make_nop(); + statement.make_nop(true); return; } } @@ -383,7 +383,7 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { ); } } - statement.make_nop(); + statement.make_nop(true); return; } } @@ -445,7 +445,7 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { StatementKind::Assign(Box::new((new_local.into(), rvalue))), ); } - statement.make_nop(); + statement.make_nop(true); return; } } diff --git a/tests/codegen/debug-fndef-size.rs b/tests/codegen/debug-fndef-size.rs index 8f716c34e7b74..02629bd748c45 100644 --- a/tests/codegen/debug-fndef-size.rs +++ b/tests/codegen/debug-fndef-size.rs @@ -16,5 +16,5 @@ pub fn main() { // CHECK: %compare.dbg.spill = alloca [0 x i8], align 1 // CHECK: dbg{{.}}declare({{(metadata )?}}ptr %compare.dbg.spill, {{(metadata )?}}![[VAR:.*]], {{(metadata )?}}!DIExpression() -// CHECK: ![[TYPE:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "fn(&i32, &i32) -> core::cmp::Ordering", baseType: !{{.*}}, align: 8, dwarfAddressSpace: {{.*}}) -// CHECK: ![[VAR]] = !DILocalVariable(name: "compare", scope: !{{.*}}, file: !{{.*}}, line: {{.*}}, type: ![[TYPE]], align: 8) +// CHECK-DAG: ![[TYPE:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "fn(&i32, &i32) -> core::cmp::Ordering", baseType: !{{.*}}, align: 8, dwarfAddressSpace: {{.*}}) +// CHECK-DAG: ![[VAR]] = !DILocalVariable(name: "compare", scope: !{{.*}}, file: !{{.*}}, line: {{.*}}, type: ![[TYPE]], align: 8) diff --git a/tests/codegen/debuginfo-dse.rs b/tests/codegen/debuginfo-dse.rs new file mode 100644 index 0000000000000..de720bb456ca7 --- /dev/null +++ b/tests/codegen/debuginfo-dse.rs @@ -0,0 +1,52 @@ +//@ compile-flags: -Copt-level=3 -g +//@ revisions: CODEGEN OPTIMIZED +//@[CODEGEN] compile-flags: -Cno-prepopulate-passes + +#![crate_type = "lib"] + +#[repr(C)] +pub struct Foo(i32, i64, i32); + +#[no_mangle] +fn r#ref(ref_foo: &Foo) -> i32 { + // CHECK-LABEL: define {{.*}} i32 @ref + // CHECK-SAME: (ptr {{.*}} [[ARG_ref_foo:%.*]]) + // OPTIMIZED: #dbg_value(ptr [[ARG_ref_foo]], [[VAR_ref_foo:![0-9]+]], !DIExpression() + // CHECK: #dbg_value(ptr [[ARG_ref_foo]], [[VAR_ref_v0:![0-9]+]], !DIExpression() + // CHECK: #dbg_value(ptr [[ARG_ref_foo]], [[VAR_ref_v1:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 8, DW_OP_stack_value) + // CHECK: #dbg_value(ptr [[ARG_ref_foo]], [[VAR_ref_v2:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 16, DW_OP_stack_value) + let ref_v0 = &ref_foo.0; + let ref_v1 = &ref_foo.1; + let ref_v2 = &ref_foo.2; + ref_foo.0 +} + +#[no_mangle] +fn ptr(ptr_foo: Foo) -> i32 { + // CHECK-LABEL: define {{.*}} i32 @ptr + // CHECK-SAME: (ptr {{.*}} [[ARG_ptr_foo:%.*]]) + // CHECK: #dbg_value(ptr [[ARG_ptr_foo]], [[VAR_ptr_v0:![0-9]+]], !DIExpression() + // CHECK: #dbg_value(ptr [[ARG_ptr_foo]], [[VAR_ptr_v1:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 8, DW_OP_stack_value) + // CHECK: #dbg_value(ptr [[ARG_ptr_foo]], [[VAR_ptr_v2:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 16, DW_OP_stack_value) + let ptr_v0 = &ptr_foo.0; + let ptr_v1 = &ptr_foo.1; + let ptr_v2 = &ptr_foo.2; + ptr_foo.2 +} + +#[no_mangle] +fn no_ptr(val: i32) -> i32 { + // CHECK-LABEL: define {{.*}} i32 @no_ptr + // CODEGEN: #dbg_value(ptr poison, [[VAR_val_ref:![0-9]+]], !DIExpression() + let val_ref = &val; + val +} + +// OPTIMIZED-DAG: [[VAR_ref_foo]] = !DILocalVariable(name: "ref_foo" +// CHECK-DAG: [[VAR_ref_v0]] = !DILocalVariable(name: "ref_v0" +// CHECK-DAG: [[VAR_ref_v1]] = !DILocalVariable(name: "ref_v1" +// CHECK-DAG: [[VAR_ref_v2]] = !DILocalVariable(name: "ref_v2" +// CHECK-DAG: [[VAR_ptr_v0]] = !DILocalVariable(name: "ptr_v0" +// CHECK-DAG: [[VAR_ptr_v1]] = !DILocalVariable(name: "ptr_v1" +// CHECK-DAG: [[VAR_ptr_v2]] = !DILocalVariable(name: "ptr_v2" +// CODEGEN-DAG: [[VAR_val_ref]] = !DILocalVariable(name: "val_ref" diff --git a/tests/debuginfo/opt/dead_refs.rs b/tests/debuginfo/opt/dead_refs.rs new file mode 100644 index 0000000000000..68cc5cf0e4e78 --- /dev/null +++ b/tests/debuginfo/opt/dead_refs.rs @@ -0,0 +1,49 @@ +//@ compile-flags: -g -Copt-level=3 + +// Checks that we still can access dead variables from debuginfos. + +// === GDB TESTS =================================================================================== + +// gdb-command:run +// gdb-command:print *ref_v0 +// gdb-check:$1 = 0 + +// gdb-command:print *ref_v1 +// gdb-check:$2 = 1 + +// gdb-command:print *ref_v2 +// gdb-check:$3 = 2 + +// === LLDB TESTS ================================================================================== + +// lldb-command:run +// lldb-command:v *ref_v0 +// lldb-check:[...] 0 + +// lldb-command:v *ref_v1 +// lldb-check:[...] 1 + +// lldb-command:v *ref_v2 +// lldb-check:[...] 2 + +#![allow(unused_variables)] +#![feature(omit_gdb_pretty_printer_section)] +#![omit_gdb_pretty_printer_section] + +use std::hint::black_box; + +pub struct Foo(i32, i64, i32); + +#[inline(never)] +#[no_mangle] +fn test_ref(ref_foo: &Foo) -> i32 { + let ref_v0 = &ref_foo.0; + let ref_v1 = &ref_foo.1; + let ref_v2 = &ref_foo.2; + ref_foo.0 // #break +} + +fn main() { + let foo = black_box(Foo(0, 1, 2)); + black_box(test_ref(&foo)); +} diff --git a/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination-initial.diff b/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination-initial.diff index ff18df1efcfc9..d584de6861c0c 100644 --- a/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination-initial.diff +++ b/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination-initial.diff @@ -19,10 +19,6 @@ - _3 = copy _2; - _2 = copy _1; - _1 = copy _5; -+ nop; -+ nop; -+ nop; -+ nop; _4 = cond() -> [return: bb1, unwind continue]; } diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff index 25ffff619e60b..6c5e4a85c6817 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff @@ -68,7 +68,6 @@ } bb0: { - StorageLive(_1); StorageLive(_2); StorageLive(_3); StorageLive(_11); @@ -89,7 +88,6 @@ bb1: { StorageDead(_3); - StorageDead(_1); return; } @@ -135,13 +133,11 @@ + _5 = *const [()] from (copy _10, const 1_usize); StorageDead(_23); StorageDead(_6); - StorageLive(_7); StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); + _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); - StorageDead(_7); - StorageDead(_5); + nop; StorageDead(_4); diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff index b2085afb71379..4bcbaf53a3f2b 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff @@ -34,7 +34,6 @@ } bb0: { - StorageLive(_1); StorageLive(_2); StorageLive(_3); _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; @@ -60,13 +59,11 @@ + _5 = *const [()] from (copy _10, const 1_usize); StorageDead(_11); StorageDead(_6); - StorageLive(_7); StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); + _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); - StorageDead(_7); - StorageDead(_5); + nop; StorageDead(_4); @@ -75,7 +72,6 @@ bb2: { StorageDead(_3); - StorageDead(_1); return; } diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff index 839b53e3b0b3b..01fd9a6cbf42e 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff @@ -68,7 +68,6 @@ } bb0: { - StorageLive(_1); StorageLive(_2); StorageLive(_3); StorageLive(_11); @@ -89,7 +88,6 @@ bb1: { StorageDead(_3); - StorageDead(_1); return; } @@ -135,13 +133,11 @@ + _5 = *const [()] from (copy _10, const 1_usize); StorageDead(_23); StorageDead(_6); - StorageLive(_7); StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); + _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); - StorageDead(_7); - StorageDead(_5); + nop; StorageDead(_4); diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff index b2085afb71379..4bcbaf53a3f2b 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff @@ -34,7 +34,6 @@ } bb0: { - StorageLive(_1); StorageLive(_2); StorageLive(_3); _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; @@ -60,13 +59,11 @@ + _5 = *const [()] from (copy _10, const 1_usize); StorageDead(_11); StorageDead(_6); - StorageLive(_7); StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); + _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); - StorageDead(_7); - StorageDead(_5); + nop; StorageDead(_4); @@ -75,7 +72,6 @@ bb2: { StorageDead(_3); - StorageDead(_1); return; } diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff index f6c111a2228a9..8ee1ee9222f81 100644 --- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff @@ -16,10 +16,12 @@ + let mut _9: *mut A; + let mut _10: usize; + scope 3 (inlined Vec::::as_mut_ptr) { ++ let mut _11: &alloc::raw_vec::RawVec; + scope 4 (inlined alloc::raw_vec::RawVec::::ptr) { ++ let mut _12: &alloc::raw_vec::RawVecInner; + scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::) { + scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::) { -+ let mut _11: std::ptr::NonNull; ++ let mut _13: std::ptr::NonNull; + scope 7 (inlined Unique::::cast::) { + scope 8 (inlined NonNull::::cast::) { + scope 9 (inlined NonNull::::as_ptr) { @@ -39,15 +41,15 @@ + } + } + scope 14 (inlined drop_in_place::<[A]> - shim(Some([A]))) { -+ let mut _12: usize; -+ let mut _13: *mut A; -+ let mut _14: bool; ++ let mut _14: usize; ++ let mut _15: *mut A; ++ let mut _16: bool; + } + } + } + scope 15 (inlined drop_in_place::> - shim(Some(Option))) { -+ let mut _15: isize; -+ let mut _16: isize; ++ let mut _17: isize; ++ let mut _18: isize; + } bb0: { @@ -59,19 +61,21 @@ + StorageLive(_7); + _6 = &mut (*_4); + StorageLive(_10); ++ StorageLive(_11); ++ StorageLive(_12); + StorageLive(_8); + StorageLive(_9); -+ StorageLive(_11); -+ _11 = copy (((((*_6).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); -+ _9 = copy _11 as *mut A (Transmute); -+ StorageDead(_11); ++ StorageLive(_13); ++ _13 = copy (((((*_6).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); ++ _9 = copy _13 as *mut A (Transmute); ++ StorageDead(_13); + _10 = copy ((*_6).1: usize); + _8 = *mut [A] from (copy _9, copy _10); + StorageDead(_9); -+ StorageLive(_12); -+ StorageLive(_13); + StorageLive(_14); -+ _12 = const 0_usize; ++ StorageLive(_15); ++ StorageLive(_16); ++ _14 = const 0_usize; + goto -> bb4; } @@ -83,35 +87,37 @@ StorageLive(_5); _5 = copy _2; - _0 = drop_in_place::>(move _5) -> [return: bb2, unwind unreachable]; -+ StorageLive(_15); -+ StorageLive(_16); -+ _15 = discriminant((*_5)); -+ switchInt(move _15) -> [0: bb5, otherwise: bb6]; ++ StorageLive(_17); ++ StorageLive(_18); ++ _17 = discriminant((*_5)); ++ switchInt(move _17) -> [0: bb5, otherwise: bb6]; } bb2: { ++ StorageDead(_16); ++ StorageDead(_15); + StorageDead(_14); -+ StorageDead(_13); -+ StorageDead(_12); + StorageDead(_8); ++ StorageDead(_12); ++ StorageDead(_11); + StorageDead(_10); + drop(((*_4).0: alloc::raw_vec::RawVec)) -> [return: bb1, unwind unreachable]; + } + + bb3: { -+ _13 = &raw mut (*_8)[_12]; -+ _12 = Add(move _12, const 1_usize); -+ drop((*_13)) -> [return: bb4, unwind unreachable]; ++ _15 = &raw mut (*_8)[_14]; ++ _14 = Add(move _14, const 1_usize); ++ drop((*_15)) -> [return: bb4, unwind unreachable]; + } + + bb4: { -+ _14 = Eq(copy _12, copy _10); -+ switchInt(move _14) -> [0: bb3, otherwise: bb2]; ++ _16 = Eq(copy _14, copy _10); ++ switchInt(move _16) -> [0: bb3, otherwise: bb2]; + } + + bb5: { -+ StorageDead(_16); -+ StorageDead(_15); ++ StorageDead(_18); ++ StorageDead(_17); StorageDead(_5); return; + } diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff index 1e9a6dd4f5c8f..0477b1ee52601 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff @@ -64,9 +64,8 @@ + let mut _45: &mut std::future::Ready<()>; + let mut _46: &mut std::pin::Pin<&mut std::future::Ready<()>>; + scope 14 (inlined > as DerefMut>::deref_mut) { -+ let mut _47: std::pin::Pin<&mut std::future::Ready<()>>; + scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) { -+ let mut _48: &mut &mut std::future::Ready<()>; ++ let mut _47: &mut &mut std::future::Ready<()>; + scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) { + } + scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) { @@ -76,15 +75,15 @@ + } + } + scope 19 (inlined Option::<()>::take) { -+ let mut _49: std::option::Option<()>; ++ let mut _48: std::option::Option<()>; + scope 20 (inlined std::mem::replace::>) { + scope 21 { + } + } + } + scope 22 (inlined #[track_caller] Option::<()>::expect) { -+ let mut _50: isize; -+ let mut _51: !; ++ let mut _49: isize; ++ let mut _50: !; + scope 23 { + } + } @@ -227,30 +226,22 @@ + _23 = move _24; + _22 = &mut (*_23); + StorageDead(_24); ++ StorageLive(_44); + StorageLive(_45); + StorageLive(_46); -+ StorageLive(_51); ++ StorageLive(_47); ++ StorageLive(_50); + StorageLive(_42); + StorageLive(_43); -+ StorageLive(_44); -+ _46 = &mut _19; -+ StorageLive(_47); -+ StorageLive(_48); -+ _48 = &mut (_19.0: &mut std::future::Ready<()>); + _45 = copy (_19.0: &mut std::future::Ready<()>); ++ StorageLive(_48); ++ _48 = Option::<()>::None; ++ _43 = copy ((*_45).0: std::option::Option<()>); ++ ((*_45).0: std::option::Option<()>) = copy _48; + StorageDead(_48); -+ _47 = Pin::<&mut std::future::Ready<()>> { pointer: copy _45 }; -+ StorageDead(_47); -+ _44 = &mut ((*_45).0: std::option::Option<()>); + StorageLive(_49); -+ _49 = Option::<()>::None; -+ _43 = copy ((*_45).0: std::option::Option<()>); -+ ((*_45).0: std::option::Option<()>) = copy _49; -+ StorageDead(_49); -+ StorageDead(_44); -+ StorageLive(_50); -+ _50 = discriminant(_43); -+ switchInt(move _50) -> [0: bb11, 1: bb12, otherwise: bb5]; ++ _49 = discriminant(_43); ++ switchInt(move _49) -> [0: bb11, 1: bb12, otherwise: bb5]; + } + + bb5: { @@ -313,18 +304,20 @@ + } + + bb11: { -+ _51 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable; ++ _50 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable; + } + + bb12: { + _42 = move ((_43 as Some).0: ()); -+ StorageDead(_50); ++ StorageDead(_49); + StorageDead(_43); + _18 = Poll::<()>::Ready(move _42); + StorageDead(_42); -+ StorageDead(_51); ++ StorageDead(_50); ++ StorageDead(_47); + StorageDead(_46); + StorageDead(_45); ++ StorageDead(_44); + StorageDead(_22); + StorageDead(_19); + _25 = discriminant(_18); diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff index 94b89a310baa8..b0cdd0412a8a4 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff @@ -66,9 +66,8 @@ + let mut _47: &mut std::future::Ready<()>; + let mut _48: &mut std::pin::Pin<&mut std::future::Ready<()>>; + scope 14 (inlined > as DerefMut>::deref_mut) { -+ let mut _49: std::pin::Pin<&mut std::future::Ready<()>>; + scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) { -+ let mut _50: &mut &mut std::future::Ready<()>; ++ let mut _49: &mut &mut std::future::Ready<()>; + scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) { + } + scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) { @@ -78,15 +77,15 @@ + } + } + scope 19 (inlined Option::<()>::take) { -+ let mut _51: std::option::Option<()>; ++ let mut _50: std::option::Option<()>; + scope 20 (inlined std::mem::replace::>) { + scope 21 { + } + } + } + scope 22 (inlined #[track_caller] Option::<()>::expect) { -+ let mut _52: isize; -+ let mut _53: !; ++ let mut _51: isize; ++ let mut _52: !; + scope 23 { + } + } @@ -244,30 +243,22 @@ + _23 = move _24; + _22 = &mut (*_23); + StorageDead(_24); ++ StorageLive(_46); + StorageLive(_47); + StorageLive(_48); -+ StorageLive(_53); ++ StorageLive(_49); ++ StorageLive(_52); + StorageLive(_44); + StorageLive(_45); -+ StorageLive(_46); -+ _48 = &mut _19; -+ StorageLive(_49); -+ StorageLive(_50); -+ _50 = &mut (_19.0: &mut std::future::Ready<()>); + _47 = copy (_19.0: &mut std::future::Ready<()>); ++ StorageLive(_50); ++ _50 = Option::<()>::None; ++ _45 = copy ((*_47).0: std::option::Option<()>); ++ ((*_47).0: std::option::Option<()>) = copy _50; + StorageDead(_50); -+ _49 = Pin::<&mut std::future::Ready<()>> { pointer: copy _47 }; -+ StorageDead(_49); -+ _46 = &mut ((*_47).0: std::option::Option<()>); + StorageLive(_51); -+ _51 = Option::<()>::None; -+ _45 = copy ((*_47).0: std::option::Option<()>); -+ ((*_47).0: std::option::Option<()>) = copy _51; -+ StorageDead(_51); -+ StorageDead(_46); -+ StorageLive(_52); -+ _52 = discriminant(_45); -+ switchInt(move _52) -> [0: bb16, 1: bb17, otherwise: bb7]; ++ _51 = discriminant(_45); ++ switchInt(move _51) -> [0: bb16, 1: bb17, otherwise: bb7]; } - bb6 (cleanup): { @@ -354,18 +345,20 @@ + } + + bb16: { -+ _53 = option::expect_failed(const "`Ready` polled after completion") -> bb11; ++ _52 = option::expect_failed(const "`Ready` polled after completion") -> bb11; + } + + bb17: { + _44 = move ((_45 as Some).0: ()); -+ StorageDead(_52); ++ StorageDead(_51); + StorageDead(_45); + _18 = Poll::<()>::Ready(move _44); + StorageDead(_44); -+ StorageDead(_53); ++ StorageDead(_52); ++ StorageDead(_49); + StorageDead(_48); + StorageDead(_47); ++ StorageDead(_46); + StorageDead(_22); + StorageDead(_19); + _25 = discriminant(_18); diff --git a/tests/mir-opt/issue_101973.inner.GVN.panic-abort.diff b/tests/mir-opt/issue_101973.inner.GVN.panic-abort.diff index ac88fe67bb86f..3ea7387a48d3c 100644 --- a/tests/mir-opt/issue_101973.inner.GVN.panic-abort.diff +++ b/tests/mir-opt/issue_101973.inner.GVN.panic-abort.diff @@ -30,7 +30,6 @@ StorageLive(_4); StorageLive(_5); _5 = copy _1; - nop; - StorageLive(_14); - _14 = BitAnd(copy _5, const 255_u32); - _4 = BitOr(const 0_u32, move _14); diff --git a/tests/mir-opt/issue_101973.inner.GVN.panic-unwind.diff b/tests/mir-opt/issue_101973.inner.GVN.panic-unwind.diff index 96c3cae2d334a..832db856b2cf9 100644 --- a/tests/mir-opt/issue_101973.inner.GVN.panic-unwind.diff +++ b/tests/mir-opt/issue_101973.inner.GVN.panic-unwind.diff @@ -30,7 +30,6 @@ StorageLive(_4); StorageLive(_5); _5 = copy _1; - nop; - StorageLive(_14); - _14 = BitAnd(copy _5, const 255_u32); - _4 = BitOr(const 0_u32, move _14); diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff index c02bab3524bca..f636359aca948 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff @@ -37,15 +37,9 @@ } bb2: { - StorageLive(_7); - _7 = &(*_2)[0 of 3]; - StorageLive(_8); - _8 = &(*_2)[1 of 3]; - StorageLive(_9); - _9 = &(*_2)[2 of 3]; - StorageDead(_9); - StorageDead(_8); - StorageDead(_7); + // DBG: AssignRef(_7, (*_2)[0 of 3]) + // DBG: AssignRef(_8, (*_2)[1 of 3]) + // DBG: AssignRef(_9, (*_2)[2 of 3]) StorageDead(_4); return; } diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff index 49be042588cb3..5be5119a1f838 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff @@ -37,15 +37,9 @@ } bb2: { - StorageLive(_7); - _7 = &(*_2)[0 of 3]; - StorageLive(_8); - _8 = &(*_2)[1 of 3]; - StorageLive(_9); - _9 = &(*_2)[2 of 3]; - StorageDead(_9); - StorageDead(_8); - StorageDead(_7); + // DBG: AssignRef(_7, (*_2)[0 of 3]) + // DBG: AssignRef(_8, (*_2)[1 of 3]) + // DBG: AssignRef(_9, (*_2)[2 of 3]) StorageDead(_4); return; } diff --git a/tests/mir-opt/pre-codegen/clone_as_copy.clone_as_copy.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/clone_as_copy.clone_as_copy.PreCodegen.after.mir index 34747e5a92854..991c546c6d338 100644 --- a/tests/mir-opt/pre-codegen/clone_as_copy.clone_as_copy.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/clone_as_copy.clone_as_copy.PreCodegen.after.mir @@ -12,10 +12,8 @@ fn clone_as_copy(_1: &NestCopy) -> NestCopy { } bb0: { - StorageLive(_2); - _2 = &((*_1).1: AllCopy); + // DBG: AssignRef(_2, ((*_1).1: AllCopy)) _0 = copy (*_1); - StorageDead(_2); return; } } diff --git a/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.PreCodegen.after.mir index 9f88e1961ec88..8ad0ad95d5758 100644 --- a/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.PreCodegen.after.mir @@ -5,58 +5,28 @@ fn enum_clone_as_copy(_1: &Enum1) -> Enum1 { let mut _0: Enum1; scope 1 (inlined ::clone) { debug self => _1; - let mut _2: isize; - let mut _3: &AllCopy; - let mut _4: &NestCopy; + let mut _2: &AllCopy; + let mut _3: &NestCopy; scope 2 { - debug __self_0 => _3; + debug __self_0 => _2; scope 6 (inlined ::clone) { - debug self => _3; + debug self => _2; } } scope 3 { - debug __self_0 => _4; + debug __self_0 => _3; scope 4 (inlined ::clone) { - debug self => _4; - let _5: &AllCopy; + debug self => _3; + let _4: &AllCopy; scope 5 (inlined ::clone) { - debug self => _5; + debug self => _4; } } } } bb0: { - StorageLive(_2); - StorageLive(_3); - StorageLive(_4); - _2 = discriminant((*_1)); - switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; - } - - bb1: { - _3 = &(((*_1) as A).0: AllCopy); _0 = copy (*_1); - goto -> bb3; - } - - bb2: { - _4 = &(((*_1) as B).0: NestCopy); - StorageLive(_5); - _5 = &((((*_1) as B).0: NestCopy).1: AllCopy); - StorageDead(_5); - _0 = copy (*_1); - goto -> bb3; - } - - bb3: { - StorageDead(_4); - StorageDead(_3); - StorageDead(_2); return; } - - bb4: { - unreachable; - } } diff --git a/tests/mir-opt/pre-codegen/clone_as_copy.rs b/tests/mir-opt/pre-codegen/clone_as_copy.rs index f5ff1854d387d..50ce9a7798e48 100644 --- a/tests/mir-opt/pre-codegen/clone_as_copy.rs +++ b/tests/mir-opt/pre-codegen/clone_as_copy.rs @@ -25,19 +25,19 @@ enum Enum1 { // EMIT_MIR clone_as_copy.clone_as_copy.PreCodegen.after.mir fn clone_as_copy(v: &NestCopy) -> NestCopy { // CHECK-LABEL: fn clone_as_copy( - // CHECK-NOT: = AllCopy { {{.*}} }; - // CHECK-NOT: = NestCopy { {{.*}} }; - // CHECK: _0 = copy (*_1); - // CHECK: return; + // CHECK: let [[DEAD_VAR:_.*]]: &AllCopy; + // CHECK: bb0: { + // CHECK-NEXT: DBG: AssignRef([[DEAD_VAR]], ((*_1).1: AllCopy)) + // CHECK-NEXT: _0 = copy (*_1); + // CHECK-NEXT: return; v.clone() } -// FIXME: We can merge into exactly one assignment statement. // EMIT_MIR clone_as_copy.enum_clone_as_copy.PreCodegen.after.mir fn enum_clone_as_copy(v: &Enum1) -> Enum1 { // CHECK-LABEL: fn enum_clone_as_copy( - // CHECK-NOT: = Enum1:: - // CHECK: _0 = copy (*_1); - // CHECK: _0 = copy (*_1); + // CHECK: bb0: { + // CHECK-NEXT: _0 = copy (*_1); + // CHECK-NEXT: return; v.clone() } diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff index 027c71dfaae46..05ded743af66e 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff @@ -66,7 +66,6 @@ + _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}; StorageDead(_10); StorageDead(_2); - StorageLive(_3); StorageLive(_4); StorageLive(_5); StorageLive(_6); @@ -105,7 +104,6 @@ StorageDead(_5); _3 = move _4 as *mut u8 (PtrToPtr); StorageDead(_4); - StorageDead(_3); - StorageDead(_1); + nop; return; diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff index 88bd4628c297a..cfaecb4a69e9d 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff @@ -48,7 +48,6 @@ StorageDead(_5); _3 = move _4 as *mut u8 (PtrToPtr); StorageDead(_4); - StorageDead(_3); - StorageDead(_1); + nop; return; @@ -67,7 +66,6 @@ + _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}; StorageDead(_10); StorageDead(_2); - StorageLive(_3); StorageLive(_4); StorageLive(_5); StorageLive(_6); diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff index ebf305a6f1b12..248fc03774d1a 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff @@ -66,7 +66,6 @@ + _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}; StorageDead(_10); StorageDead(_2); - StorageLive(_3); StorageLive(_4); StorageLive(_5); StorageLive(_6); @@ -105,7 +104,6 @@ StorageDead(_5); _3 = move _4 as *mut u8 (PtrToPtr); StorageDead(_4); - StorageDead(_3); - StorageDead(_1); + nop; return; diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff index 0c52f1e058367..8b8f933164518 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff @@ -48,7 +48,6 @@ StorageDead(_5); _3 = move _4 as *mut u8 (PtrToPtr); StorageDead(_4); - StorageDead(_3); - StorageDead(_1); + nop; return; @@ -67,7 +66,6 @@ + _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}; StorageDead(_10); StorageDead(_2); - StorageLive(_3); StorageLive(_4); StorageLive(_5); StorageLive(_6); diff --git a/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir index 75e8cb1d8618c..c56f539ce1108 100644 --- a/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir @@ -6,20 +6,20 @@ fn filter_mapped(_1: impl Iterator, _2: impl Fn(T) -> Option) -> () let mut _0: (); let mut _3: std::iter::FilterMap, impl Fn(T) -> Option>; let mut _4: std::iter::FilterMap, impl Fn(T) -> Option>; - let mut _5: &mut std::iter::FilterMap, impl Fn(T) -> Option>; - let mut _8: std::option::Option; - let mut _9: isize; - let _11: (); + let mut _7: std::option::Option; + let mut _8: isize; + let _10: (); + let mut _11: &mut std::iter::FilterMap, impl Fn(T) -> Option>; scope 1 { debug iter => _4; - let _10: U; + let _9: U; scope 2 { - debug x => _10; + debug x => _9; } scope 4 (inlined , impl Fn(T) -> Option> as Iterator>::next) { - debug self => _5; - let mut _6: &mut impl Iterator; - let mut _7: &mut impl Fn(T) -> Option; + debug self => _11; + let mut _5: &mut impl Iterator; + let mut _6: &mut impl Fn(T) -> Option; } } scope 3 (inlined , impl Fn(T) -> Option> as IntoIterator>::into_iter) { @@ -37,24 +37,24 @@ fn filter_mapped(_1: impl Iterator, _2: impl Fn(T) -> Option) -> () } bb2: { - StorageLive(_8); - _5 = &mut _4; - StorageLive(_6); - _6 = &mut (_4.0: impl Iterator); StorageLive(_7); - _7 = &mut (_4.1: impl Fn(T) -> Option); - _8 = as Iterator>::find_map:: Option>(move _6, move _7) -> [return: bb3, unwind: bb9]; + // DBG: AssignRef(_11, _4) + StorageLive(_5); + _5 = &mut (_4.0: impl Iterator); + StorageLive(_6); + _6 = &mut (_4.1: impl Fn(T) -> Option); + _7 = as Iterator>::find_map:: Option>(move _5, move _6) -> [return: bb3, unwind: bb9]; } bb3: { - StorageDead(_7); StorageDead(_6); - _9 = discriminant(_8); - switchInt(move _9) -> [0: bb4, 1: bb6, otherwise: bb8]; + StorageDead(_5); + _8 = discriminant(_7); + switchInt(move _8) -> [0: bb4, 1: bb6, otherwise: bb8]; } bb4: { - StorageDead(_8); + StorageDead(_7); drop(_4) -> [return: bb5, unwind continue]; } @@ -64,12 +64,12 @@ fn filter_mapped(_1: impl Iterator, _2: impl Fn(T) -> Option) -> () } bb6: { - _10 = move ((_8 as Some).0: U); - _11 = opaque::(move _10) -> [return: bb7, unwind: bb9]; + _9 = move ((_7 as Some).0: U); + _10 = opaque::(move _9) -> [return: bb7, unwind: bb9]; } bb7: { - StorageDead(_8); + StorageDead(_7); goto -> bb2; } diff --git a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir index 154cbd3791cbd..3a3b401b0188f 100644 --- a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir @@ -4,33 +4,34 @@ fn int_range(_1: usize, _2: usize) -> () { debug start => _1; debug end => _2; let mut _0: (); - let mut _3: std::ops::Range; - let mut _4: std::ops::Range; - let mut _5: &mut std::ops::Range; - let mut _13: std::option::Option; - let _15: (); + let mut _3: usize; + let mut _8: std::option::Option; + let _10: (); + let mut _11: std::ops::Range; + let mut _12: &mut std::ops::Range; scope 1 { - debug iter => _4; - let _14: usize; + debug ((iter: std::ops::Range).0: usize) => _3; + debug ((iter: std::ops::Range).1: usize) => _2; + let _9: usize; scope 2 { - debug i => _14; + debug i => _9; } scope 4 (inlined iter::range::>::next) { - debug self => _5; + debug self => _12; scope 5 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - debug self => _5; - let mut _6: &usize; - let mut _7: &usize; - let mut _10: bool; - let _11: usize; - let mut _12: usize; + debug self => _12; + let mut _5: bool; + let _6: usize; + let mut _7: usize; + let mut _13: &usize; + let mut _14: &usize; scope 6 { - debug old => _11; + debug old => _6; scope 8 (inlined ::forward_unchecked) { - debug start => _11; + debug start => _6; debug n => const 1_usize; scope 9 (inlined #[track_caller] core::num::::unchecked_add) { - debug self => _11; + debug self => _6; debug rhs => const 1_usize; scope 10 (inlined core::ub_checks::check_language_ub) { scope 11 (inlined core::ub_checks::check_language_ub::runtime) { @@ -40,68 +41,58 @@ fn int_range(_1: usize, _2: usize) -> () { } } scope 7 (inlined std::cmp::impls::::lt) { - debug self => _6; - debug other => _7; - let mut _8: usize; - let mut _9: usize; + debug self => _13; + debug other => _14; + let mut _4: usize; } } } } scope 3 (inlined as IntoIterator>::into_iter) { - debug self => _3; + debug ((self: std::ops::Range).0: usize) => _1; + debug ((self: std::ops::Range).1: usize) => _2; } bb0: { - _3 = std::ops::Range:: { start: copy _1, end: copy _2 }; - StorageLive(_4); - _4 = copy _3; + StorageLive(_3); + _3 = copy _1; goto -> bb1; } bb1: { - StorageLive(_13); - _5 = &mut _4; - StorageLive(_10); - StorageLive(_6); - _6 = &(_4.0: usize); - StorageLive(_7); - _7 = &(_4.1: usize); StorageLive(_8); - _8 = copy (_4.0: usize); - StorageLive(_9); - _9 = copy (_4.1: usize); - _10 = Lt(move _8, move _9); - StorageDead(_9); - StorageDead(_8); - switchInt(move _10) -> [0: bb2, otherwise: bb3]; + // DBG: AssignRef(_12, _11) + StorageLive(_5); + // DBG: AssignRef(_13, (_11.0: usize)) + // DBG: AssignRef(_14, (_11.1: usize)) + StorageLive(_4); + _4 = copy _3; + _5 = Lt(move _4, copy _2); + StorageDead(_4); + switchInt(move _5) -> [0: bb2, otherwise: bb3]; } bb2: { - StorageDead(_7); - StorageDead(_6); - StorageDead(_10); - StorageDead(_13); - StorageDead(_4); + StorageDead(_5); + StorageDead(_8); + StorageDead(_3); return; } bb3: { + _6 = copy _3; + StorageLive(_7); + _7 = AddUnchecked(copy _6, const 1_usize); + _3 = move _7; StorageDead(_7); - StorageDead(_6); - _11 = copy (_4.0: usize); - StorageLive(_12); - _12 = AddUnchecked(copy _11, const 1_usize); - (_4.0: usize) = move _12; - StorageDead(_12); - _13 = Option::::Some(copy _11); - StorageDead(_10); - _14 = copy ((_13 as Some).0: usize); - _15 = opaque::(move _14) -> [return: bb4, unwind continue]; + _8 = Option::::Some(copy _6); + StorageDead(_5); + _9 = copy ((_8 as Some).0: usize); + _10 = opaque::(move _9) -> [return: bb4, unwind continue]; } bb4: { - StorageDead(_13); + StorageDead(_8); goto -> bb1; } } diff --git a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir index d22ea54004c91..1fa63c286208f 100644 --- a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir @@ -6,32 +6,32 @@ fn mapped(_1: impl Iterator, _2: impl Fn(T) -> U) -> () { let mut _0: (); let mut _3: std::iter::Map, impl Fn(T) -> U>; let mut _4: std::iter::Map, impl Fn(T) -> U>; - let mut _5: &mut std::iter::Map, impl Fn(T) -> U>; - let mut _13: std::option::Option; - let _15: (); + let mut _12: std::option::Option; + let _14: (); + let mut _15: &mut std::iter::Map, impl Fn(T) -> U>; scope 1 { debug iter => _4; - let _14: U; + let _13: U; scope 2 { - debug x => _14; + debug x => _13; } scope 4 (inlined , impl Fn(T) -> U> as Iterator>::next) { - debug self => _5; - let mut _6: &mut impl Iterator; - let mut _7: std::option::Option; - let mut _8: &mut impl Fn(T) -> U; + debug self => _15; + let mut _5: &mut impl Iterator; + let mut _6: std::option::Option; + let mut _7: &mut impl Fn(T) -> U; scope 5 (inlined Option::::map:: U>) { - debug self => _7; - debug f => _8; - let mut _9: isize; - let _10: T; - let mut _11: (T,); - let mut _12: U; + debug self => _6; + debug f => _7; + let mut _8: isize; + let _9: T; + let mut _10: (T,); + let mut _11: U; scope 6 { - debug x => _10; + debug x => _9; scope 7 (inlined ops::function::impls:: for &mut impl Fn(T) -> U>::call_once) { - debug self => _8; - debug args => _11; + debug self => _7; + debug args => _10; } } } @@ -52,30 +52,30 @@ fn mapped(_1: impl Iterator, _2: impl Fn(T) -> U) -> () { } bb2: { - StorageLive(_13); - _5 = &mut _4; - StorageLive(_8); + StorageLive(_12); + // DBG: AssignRef(_15, _4) StorageLive(_7); StorageLive(_6); - _6 = &mut (_4.0: impl Iterator); - _7 = as Iterator>::next(move _6) -> [return: bb3, unwind: bb10]; + StorageLive(_5); + _5 = &mut (_4.0: impl Iterator); + _6 = as Iterator>::next(move _5) -> [return: bb3, unwind: bb10]; } bb3: { - StorageDead(_6); - _8 = &mut (_4.1: impl Fn(T) -> U); + StorageDead(_5); + _7 = &mut (_4.1: impl Fn(T) -> U); + StorageLive(_8); StorageLive(_9); - StorageLive(_10); - _9 = discriminant(_7); - switchInt(move _9) -> [0: bb4, 1: bb6, otherwise: bb9]; + _8 = discriminant(_6); + switchInt(move _8) -> [0: bb4, 1: bb6, otherwise: bb9]; } bb4: { - StorageDead(_10); StorageDead(_9); - StorageDead(_7); StorageDead(_8); - StorageDead(_13); + StorageDead(_6); + StorageDead(_7); + StorageDead(_12); drop(_4) -> [return: bb5, unwind continue]; } @@ -85,27 +85,27 @@ fn mapped(_1: impl Iterator, _2: impl Fn(T) -> U) -> () { } bb6: { - _10 = move ((_7 as Some).0: T); - StorageLive(_12); + _9 = move ((_6 as Some).0: T); StorageLive(_11); - _11 = (copy _10,); - _12 = U as FnMut<(T,)>>::call_mut(move _8, move _11) -> [return: bb7, unwind: bb10]; + StorageLive(_10); + _10 = (copy _9,); + _11 = U as FnMut<(T,)>>::call_mut(move _7, move _10) -> [return: bb7, unwind: bb10]; } bb7: { - StorageDead(_11); - _13 = Option::::Some(move _12); - StorageDead(_12); StorageDead(_10); + _12 = Option::::Some(move _11); + StorageDead(_11); StorageDead(_9); - StorageDead(_7); StorageDead(_8); - _14 = move ((_13 as Some).0: U); - _15 = opaque::(move _14) -> [return: bb8, unwind: bb10]; + StorageDead(_6); + StorageDead(_7); + _13 = move ((_12 as Some).0: U); + _14 = opaque::(move _13) -> [return: bb8, unwind: bb10]; } bb8: { - StorageDead(_13); + StorageDead(_12); goto -> bb2; } diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir index cbdd194afd3ab..40451bd234b98 100644 --- a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir @@ -3,183 +3,142 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2: &&(usize, usize, usize, usize)) -> bool { let mut _0: bool; let mut _3: &(usize, usize, usize, usize); - let _4: &usize; - let _5: &usize; - let _6: &usize; - let _7: &usize; - let mut _8: &&usize; - let _9: &usize; - let mut _10: &&usize; - let mut _13: bool; - let mut _14: &&usize; + let mut _6: bool; + let mut _9: bool; + let mut _10: bool; + let _13: &usize; + let _14: &usize; let _15: &usize; - let mut _16: &&usize; - let mut _19: bool; + let _16: &usize; + let mut _17: &&usize; + let mut _18: &&usize; + let mut _19: &&usize; let mut _20: &&usize; - let _21: &usize; + let mut _21: &&usize; let mut _22: &&usize; - let mut _23: bool; + let mut _23: &&usize; let mut _24: &&usize; - let _25: &usize; - let mut _26: &&usize; scope 1 { - debug a => _4; - debug b => _5; - debug c => _6; - debug d => _7; + debug a => _13; + debug b => _14; + debug c => _15; + debug d => _16; scope 2 (inlined std::cmp::impls::::le) { - debug self => _8; - debug other => _10; + debug self => _17; + debug other => _18; scope 3 (inlined std::cmp::impls::::le) { - debug self => _4; - debug other => _6; - let mut _11: usize; - let mut _12: usize; + debug self => _13; + debug other => _15; + let mut _4: usize; + let mut _5: usize; } } scope 4 (inlined std::cmp::impls::::le) { - debug self => _14; - debug other => _16; + debug self => _19; + debug other => _20; scope 5 (inlined std::cmp::impls::::le) { - debug self => _7; - debug other => _5; - let mut _17: usize; - let mut _18: usize; + debug self => _16; + debug other => _14; + let mut _7: usize; + let mut _8: usize; } } scope 6 (inlined std::cmp::impls::::le) { - debug self => _20; + debug self => _21; debug other => _22; scope 7 (inlined std::cmp::impls::::le) { - debug self => _6; - debug other => _4; + debug self => _15; + debug other => _13; } } scope 8 (inlined std::cmp::impls::::le) { - debug self => _24; - debug other => _26; + debug self => _23; + debug other => _24; scope 9 (inlined std::cmp::impls::::le) { - debug self => _5; - debug other => _7; - let mut _27: usize; - let mut _28: usize; + debug self => _14; + debug other => _16; + let mut _11: usize; + let mut _12: usize; } } } bb0: { _3 = copy (*_2); - _4 = &((*_3).0: usize); - _5 = &((*_3).1: usize); - _6 = &((*_3).2: usize); - _7 = &((*_3).3: usize); - StorageLive(_13); - StorageLive(_8); - _8 = &_4; - StorageLive(_10); - StorageLive(_9); - _9 = copy _6; - _10 = &_9; - _11 = copy ((*_3).0: usize); - _12 = copy ((*_3).2: usize); - _13 = Le(copy _11, copy _12); - switchInt(move _13) -> [0: bb1, otherwise: bb2]; + // DBG: AssignRef(_13, ((*_3).0: usize)) + // DBG: AssignRef(_14, ((*_3).1: usize)) + // DBG: AssignRef(_15, ((*_3).2: usize)) + // DBG: AssignRef(_16, ((*_3).3: usize)) + StorageLive(_6); + // DBG: AssignRef(_17, _13) + // DBG: AssignRef(_18, _15) + _4 = copy ((*_3).0: usize); + _5 = copy ((*_3).2: usize); + _6 = Le(copy _4, copy _5); + switchInt(move _6) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageDead(_9); - StorageDead(_10); - StorageDead(_8); goto -> bb4; } bb2: { - StorageDead(_9); - StorageDead(_10); + StorageLive(_9); + // DBG: AssignRef(_19, _16) + // DBG: AssignRef(_20, _14) + StorageLive(_7); + _7 = copy ((*_3).3: usize); + StorageLive(_8); + _8 = copy ((*_3).1: usize); + _9 = Le(move _7, move _8); StorageDead(_8); - StorageLive(_19); - StorageLive(_14); - _14 = &_7; - StorageLive(_16); - StorageLive(_15); - _15 = copy _5; - _16 = &_15; - StorageLive(_17); - _17 = copy ((*_3).3: usize); - StorageLive(_18); - _18 = copy ((*_3).1: usize); - _19 = Le(move _17, move _18); - StorageDead(_18); - StorageDead(_17); - switchInt(move _19) -> [0: bb3, otherwise: bb8]; + StorageDead(_7); + switchInt(move _9) -> [0: bb3, otherwise: bb8]; } bb3: { - StorageDead(_15); - StorageDead(_16); - StorageDead(_14); goto -> bb4; } bb4: { - StorageLive(_23); - StorageLive(_20); - _20 = &_6; - StorageLive(_22); - StorageLive(_21); - _21 = copy _4; - _22 = &_21; - _23 = Le(copy _12, copy _11); - switchInt(move _23) -> [0: bb5, otherwise: bb6]; + StorageLive(_10); + // DBG: AssignRef(_21, _15) + // DBG: AssignRef(_22, _13) + _10 = Le(copy _5, copy _4); + switchInt(move _10) -> [0: bb5, otherwise: bb6]; } bb5: { - StorageDead(_21); - StorageDead(_22); - StorageDead(_20); _0 = const false; goto -> bb7; } bb6: { - StorageDead(_21); - StorageDead(_22); - StorageDead(_20); - StorageLive(_24); - _24 = &_5; - StorageLive(_26); - StorageLive(_25); - _25 = copy _7; - _26 = &_25; - StorageLive(_27); - _27 = copy ((*_3).1: usize); - StorageLive(_28); - _28 = copy ((*_3).3: usize); - _0 = Le(move _27, move _28); - StorageDead(_28); - StorageDead(_27); - StorageDead(_25); - StorageDead(_26); - StorageDead(_24); + // DBG: AssignRef(_23, _14) + // DBG: AssignRef(_24, _16) + StorageLive(_11); + _11 = copy ((*_3).1: usize); + StorageLive(_12); + _12 = copy ((*_3).3: usize); + _0 = Le(move _11, move _12); + StorageDead(_12); + StorageDead(_11); goto -> bb7; } bb7: { - StorageDead(_23); + StorageDead(_10); goto -> bb9; } bb8: { - StorageDead(_15); - StorageDead(_16); - StorageDead(_14); _0 = const true; goto -> bb9; } bb9: { - StorageDead(_19); - StorageDead(_13); + StorageDead(_9); + StorageDead(_6); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir index b09e36223441a..810297105b5ee 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -7,19 +7,89 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _11: std::slice::Iter<'_, T>; let mut _12: std::iter::Rev>; let mut _13: std::iter::Rev>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _36: std::option::Option<&T>; + let mut _38: &impl Fn(&T); + let mut _39: (&T,); + let _40: (); scope 1 { debug iter => _13; - let _17: &T; + let _37: &T; scope 2 { - debug x => _17; + debug x => _37; } scope 18 (inlined > as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; + scope 19 (inlined as DoubleEndedIterator>::next_back) { + let mut _14: *const T; + let mut _19: bool; + let mut _20: *const T; + let _35: &T; + scope 20 { + let _15: std::ptr::NonNull; + let _21: usize; + scope 21 { + } + scope 22 { + scope 25 (inlined as PartialEq>::eq) { + let mut _16: std::ptr::NonNull; + let mut _17: *mut T; + let mut _18: *mut T; + scope 26 (inlined NonNull::::as_ptr) { + } + scope 27 (inlined NonNull::::as_ptr) { + } + } + } + scope 23 (inlined std::ptr::const_ptr::::addr) { + scope 24 (inlined std::ptr::const_ptr::::cast::<()>) { + } + } + } + scope 28 (inlined std::slice::Iter::<'_, T>::next_back_unchecked) { + let _28: std::ptr::NonNull; + scope 29 (inlined std::slice::Iter::<'_, T>::pre_dec_end) { + let mut _22: *mut *const T; + let mut _23: *mut std::ptr::NonNull; + let mut _24: std::ptr::NonNull; + let mut _27: std::ptr::NonNull; + let mut _29: *mut *const T; + let mut _30: *mut usize; + let mut _31: usize; + let mut _32: usize; + scope 30 { + scope 31 { + } + scope 32 { + scope 35 (inlined NonNull::::sub) { + scope 36 (inlined #[track_caller] core::num::::unchecked_neg) { + scope 37 (inlined core::ub_checks::check_language_ub) { + scope 38 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 39 (inlined NonNull::::offset) { + let mut _25: *const T; + let mut _26: *const T; + scope 40 (inlined NonNull::::as_ptr) { + } + } + } + } + scope 33 (inlined std::ptr::mut_ptr::::cast::) { + } + scope 34 (inlined std::ptr::mut_ptr::::cast::>) { + } + } + } + scope 41 (inlined NonNull::::as_ref::<'_>) { + let mut _33: std::ptr::NonNull; + let _34: *const T; + scope 42 (inlined NonNull::::as_ptr) { + } + scope 43 (inlined std::ptr::mut_ptr::::cast_const) { + } + } + } + } } } scope 3 (inlined core::slice::::iter) { @@ -109,45 +179,146 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb4: { + StorageLive(_36); + StorageLive(_21); + StorageLive(_20); StorageLive(_15); - StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable]; + StorageLive(_35); + StorageLive(_19); + switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb6]; } bb5: { + StorageLive(_14); + _14 = copy ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _15 = move _14 as std::ptr::NonNull (Transmute); StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageLive(_17); + StorageLive(_16); + _16 = copy ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); + _17 = copy _16 as *mut T (Transmute); + StorageDead(_16); + StorageLive(_18); + _18 = copy _15 as *mut T (Transmute); + _19 = Eq(move _17, move _18); + StorageDead(_18); + StorageDead(_17); + goto -> bb7; } bb6: { - StorageDead(_15); - StorageDead(_13); - drop(_2) -> [return: bb7, unwind unreachable]; + _20 = copy ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _21 = copy _20 as usize (Transmute); + _19 = Eq(copy _21, const 0_usize); + goto -> bb7; } bb7: { - return; + switchInt(move _19) -> [0: bb8, otherwise: bb16]; } bb8: { - _17 = copy ((_15 as Some).0: &T); - StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (copy _17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind unreachable]; + StorageLive(_28); + StorageLive(_30); + StorageLive(_23); + switchInt(const ::IS_ZST) -> [0: bb9, otherwise: bb13]; } bb9: { + StorageLive(_22); + _22 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _23 = copy _22 as *mut std::ptr::NonNull (PtrToPtr); + StorageDead(_22); + StorageLive(_27); + StorageLive(_24); + _24 = copy (*_23); + switchInt(const ::IS_ZST) -> [0: bb10, otherwise: bb11]; + } + + bb10: { + StorageLive(_26); + StorageLive(_25); + _25 = copy _24 as *const T (Transmute); + _26 = Offset(move _25, const -1_isize); + StorageDead(_25); + _27 = NonNull:: { pointer: move _26 }; + StorageDead(_26); + goto -> bb12; + } + + bb11: { + _27 = copy _24; + goto -> bb12; + } + + bb12: { + StorageDead(_24); + (*_23) = move _27; + StorageDead(_27); + _28 = copy (*_23); + goto -> bb14; + } + + bb13: { + StorageLive(_29); + _29 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _30 = copy _29 as *mut usize (PtrToPtr); + StorageDead(_29); + StorageLive(_32); + StorageLive(_31); + _31 = copy (*_30); + _32 = SubUnchecked(move _31, const 1_usize); + StorageDead(_31); + (*_30) = move _32; + StorageDead(_32); + _28 = copy ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); + goto -> bb14; + } + + bb14: { + StorageDead(_23); + StorageDead(_30); + StorageLive(_33); + StorageLive(_34); + _33 = copy _28; + _34 = copy _33 as *const T (Transmute); + _35 = &(*_34); + StorageDead(_34); + StorageDead(_33); + StorageDead(_28); + _36 = Option::<&T>::Some(copy _35); StorageDead(_19); - StorageDead(_18); + StorageDead(_35); StorageDead(_15); + StorageDead(_20); + StorageDead(_21); + _37 = copy ((_36 as Some).0: &T); + StorageLive(_38); + _38 = &_2; + StorageLive(_39); + _39 = (copy _37,); + _40 = >::call(move _38, move _39) -> [return: bb15, unwind unreachable]; + } + + bb15: { + StorageDead(_39); + StorageDead(_38); + StorageDead(_36); goto -> bb4; } - bb10: { - unreachable; + bb16: { + StorageDead(_19); + StorageDead(_35); + StorageDead(_15); + StorageDead(_20); + StorageDead(_21); + StorageDead(_36); + StorageDead(_13); + drop(_2) -> [return: bb17, unwind unreachable]; + } + + bb17: { + return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index 12b54b57b8448..aea27f9cf867b 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -7,19 +7,89 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _11: std::slice::Iter<'_, T>; let mut _12: std::iter::Rev>; let mut _13: std::iter::Rev>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _36: std::option::Option<&T>; + let mut _38: &impl Fn(&T); + let mut _39: (&T,); + let _40: (); scope 1 { debug iter => _13; - let _17: &T; + let _37: &T; scope 2 { - debug x => _17; + debug x => _37; } scope 18 (inlined > as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; + scope 19 (inlined as DoubleEndedIterator>::next_back) { + let mut _14: *const T; + let mut _19: bool; + let mut _20: *const T; + let _35: &T; + scope 20 { + let _15: std::ptr::NonNull; + let _21: usize; + scope 21 { + } + scope 22 { + scope 25 (inlined as PartialEq>::eq) { + let mut _16: std::ptr::NonNull; + let mut _17: *mut T; + let mut _18: *mut T; + scope 26 (inlined NonNull::::as_ptr) { + } + scope 27 (inlined NonNull::::as_ptr) { + } + } + } + scope 23 (inlined std::ptr::const_ptr::::addr) { + scope 24 (inlined std::ptr::const_ptr::::cast::<()>) { + } + } + } + scope 28 (inlined std::slice::Iter::<'_, T>::next_back_unchecked) { + let _28: std::ptr::NonNull; + scope 29 (inlined std::slice::Iter::<'_, T>::pre_dec_end) { + let mut _22: *mut *const T; + let mut _23: *mut std::ptr::NonNull; + let mut _24: std::ptr::NonNull; + let mut _27: std::ptr::NonNull; + let mut _29: *mut *const T; + let mut _30: *mut usize; + let mut _31: usize; + let mut _32: usize; + scope 30 { + scope 31 { + } + scope 32 { + scope 35 (inlined NonNull::::sub) { + scope 36 (inlined #[track_caller] core::num::::unchecked_neg) { + scope 37 (inlined core::ub_checks::check_language_ub) { + scope 38 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 39 (inlined NonNull::::offset) { + let mut _25: *const T; + let mut _26: *const T; + scope 40 (inlined NonNull::::as_ptr) { + } + } + } + } + scope 33 (inlined std::ptr::mut_ptr::::cast::) { + } + scope 34 (inlined std::ptr::mut_ptr::::cast::>) { + } + } + } + scope 41 (inlined NonNull::::as_ref::<'_>) { + let mut _33: std::ptr::NonNull; + let _34: *const T; + scope 42 (inlined NonNull::::as_ptr) { + } + scope 43 (inlined std::ptr::mut_ptr::::cast_const) { + } + } + } + } } } scope 3 (inlined core::slice::::iter) { @@ -109,53 +179,154 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb4: { + StorageLive(_36); + StorageLive(_21); + StorageLive(_20); StorageLive(_15); - StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11]; + StorageLive(_35); + StorageLive(_19); + switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb6]; } bb5: { + StorageLive(_14); + _14 = copy ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _15 = move _14 as std::ptr::NonNull (Transmute); StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageLive(_17); + StorageLive(_16); + _16 = copy ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); + _17 = copy _16 as *mut T (Transmute); + StorageDead(_16); + StorageLive(_18); + _18 = copy _15 as *mut T (Transmute); + _19 = Eq(move _17, move _18); + StorageDead(_18); + StorageDead(_17); + goto -> bb7; } bb6: { - StorageDead(_15); - StorageDead(_13); - drop(_2) -> [return: bb7, unwind continue]; + _20 = copy ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _21 = copy _20 as usize (Transmute); + _19 = Eq(copy _21, const 0_usize); + goto -> bb7; } bb7: { - return; + switchInt(move _19) -> [0: bb8, otherwise: bb18]; } bb8: { - _17 = copy ((_15 as Some).0: &T); - StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (copy _17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; + StorageLive(_28); + StorageLive(_30); + StorageLive(_23); + switchInt(const ::IS_ZST) -> [0: bb9, otherwise: bb13]; } bb9: { + StorageLive(_22); + _22 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _23 = copy _22 as *mut std::ptr::NonNull (PtrToPtr); + StorageDead(_22); + StorageLive(_27); + StorageLive(_24); + _24 = copy (*_23); + switchInt(const ::IS_ZST) -> [0: bb10, otherwise: bb11]; + } + + bb10: { + StorageLive(_26); + StorageLive(_25); + _25 = copy _24 as *const T (Transmute); + _26 = Offset(move _25, const -1_isize); + StorageDead(_25); + _27 = NonNull:: { pointer: move _26 }; + StorageDead(_26); + goto -> bb12; + } + + bb11: { + _27 = copy _24; + goto -> bb12; + } + + bb12: { + StorageDead(_24); + (*_23) = move _27; + StorageDead(_27); + _28 = copy (*_23); + goto -> bb14; + } + + bb13: { + StorageLive(_29); + _29 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _30 = copy _29 as *mut usize (PtrToPtr); + StorageDead(_29); + StorageLive(_32); + StorageLive(_31); + _31 = copy (*_30); + _32 = SubUnchecked(move _31, const 1_usize); + StorageDead(_31); + (*_30) = move _32; + StorageDead(_32); + _28 = copy ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); + goto -> bb14; + } + + bb14: { + StorageDead(_23); + StorageDead(_30); + StorageLive(_33); + StorageLive(_34); + _33 = copy _28; + _34 = copy _33 as *const T (Transmute); + _35 = &(*_34); + StorageDead(_34); + StorageDead(_33); + StorageDead(_28); + _36 = Option::<&T>::Some(copy _35); StorageDead(_19); - StorageDead(_18); + StorageDead(_35); StorageDead(_15); - goto -> bb4; + StorageDead(_20); + StorageDead(_21); + _37 = copy ((_36 as Some).0: &T); + StorageLive(_38); + _38 = &_2; + StorageLive(_39); + _39 = (copy _37,); + _40 = >::call(move _38, move _39) -> [return: bb15, unwind: bb16]; } - bb10: { - unreachable; + bb15: { + StorageDead(_39); + StorageDead(_38); + StorageDead(_36); + goto -> bb4; } - bb11 (cleanup): { - drop(_2) -> [return: bb12, unwind terminate(cleanup)]; + bb16 (cleanup): { + drop(_2) -> [return: bb17, unwind terminate(cleanup)]; } - bb12 (cleanup): { + bb17 (cleanup): { resume; } + + bb18: { + StorageDead(_19); + StorageDead(_35); + StorageDead(_15); + StorageDead(_20); + StorageDead(_21); + StorageDead(_36); + StorageDead(_13); + drop(_2) -> [return: bb19, unwind continue]; + } + + bb19: { + return; + } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir index 78f96bf419559..7fb801a12227b 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir @@ -3,12 +3,199 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut T> { debug it => _1; let mut _0: std::option::Option<&mut T>; + scope 1 (inlined as DoubleEndedIterator>::next_back) { + let mut _2: *mut T; + let mut _7: bool; + let mut _8: *mut T; + let mut _23: &mut T; + scope 2 { + let _3: std::ptr::NonNull; + let _9: usize; + scope 3 { + } + scope 4 { + scope 7 (inlined as PartialEq>::eq) { + let mut _4: std::ptr::NonNull; + let mut _5: *mut T; + let mut _6: *mut T; + scope 8 (inlined NonNull::::as_ptr) { + } + scope 9 (inlined NonNull::::as_ptr) { + } + } + } + scope 5 (inlined std::ptr::mut_ptr::::addr) { + scope 6 (inlined std::ptr::mut_ptr::::cast::<()>) { + } + } + } + scope 10 (inlined std::slice::IterMut::<'_, T>::next_back_unchecked) { + let mut _16: std::ptr::NonNull; + scope 11 (inlined std::slice::IterMut::<'_, T>::pre_dec_end) { + let mut _10: *mut *mut T; + let mut _11: *mut std::ptr::NonNull; + let mut _12: std::ptr::NonNull; + let mut _15: std::ptr::NonNull; + let mut _17: *mut *mut T; + let mut _18: *mut usize; + let mut _19: usize; + let mut _20: usize; + scope 12 { + scope 13 { + } + scope 14 { + scope 17 (inlined NonNull::::sub) { + scope 18 (inlined #[track_caller] core::num::::unchecked_neg) { + scope 19 (inlined core::ub_checks::check_language_ub) { + scope 20 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 21 (inlined NonNull::::offset) { + let mut _13: *const T; + let mut _14: *const T; + scope 22 (inlined NonNull::::as_ptr) { + } + } + } + } + scope 15 (inlined std::ptr::mut_ptr::::cast::) { + } + scope 16 (inlined std::ptr::mut_ptr::::cast::>) { + } + } + } + scope 23 (inlined NonNull::::as_mut::<'_>) { + let mut _21: std::ptr::NonNull; + let mut _22: *mut T; + scope 24 (inlined NonNull::::as_ptr) { + } + } + } + } bb0: { - _0 = as DoubleEndedIterator>::next_back(move _1) -> [return: bb1, unwind unreachable]; + StorageLive(_9); + StorageLive(_8); + StorageLive(_3); + StorageLive(_2); + StorageLive(_23); + StorageLive(_7); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { + _2 = copy ((*_1).1: *mut T); + _3 = copy _2 as std::ptr::NonNull (Transmute); + StorageLive(_5); + StorageLive(_4); + _4 = copy ((*_1).0: std::ptr::NonNull); + _5 = copy _4 as *mut T (Transmute); + StorageDead(_4); + StorageLive(_6); + _6 = copy _3 as *mut T (Transmute); + _7 = Eq(move _5, move _6); + StorageDead(_6); + StorageDead(_5); + goto -> bb3; + } + + bb2: { + _8 = copy ((*_1).1: *mut T); + _9 = copy _8 as usize (Transmute); + _7 = Eq(copy _9, const 0_usize); + goto -> bb3; + } + + bb3: { + switchInt(move _7) -> [0: bb4, otherwise: bb11]; + } + + bb4: { + StorageLive(_16); + StorageLive(_18); + StorageLive(_11); + switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb9]; + } + + bb5: { + StorageLive(_10); + _10 = &raw mut ((*_1).1: *mut T); + _11 = copy _10 as *mut std::ptr::NonNull (PtrToPtr); + StorageDead(_10); + StorageLive(_15); + StorageLive(_12); + _12 = copy (*_11); + switchInt(const ::IS_ZST) -> [0: bb6, otherwise: bb7]; + } + + bb6: { + StorageLive(_14); + StorageLive(_13); + _13 = copy _12 as *const T (Transmute); + _14 = Offset(move _13, const -1_isize); + StorageDead(_13); + _15 = NonNull:: { pointer: move _14 }; + StorageDead(_14); + goto -> bb8; + } + + bb7: { + _15 = copy _12; + goto -> bb8; + } + + bb8: { + StorageDead(_12); + (*_11) = move _15; + StorageDead(_15); + _16 = copy (*_11); + goto -> bb10; + } + + bb9: { + StorageLive(_17); + _17 = &raw mut ((*_1).1: *mut T); + _18 = copy _17 as *mut usize (PtrToPtr); + StorageDead(_17); + StorageLive(_20); + StorageLive(_19); + _19 = copy (*_18); + _20 = SubUnchecked(move _19, const 1_usize); + StorageDead(_19); + (*_18) = move _20; + StorageDead(_20); + _16 = copy ((*_1).0: std::ptr::NonNull); + goto -> bb10; + } + + bb10: { + StorageDead(_11); + StorageDead(_18); + StorageLive(_22); + StorageLive(_21); + _21 = copy _16; + _22 = copy _21 as *mut T (Transmute); + StorageDead(_21); + _23 = &mut (*_22); + StorageDead(_22); + StorageDead(_16); + _0 = Option::<&mut T>::Some(copy _23); + goto -> bb12; + } + + bb11: { + _0 = const {transmute(0x0000000000000000): Option<&mut T>}; + goto -> bb12; + } + + bb12: { + StorageDead(_7); + StorageDead(_23); + StorageDead(_2); + StorageDead(_3); + StorageDead(_8); + StorageDead(_9); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir index dfe5e206fadaf..7fb801a12227b 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir @@ -3,12 +3,199 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut T> { debug it => _1; let mut _0: std::option::Option<&mut T>; + scope 1 (inlined as DoubleEndedIterator>::next_back) { + let mut _2: *mut T; + let mut _7: bool; + let mut _8: *mut T; + let mut _23: &mut T; + scope 2 { + let _3: std::ptr::NonNull; + let _9: usize; + scope 3 { + } + scope 4 { + scope 7 (inlined as PartialEq>::eq) { + let mut _4: std::ptr::NonNull; + let mut _5: *mut T; + let mut _6: *mut T; + scope 8 (inlined NonNull::::as_ptr) { + } + scope 9 (inlined NonNull::::as_ptr) { + } + } + } + scope 5 (inlined std::ptr::mut_ptr::::addr) { + scope 6 (inlined std::ptr::mut_ptr::::cast::<()>) { + } + } + } + scope 10 (inlined std::slice::IterMut::<'_, T>::next_back_unchecked) { + let mut _16: std::ptr::NonNull; + scope 11 (inlined std::slice::IterMut::<'_, T>::pre_dec_end) { + let mut _10: *mut *mut T; + let mut _11: *mut std::ptr::NonNull; + let mut _12: std::ptr::NonNull; + let mut _15: std::ptr::NonNull; + let mut _17: *mut *mut T; + let mut _18: *mut usize; + let mut _19: usize; + let mut _20: usize; + scope 12 { + scope 13 { + } + scope 14 { + scope 17 (inlined NonNull::::sub) { + scope 18 (inlined #[track_caller] core::num::::unchecked_neg) { + scope 19 (inlined core::ub_checks::check_language_ub) { + scope 20 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 21 (inlined NonNull::::offset) { + let mut _13: *const T; + let mut _14: *const T; + scope 22 (inlined NonNull::::as_ptr) { + } + } + } + } + scope 15 (inlined std::ptr::mut_ptr::::cast::) { + } + scope 16 (inlined std::ptr::mut_ptr::::cast::>) { + } + } + } + scope 23 (inlined NonNull::::as_mut::<'_>) { + let mut _21: std::ptr::NonNull; + let mut _22: *mut T; + scope 24 (inlined NonNull::::as_ptr) { + } + } + } + } bb0: { - _0 = as DoubleEndedIterator>::next_back(move _1) -> [return: bb1, unwind continue]; + StorageLive(_9); + StorageLive(_8); + StorageLive(_3); + StorageLive(_2); + StorageLive(_23); + StorageLive(_7); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { + _2 = copy ((*_1).1: *mut T); + _3 = copy _2 as std::ptr::NonNull (Transmute); + StorageLive(_5); + StorageLive(_4); + _4 = copy ((*_1).0: std::ptr::NonNull); + _5 = copy _4 as *mut T (Transmute); + StorageDead(_4); + StorageLive(_6); + _6 = copy _3 as *mut T (Transmute); + _7 = Eq(move _5, move _6); + StorageDead(_6); + StorageDead(_5); + goto -> bb3; + } + + bb2: { + _8 = copy ((*_1).1: *mut T); + _9 = copy _8 as usize (Transmute); + _7 = Eq(copy _9, const 0_usize); + goto -> bb3; + } + + bb3: { + switchInt(move _7) -> [0: bb4, otherwise: bb11]; + } + + bb4: { + StorageLive(_16); + StorageLive(_18); + StorageLive(_11); + switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb9]; + } + + bb5: { + StorageLive(_10); + _10 = &raw mut ((*_1).1: *mut T); + _11 = copy _10 as *mut std::ptr::NonNull (PtrToPtr); + StorageDead(_10); + StorageLive(_15); + StorageLive(_12); + _12 = copy (*_11); + switchInt(const ::IS_ZST) -> [0: bb6, otherwise: bb7]; + } + + bb6: { + StorageLive(_14); + StorageLive(_13); + _13 = copy _12 as *const T (Transmute); + _14 = Offset(move _13, const -1_isize); + StorageDead(_13); + _15 = NonNull:: { pointer: move _14 }; + StorageDead(_14); + goto -> bb8; + } + + bb7: { + _15 = copy _12; + goto -> bb8; + } + + bb8: { + StorageDead(_12); + (*_11) = move _15; + StorageDead(_15); + _16 = copy (*_11); + goto -> bb10; + } + + bb9: { + StorageLive(_17); + _17 = &raw mut ((*_1).1: *mut T); + _18 = copy _17 as *mut usize (PtrToPtr); + StorageDead(_17); + StorageLive(_20); + StorageLive(_19); + _19 = copy (*_18); + _20 = SubUnchecked(move _19, const 1_usize); + StorageDead(_19); + (*_18) = move _20; + StorageDead(_20); + _16 = copy ((*_1).0: std::ptr::NonNull); + goto -> bb10; + } + + bb10: { + StorageDead(_11); + StorageDead(_18); + StorageLive(_22); + StorageLive(_21); + _21 = copy _16; + _22 = copy _21 as *mut T (Transmute); + StorageDead(_21); + _23 = &mut (*_22); + StorageDead(_22); + StorageDead(_16); + _0 = Option::<&mut T>::Some(copy _23); + goto -> bb12; + } + + bb11: { + _0 = const {transmute(0x0000000000000000): Option<&mut T>}; + goto -> bb12; + } + + bb12: { + StorageDead(_7); + StorageDead(_23); + StorageDead(_2); + StorageDead(_3); + StorageDead(_8); + StorageDead(_9); return; } } diff --git a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir index fe4e2deab8706..53effd7429256 100644 --- a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir @@ -9,7 +9,7 @@ fn outer(_1: u8) -> u8 { } bb0: { - _2 = &_1; // scope 0 at $DIR/spans.rs:11:11: 11:13 + // DBG: AssignRef(_2, _1) _0 = copy _1; // scope 1 at $DIR/spans.rs:15:5: 15:7 return; // scope 0 at $DIR/spans.rs:12:2: 12:2 } diff --git a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir index fe4e2deab8706..53effd7429256 100644 --- a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir @@ -9,7 +9,7 @@ fn outer(_1: u8) -> u8 { } bb0: { - _2 = &_1; // scope 0 at $DIR/spans.rs:11:11: 11:13 + // DBG: AssignRef(_2, _1) _0 = copy _1; // scope 1 at $DIR/spans.rs:15:5: 15:7 return; // scope 0 at $DIR/spans.rs:12:2: 12:2 } diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir index 2eee8a97db0d4..e1cde9d6b8fa1 100644 --- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir @@ -11,7 +11,9 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { let mut _4: usize; scope 3 (inlined Vec::::as_ptr) { debug self => _1; + let mut _6: &alloc::raw_vec::RawVec; scope 4 (inlined alloc::raw_vec::RawVec::::ptr) { + let mut _7: &alloc::raw_vec::RawVecInner; scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::) { scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::) { let mut _2: std::ptr::NonNull; @@ -55,6 +57,8 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { bb0: { StorageLive(_2); StorageLive(_3); + // DBG: AssignRef(_6, ((*_1).0: alloc::raw_vec::RawVec)) + // DBG: AssignRef(_7, (((*_1).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner)) _2 = copy (((((*_1).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); _3 = copy _2 as *const u8 (Transmute); StorageLive(_4); diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir index 2eee8a97db0d4..e1cde9d6b8fa1 100644 --- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir @@ -11,7 +11,9 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { let mut _4: usize; scope 3 (inlined Vec::::as_ptr) { debug self => _1; + let mut _6: &alloc::raw_vec::RawVec; scope 4 (inlined alloc::raw_vec::RawVec::::ptr) { + let mut _7: &alloc::raw_vec::RawVecInner; scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::) { scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::) { let mut _2: std::ptr::NonNull; @@ -55,6 +57,8 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { bb0: { StorageLive(_2); StorageLive(_3); + // DBG: AssignRef(_6, ((*_1).0: alloc::raw_vec::RawVec)) + // DBG: AssignRef(_7, (((*_1).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner)) _2 = copy (((((*_1).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); _3 = copy _2 as *const u8 (Transmute); StorageLive(_4); diff --git a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff index 05ad9dbf3cccf..e53c5d323d691 100644 --- a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff @@ -54,16 +54,18 @@ } bb0: { - StorageLive(_1); - StorageLive(_2); +- StorageLive(_1); +- StorageLive(_2); _2 = const 5_u8; - _1 = &mut _2; - StorageLive(_3); +- _1 = &mut _2; +- StorageLive(_3); ++ // DBG: AssignRef(_1, _2) _28 = const debuginfo::promoted[2]; - _3 = &((*_28).0: u8); +- _3 = &((*_28).0: u8); - StorageLive(_5); - _5 = &(*_1); - StorageLive(_6); ++ // DBG: AssignRef(_3, ((*_28).0: u8)) StorageLive(_7); _7 = Option::::Some(const 0_i32); _8 = discriminant(_7); @@ -75,11 +77,12 @@ } bb2: { - StorageLive(_9); +- StorageLive(_9); _27 = const debuginfo::promoted[1]; - _9 = &(((*_27) as Some).0: i32); +- _9 = &(((*_27) as Some).0: i32); - _6 = const (); - StorageDead(_9); +- StorageDead(_9); ++ // DBG: AssignRef(_9, (((*_27) as Some).0: i32)) goto -> bb4; } @@ -114,19 +117,19 @@ } bb6: { - StorageLive(_19); +- StorageLive(_19); - _19 = &(*_11)[1 of 3]; -+ _19 = &(*_12)[1 of 3]; - StorageLive(_20); +- StorageLive(_20); - _20 = &(*_11)[2:-1]; -+ _20 = &(*_12)[2:-1]; - StorageLive(_21); +- StorageLive(_21); - _21 = &(*_11)[-1 of 3]; - _10 = const (); -+ _21 = &(*_12)[-1 of 3]; - StorageDead(_21); - StorageDead(_20); - StorageDead(_19); +- StorageDead(_21); +- StorageDead(_20); +- StorageDead(_19); ++ // DBG: AssignRef(_19, (*_12)[1 of 3]) ++ // DBG: AssignRef(_20, (*_12)[2:-1]) ++ // DBG: AssignRef(_21, (*_12)[-1 of 3]) goto -> bb8; } @@ -139,23 +142,26 @@ - StorageDead(_12); - StorageDead(_11); - StorageDead(_10); - StorageLive(_22); - StorageLive(_23); - StorageLive(_24); - StorageLive(_25); +- StorageLive(_22); +- StorageLive(_23); +- StorageLive(_24); +- StorageLive(_25); _25 = T(const 6_u8); - _24 = &mut (_25.0: u8); - _23 = &_24; - _22 = &_23; +- _24 = &mut (_25.0: u8); +- _23 = &_24; +- _22 = &_23; ++ // DBG: AssignRef(_24, (_25.0: u8)) ++ // DBG: AssignRef(_23, _24) ++ // DBG: AssignRef(_22, _23) _0 = const (); - StorageDead(_25); - StorageDead(_24); - StorageDead(_23); - StorageDead(_22); +- StorageDead(_25); +- StorageDead(_24); +- StorageDead(_23); +- StorageDead(_22); - StorageDead(_5); - StorageDead(_3); - StorageDead(_2); - StorageDead(_1); +- StorageDead(_3); +- StorageDead(_2); +- StorageDead(_1); return; } } diff --git a/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff index 90fd91764cb94..b77c16d6ff7b0 100644 --- a/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff @@ -35,7 +35,7 @@ StorageLive(_1); _1 = const 2_i32; - StorageLive(_2); - _2 = &mut _1; +- _2 = &mut _1; - StorageLive(_3); - StorageLive(_4); - StorageLive(_5); @@ -46,6 +46,7 @@ - StorageDead(_4); - StorageLive(_6); - _6 = &(*_2); ++ // DBG: AssignRef(_2, _1) StorageLive(_7); - _7 = copy (*_6); - StorageLive(_8); diff --git a/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff index 3c6a9a9614c32..90d515369507c 100644 --- a/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff @@ -188,10 +188,11 @@ - StorageLive(_3); StorageLive(_4); _4 = const 5_usize; - StorageLive(_5); - _5 = &_4; - StorageLive(_6); +- StorageLive(_5); +- _5 = &_4; +- StorageLive(_6); - _6 = copy (*_5); ++ // DBG: AssignRef(_5, _4) + _6 = copy _4; StorageLive(_7); StorageLive(_8); @@ -203,8 +204,8 @@ StorageDead(_8); StorageDead(_7); - _3 = const (); - StorageDead(_6); - StorageDead(_5); +- StorageDead(_6); +- StorageDead(_5); StorageDead(_4); - StorageDead(_3); - StorageLive(_9); @@ -222,7 +223,7 @@ _12 = move _13; StorageDead(_13); - StorageDead(_14); - StorageLive(_15); +- StorageLive(_15); _15 = copy (*_12); StorageLive(_16); StorageLive(_17); @@ -234,7 +235,7 @@ StorageDead(_17); StorageDead(_16); - _9 = const (); - StorageDead(_15); +- StorageDead(_15); StorageDead(_12); StorageDead(_11); StorageDead(_10); @@ -246,7 +247,7 @@ _20 = &_19; StorageLive(_21); _21 = &_20; - StorageLive(_22); +- StorageLive(_22); - _22 = copy (*_20); + _22 = copy _19; StorageLive(_23); @@ -259,7 +260,7 @@ StorageDead(_24); StorageDead(_23); - _18 = const (); - StorageDead(_22); +- StorageDead(_22); StorageDead(_21); StorageDead(_20); StorageDead(_19); @@ -271,7 +272,7 @@ _27 = &_26; StorageLive(_28); _28 = &raw mut _27; - StorageLive(_29); +- StorageLive(_29); _29 = copy (*_27); StorageLive(_30); StorageLive(_31); @@ -283,7 +284,7 @@ StorageDead(_31); StorageDead(_30); - _25 = const (); - StorageDead(_29); +- StorageDead(_29); StorageDead(_28); StorageDead(_27); StorageDead(_26); @@ -293,7 +294,7 @@ _33 = const 7_usize; StorageLive(_34); _34 = &_33; - StorageLive(_35); +- StorageLive(_35); - _35 = copy (*_34); + _35 = copy _33; StorageLive(_36); @@ -306,7 +307,7 @@ StorageDead(_37); StorageDead(_36); - _32 = const (); - StorageDead(_35); +- StorageDead(_35); StorageDead(_34); StorageDead(_33); - StorageDead(_32); @@ -315,12 +316,12 @@ _39 = const 7_usize; StorageLive(_40); _40 = &_39; - StorageLive(_41); +- StorageLive(_41); - _41 = copy (*_40); + _41 = copy _39; StorageLive(_42); _42 = copy _40; - StorageLive(_43); +- StorageLive(_43); - _43 = copy (*_42); + _43 = copy _39; StorageLive(_44); @@ -336,16 +337,16 @@ StorageDead(_45); - _38 = const (); StorageDead(_44); - StorageDead(_43); +- StorageDead(_43); StorageDead(_42); - StorageDead(_41); +- StorageDead(_41); StorageDead(_40); StorageDead(_39); - StorageDead(_38); - StorageLive(_47); - StorageLive(_48); - _48 = &(*_1); - StorageLive(_49); +- StorageLive(_49); - _49 = copy (*_48); + _49 = copy (*_1); StorageLive(_50); @@ -358,7 +359,7 @@ StorageDead(_51); StorageDead(_50); - _47 = const (); - StorageDead(_49); +- StorageDead(_49); - StorageDead(_48); - StorageDead(_47); - StorageLive(_52); @@ -372,7 +373,7 @@ _2 = move _54; StorageDead(_54); - StorageDead(_55); - StorageLive(_56); +- StorageLive(_56); _56 = copy (*_53); StorageLive(_57); StorageLive(_58); @@ -384,18 +385,20 @@ StorageDead(_58); StorageDead(_57); - _52 = const (); - StorageDead(_56); +- StorageDead(_56); StorageDead(_53); - StorageDead(_52); - StorageLive(_59); StorageLive(_60); _60 = const 5_usize; - StorageLive(_61); - _61 = &_60; - StorageLive(_62); - _62 = &_61; - StorageLive(_63); +- StorageLive(_61); +- _61 = &_60; +- StorageLive(_62); +- _62 = &_61; +- StorageLive(_63); - _63 = copy (*_61); ++ // DBG: AssignRef(_61, _60) ++ // DBG: AssignRef(_62, _61) + _63 = copy _60; StorageLive(_64); StorageLive(_65); @@ -407,19 +410,22 @@ StorageDead(_65); StorageDead(_64); - _59 = const (); - StorageDead(_63); - StorageDead(_62); - StorageDead(_61); +- StorageDead(_63); +- StorageDead(_62); +- StorageDead(_61); StorageDead(_60); - StorageDead(_59); StorageLive(_66); _66 = const 5_usize; - StorageLive(_67); - _67 = &_66; - StorageLive(_68); - _68 = &mut _67; - StorageLive(_69); - _69 = copy (*_67); +- StorageLive(_67); +- _67 = &_66; +- StorageLive(_68); +- _68 = &mut _67; +- StorageLive(_69); +- _69 = copy (*_67); ++ // DBG: AssignRef(_67, _66) ++ // DBG: AssignRef(_68, _67) ++ _69 = copy _66; StorageLive(_70); StorageLive(_71); _71 = (); @@ -430,9 +436,9 @@ StorageDead(_71); StorageDead(_70); _0 = const (); - StorageDead(_69); - StorageDead(_68); - StorageDead(_67); +- StorageDead(_69); +- StorageDead(_68); +- StorageDead(_67); StorageDead(_66); return; } diff --git a/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff index 75fe99de93810..0aa43317c4fe7 100644 --- a/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff @@ -205,9 +205,9 @@ - StorageLive(_3); StorageLive(_4); _4 = const 5_usize; - StorageLive(_5); +- StorageLive(_5); _5 = &raw const _4; - StorageLive(_6); +- StorageLive(_6); - _6 = copy (*_5); + _6 = copy _4; StorageLive(_7); @@ -220,8 +220,8 @@ StorageDead(_8); StorageDead(_7); - _3 = const (); - StorageDead(_6); - StorageDead(_5); +- StorageDead(_6); +- StorageDead(_5); StorageDead(_4); - StorageDead(_3); - StorageLive(_9); @@ -235,7 +235,7 @@ _13 = &raw const _11; _12 = move _13; StorageDead(_13); - StorageLive(_14); +- StorageLive(_14); _14 = copy (*_12); StorageLive(_15); StorageLive(_16); @@ -247,7 +247,7 @@ StorageDead(_16); StorageDead(_15); - _9 = const (); - StorageDead(_14); +- StorageDead(_14); StorageDead(_12); StorageDead(_11); StorageDead(_10); @@ -259,7 +259,7 @@ _19 = &raw const _18; StorageLive(_20); _20 = &_19; - StorageLive(_21); +- StorageLive(_21); - _21 = copy (*_19); + _21 = copy _18; StorageLive(_22); @@ -272,7 +272,7 @@ StorageDead(_23); StorageDead(_22); - _17 = const (); - StorageDead(_21); +- StorageDead(_21); StorageDead(_20); StorageDead(_19); StorageDead(_18); @@ -284,7 +284,7 @@ _26 = &raw const _25; StorageLive(_27); _27 = &raw mut _26; - StorageLive(_28); +- StorageLive(_28); _28 = copy (*_26); StorageLive(_29); StorageLive(_30); @@ -296,7 +296,7 @@ StorageDead(_30); StorageDead(_29); - _24 = const (); - StorageDead(_28); +- StorageDead(_28); StorageDead(_27); StorageDead(_26); StorageDead(_25); @@ -306,7 +306,7 @@ _32 = const 7_usize; StorageLive(_33); _33 = &raw const _32; - StorageLive(_34); +- StorageLive(_34); - _34 = copy (*_33); + _34 = copy _32; StorageLive(_35); @@ -319,7 +319,7 @@ StorageDead(_36); StorageDead(_35); - _31 = const (); - StorageDead(_34); +- StorageDead(_34); StorageDead(_33); StorageDead(_32); - StorageDead(_31); @@ -328,12 +328,12 @@ _38 = const 7_usize; StorageLive(_39); _39 = &raw const _38; - StorageLive(_40); +- StorageLive(_40); - _40 = copy (*_39); + _40 = copy _38; StorageLive(_41); _41 = copy _39; - StorageLive(_42); +- StorageLive(_42); - _42 = copy (*_41); + _42 = copy _38; StorageLive(_43); @@ -349,16 +349,16 @@ StorageDead(_44); - _37 = const (); StorageDead(_43); - StorageDead(_42); +- StorageDead(_42); StorageDead(_41); - StorageDead(_40); +- StorageDead(_40); StorageDead(_39); StorageDead(_38); - StorageDead(_37); - StorageLive(_46); - StorageLive(_47); - _47 = &raw const (*_1); - StorageLive(_48); +- StorageLive(_48); - _48 = copy (*_47); + _48 = copy (*_1); StorageLive(_49); @@ -371,7 +371,7 @@ StorageDead(_50); StorageDead(_49); - _46 = const (); - StorageDead(_48); +- StorageDead(_48); - StorageDead(_47); - StorageDead(_46); - StorageLive(_51); @@ -381,7 +381,7 @@ _53 = &raw const (*_1); _2 = move _53; StorageDead(_53); - StorageLive(_54); +- StorageLive(_54); _54 = copy (*_52); StorageLive(_55); StorageLive(_56); @@ -393,19 +393,19 @@ StorageDead(_56); StorageDead(_55); - _51 = const (); - StorageDead(_54); +- StorageDead(_54); StorageDead(_52); - StorageDead(_51); - StorageLive(_57); StorageLive(_58); _58 = const 13_usize; - StorageLive(_59); +- StorageLive(_59); _59 = &raw const _58; - StorageLive(_60); +- StorageLive(_60); - _60 = &raw const (*_59); -+ _60 = &raw const _58; - StorageLive(_61); +- StorageLive(_61); - _61 = copy (*_60); ++ _60 = &raw const _58; + _61 = copy _58; StorageLive(_62); StorageLive(_63); @@ -417,20 +417,21 @@ StorageDead(_63); StorageDead(_62); - _57 = const (); - StorageDead(_61); - StorageDead(_60); - StorageDead(_59); +- StorageDead(_61); +- StorageDead(_60); +- StorageDead(_59); StorageDead(_58); - StorageDead(_57); - StorageLive(_64); StorageLive(_65); _65 = const 5_usize; - StorageLive(_66); +- StorageLive(_66); _66 = &raw const _65; - StorageLive(_67); - _67 = &_66; - StorageLive(_68); +- StorageLive(_67); +- _67 = &_66; +- StorageLive(_68); - _68 = copy (*_66); ++ // DBG: AssignRef(_67, _66) + _68 = copy _65; StorageLive(_69); StorageLive(_70); @@ -442,19 +443,21 @@ StorageDead(_70); StorageDead(_69); - _64 = const (); - StorageDead(_68); - StorageDead(_67); - StorageDead(_66); +- StorageDead(_68); +- StorageDead(_67); +- StorageDead(_66); StorageDead(_65); - StorageDead(_64); StorageLive(_71); _71 = const 5_usize; - StorageLive(_72); +- StorageLive(_72); _72 = &raw const _71; - StorageLive(_73); - _73 = &mut _72; - StorageLive(_74); - _74 = copy (*_72); +- StorageLive(_73); +- _73 = &mut _72; +- StorageLive(_74); +- _74 = copy (*_72); ++ // DBG: AssignRef(_73, _72) ++ _74 = copy _71; StorageLive(_75); StorageLive(_76); _76 = (); @@ -465,9 +468,9 @@ StorageDead(_76); StorageDead(_75); _0 = const (); - StorageDead(_74); - StorageDead(_73); - StorageDead(_72); +- StorageDead(_74); +- StorageDead(_73); +- StorageDead(_72); StorageDead(_71); return; } diff --git a/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff index f35b4974d6eba..b8b0791187b68 100644 --- a/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff @@ -188,10 +188,11 @@ - StorageLive(_3); StorageLive(_4); _4 = const 5_usize; - StorageLive(_5); - _5 = &mut _4; - StorageLive(_6); +- StorageLive(_5); +- _5 = &mut _4; +- StorageLive(_6); - _6 = copy (*_5); ++ // DBG: AssignRef(_5, _4) + _6 = copy _4; StorageLive(_7); StorageLive(_8); @@ -203,8 +204,8 @@ StorageDead(_8); StorageDead(_7); - _3 = const (); - StorageDead(_6); - StorageDead(_5); +- StorageDead(_6); +- StorageDead(_5); StorageDead(_4); - StorageDead(_3); - StorageLive(_9); @@ -222,7 +223,7 @@ _12 = move _13; StorageDead(_13); - StorageDead(_14); - StorageLive(_15); +- StorageLive(_15); _15 = copy (*_12); StorageLive(_16); StorageLive(_17); @@ -234,7 +235,7 @@ StorageDead(_17); StorageDead(_16); - _9 = const (); - StorageDead(_15); +- StorageDead(_15); StorageDead(_12); StorageDead(_11); StorageDead(_10); @@ -246,7 +247,7 @@ _20 = &mut _19; StorageLive(_21); _21 = &_20; - StorageLive(_22); +- StorageLive(_22); _22 = copy (*_20); StorageLive(_23); StorageLive(_24); @@ -258,7 +259,7 @@ StorageDead(_24); StorageDead(_23); - _18 = const (); - StorageDead(_22); +- StorageDead(_22); StorageDead(_21); StorageDead(_20); StorageDead(_19); @@ -270,7 +271,7 @@ _27 = &mut _26; StorageLive(_28); _28 = &raw mut _27; - StorageLive(_29); +- StorageLive(_29); _29 = copy (*_27); StorageLive(_30); StorageLive(_31); @@ -282,7 +283,7 @@ StorageDead(_31); StorageDead(_30); - _25 = const (); - StorageDead(_29); +- StorageDead(_29); StorageDead(_28); StorageDead(_27); StorageDead(_26); @@ -292,7 +293,7 @@ _33 = const 7_usize; StorageLive(_34); _34 = &mut _33; - StorageLive(_35); +- StorageLive(_35); _35 = copy (*_34); StorageLive(_36); StorageLive(_37); @@ -304,7 +305,7 @@ StorageDead(_37); StorageDead(_36); - _32 = const (); - StorageDead(_35); +- StorageDead(_35); StorageDead(_34); StorageDead(_33); - StorageDead(_32); @@ -313,11 +314,11 @@ _39 = const 7_usize; StorageLive(_40); _40 = &mut _39; - StorageLive(_41); +- StorageLive(_41); _41 = copy (*_40); StorageLive(_42); _42 = move _40; - StorageLive(_43); +- StorageLive(_43); _43 = copy (*_42); StorageLive(_44); _44 = move _42; @@ -332,16 +333,16 @@ StorageDead(_45); - _38 = const (); StorageDead(_44); - StorageDead(_43); +- StorageDead(_43); StorageDead(_42); - StorageDead(_41); +- StorageDead(_41); StorageDead(_40); StorageDead(_39); - StorageDead(_38); - StorageLive(_47); - StorageLive(_48); - _48 = &mut (*_1); - StorageLive(_49); +- StorageLive(_49); - _49 = copy (*_48); + _49 = copy (*_1); StorageLive(_50); @@ -354,7 +355,7 @@ StorageDead(_51); StorageDead(_50); - _47 = const (); - StorageDead(_49); +- StorageDead(_49); - StorageDead(_48); - StorageDead(_47); - StorageLive(_52); @@ -368,7 +369,7 @@ _2 = move _54; StorageDead(_54); - StorageDead(_55); - StorageLive(_56); +- StorageLive(_56); _56 = copy (*_53); StorageLive(_57); StorageLive(_58); @@ -380,18 +381,21 @@ StorageDead(_58); StorageDead(_57); - _52 = const (); - StorageDead(_56); +- StorageDead(_56); StorageDead(_53); - StorageDead(_52); - StorageLive(_59); StorageLive(_60); _60 = const 5_usize; - StorageLive(_61); - _61 = &mut _60; - StorageLive(_62); - _62 = &_61; - StorageLive(_63); - _63 = copy (*_61); +- StorageLive(_61); +- _61 = &mut _60; +- StorageLive(_62); +- _62 = &_61; +- StorageLive(_63); +- _63 = copy (*_61); ++ // DBG: AssignRef(_61, _60) ++ // DBG: AssignRef(_62, _61) ++ _63 = copy _60; StorageLive(_64); StorageLive(_65); _65 = (); @@ -402,19 +406,22 @@ StorageDead(_65); StorageDead(_64); - _59 = const (); - StorageDead(_63); - StorageDead(_62); - StorageDead(_61); +- StorageDead(_63); +- StorageDead(_62); +- StorageDead(_61); StorageDead(_60); - StorageDead(_59); StorageLive(_66); _66 = const 5_usize; - StorageLive(_67); - _67 = &mut _66; - StorageLive(_68); - _68 = &mut _67; - StorageLive(_69); - _69 = copy (*_67); +- StorageLive(_67); +- _67 = &mut _66; +- StorageLive(_68); +- _68 = &mut _67; +- StorageLive(_69); +- _69 = copy (*_67); ++ // DBG: AssignRef(_67, _66) ++ // DBG: AssignRef(_68, _67) ++ _69 = copy _66; StorageLive(_70); StorageLive(_71); _71 = (); @@ -425,9 +432,9 @@ StorageDead(_71); StorageDead(_70); _0 = const (); - StorageDead(_69); - StorageDead(_68); - StorageDead(_67); +- StorageDead(_69); +- StorageDead(_68); +- StorageDead(_67); StorageDead(_66); return; } diff --git a/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff index 21b322b721876..d16ba5a2e7e8e 100644 --- a/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff @@ -186,9 +186,9 @@ - StorageLive(_3); StorageLive(_4); _4 = const 5_usize; - StorageLive(_5); +- StorageLive(_5); _5 = &raw mut _4; - StorageLive(_6); +- StorageLive(_6); - _6 = copy (*_5); + _6 = copy _4; StorageLive(_7); @@ -201,8 +201,8 @@ StorageDead(_8); StorageDead(_7); - _3 = const (); - StorageDead(_6); - StorageDead(_5); +- StorageDead(_6); +- StorageDead(_5); StorageDead(_4); - StorageDead(_3); - StorageLive(_9); @@ -216,7 +216,7 @@ _13 = &raw mut _11; _12 = move _13; StorageDead(_13); - StorageLive(_14); +- StorageLive(_14); _14 = copy (*_12); StorageLive(_15); StorageLive(_16); @@ -228,7 +228,7 @@ StorageDead(_16); StorageDead(_15); - _9 = const (); - StorageDead(_14); +- StorageDead(_14); StorageDead(_12); StorageDead(_11); StorageDead(_10); @@ -240,7 +240,7 @@ _19 = &raw mut _18; StorageLive(_20); _20 = &_19; - StorageLive(_21); +- StorageLive(_21); _21 = copy (*_19); StorageLive(_22); StorageLive(_23); @@ -252,7 +252,7 @@ StorageDead(_23); StorageDead(_22); - _17 = const (); - StorageDead(_21); +- StorageDead(_21); StorageDead(_20); StorageDead(_19); StorageDead(_18); @@ -264,7 +264,7 @@ _26 = &raw mut _25; StorageLive(_27); _27 = &raw mut _26; - StorageLive(_28); +- StorageLive(_28); _28 = copy (*_26); StorageLive(_29); StorageLive(_30); @@ -276,7 +276,7 @@ StorageDead(_30); StorageDead(_29); - _24 = const (); - StorageDead(_28); +- StorageDead(_28); StorageDead(_27); StorageDead(_26); StorageDead(_25); @@ -286,7 +286,7 @@ _32 = const 7_usize; StorageLive(_33); _33 = &raw mut _32; - StorageLive(_34); +- StorageLive(_34); _34 = copy (*_33); StorageLive(_35); StorageLive(_36); @@ -298,7 +298,7 @@ StorageDead(_36); StorageDead(_35); - _31 = const (); - StorageDead(_34); +- StorageDead(_34); StorageDead(_33); StorageDead(_32); - StorageDead(_31); @@ -307,11 +307,11 @@ _38 = const 7_usize; StorageLive(_39); _39 = &raw mut _38; - StorageLive(_40); +- StorageLive(_40); _40 = copy (*_39); StorageLive(_41); _41 = copy _39; - StorageLive(_42); +- StorageLive(_42); _42 = copy (*_41); StorageLive(_43); _43 = copy _41; @@ -326,16 +326,16 @@ StorageDead(_44); - _37 = const (); StorageDead(_43); - StorageDead(_42); +- StorageDead(_42); StorageDead(_41); - StorageDead(_40); +- StorageDead(_40); StorageDead(_39); StorageDead(_38); - StorageDead(_37); - StorageLive(_46); - StorageLive(_47); - _47 = &raw mut (*_1); - StorageLive(_48); +- StorageLive(_48); - _48 = copy (*_47); + _48 = copy (*_1); StorageLive(_49); @@ -348,7 +348,7 @@ StorageDead(_50); StorageDead(_49); - _46 = const (); - StorageDead(_48); +- StorageDead(_48); - StorageDead(_47); - StorageDead(_46); - StorageLive(_51); @@ -358,7 +358,7 @@ _53 = &raw mut (*_1); _2 = move _53; StorageDead(_53); - StorageLive(_54); +- StorageLive(_54); _54 = copy (*_52); StorageLive(_55); StorageLive(_56); @@ -370,18 +370,20 @@ StorageDead(_56); StorageDead(_55); - _51 = const (); - StorageDead(_54); +- StorageDead(_54); StorageDead(_52); - StorageDead(_51); - StorageLive(_57); StorageLive(_58); _58 = const 5_usize; - StorageLive(_59); +- StorageLive(_59); _59 = &raw mut _58; - StorageLive(_60); - _60 = &_59; - StorageLive(_61); - _61 = copy (*_59); +- StorageLive(_60); +- _60 = &_59; +- StorageLive(_61); +- _61 = copy (*_59); ++ // DBG: AssignRef(_60, _59) ++ _61 = copy _58; StorageLive(_62); StorageLive(_63); _63 = (); @@ -392,19 +394,21 @@ StorageDead(_63); StorageDead(_62); - _57 = const (); - StorageDead(_61); - StorageDead(_60); - StorageDead(_59); +- StorageDead(_61); +- StorageDead(_60); +- StorageDead(_59); StorageDead(_58); - StorageDead(_57); StorageLive(_64); _64 = const 5_usize; - StorageLive(_65); +- StorageLive(_65); _65 = &raw mut _64; - StorageLive(_66); - _66 = &mut _65; - StorageLive(_67); - _67 = copy (*_65); +- StorageLive(_66); +- _66 = &mut _65; +- StorageLive(_67); +- _67 = copy (*_65); ++ // DBG: AssignRef(_66, _65) ++ _67 = copy _64; StorageLive(_68); StorageLive(_69); _69 = (); @@ -415,9 +419,9 @@ StorageDead(_69); StorageDead(_68); _0 = const (); - StorageDead(_67); - StorageDead(_66); - StorageDead(_65); +- StorageDead(_67); +- StorageDead(_66); +- StorageDead(_65); StorageDead(_64); return; } diff --git a/tests/mir-opt/reference_prop.rs b/tests/mir-opt/reference_prop.rs index 00d4893807163..ba3ccbcf73801 100644 --- a/tests/mir-opt/reference_prop.rs +++ b/tests/mir-opt/reference_prop.rs @@ -14,8 +14,8 @@ fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) { { // CHECK: bb0: { // CHECK: [[a:_.*]] = const 5_usize; - // CHECK: [[b:_.*]] = &[[a]]; - // CHECK: [[c:_.*]] = copy [[a]]; + // CHECK-NEXT: DBG: AssignRef([[b:_.*]], [[a]]) + // CHECK-NEXT: [[c:_.*]] = copy [[a]]; let a = 5_usize; let b = &a; // This borrow is only used once. @@ -135,9 +135,9 @@ fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) { { // CHECK: bb8: { // CHECK: [[a:_.*]] = const 5_usize; - // CHECK: [[b:_.*]] = &[[a]]; - // CHECK: [[d:_.*]] = &[[b]]; - // CHECK: [[c:_.*]] = copy [[a]]; + // CHECK-NEXT: DBG: AssignRef([[b:_.*]], [[a]]) + // CHECK-NEXT: DBG: AssignRef([[d:_.*]], [[b]]) + // CHECK-NEXT: [[c:_.*]] = copy [[a]]; let a = 5_usize; let b = &a; @@ -150,10 +150,9 @@ fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) { { // CHECK: bb9: { // CHECK: [[a:_.*]] = const 5_usize; - // CHECK: [[b:_.*]] = &[[a]]; - // CHECK: [[d:_.*]] = &mut [[b]]; - // FIXME this could be [[a]] - // CHECK: [[c:_.*]] = copy (*[[b]]); + // CHECK-NEXT: DBG: AssignRef([[b:_.*]], [[a]]) + // CHECK-NEXT: DBG: AssignRef([[d:_.*]], [[b]]) + // CHECK: [[c:_.*]] = copy [[a]]; let a = 5_usize; let mut b = &a; @@ -170,8 +169,8 @@ fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a m { // CHECK: bb0: { // CHECK: [[a:_.*]] = const 5_usize; - // CHECK: [[b:_.*]] = &mut [[a]]; - // CHECK: [[c:_.*]] = copy [[a]]; + // CHECK-NEXT: DBG: AssignRef([[b:_.*]], [[a]]) + // CHECK-NEXT: [[c:_.*]] = copy [[a]]; let mut a = 5_usize; let b = &mut a; // This borrow is only used once. @@ -291,10 +290,9 @@ fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a m { // CHECK: bb8: { // CHECK: [[a:_.*]] = const 5_usize; - // CHECK: [[b:_.*]] = &mut [[a]]; - // CHECK: [[d:_.*]] = &[[b]]; - // FIXME this could be [[a]] - // CHECK: [[c:_.*]] = copy (*[[b]]); + // CHECK-NEXT: DBG: AssignRef([[b:_.*]], [[a]]) + // CHECK-NEXT: DBG: AssignRef([[d:_.*]], [[b]]) + // CHECK-NEXT: [[c:_.*]] = copy [[a]]; let mut a = 5_usize; let b = &mut a; @@ -307,10 +305,9 @@ fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a m { // CHECK: bb9: { // CHECK: [[a:_.*]] = const 5_usize; - // CHECK: [[b:_.*]] = &mut [[a]]; - // CHECK: [[d:_.*]] = &mut [[b]]; - // FIXME this could be [[a]] - // CHECK: [[c:_.*]] = copy (*[[b]]); + // CHECK-NEXT: DBG: AssignRef([[b:_.*]], [[a]]) + // CHECK-NEXT: DBG: AssignRef([[d:_.*]], [[b]]) + // CHECK-NEXT: [[c:_.*]] = copy [[a]]; let mut a = 5_usize; let mut b = &mut a; @@ -463,9 +460,9 @@ fn reference_propagation_const_ptr(single: *const T, mut multiple: *con unsafe { // CHECK: bb9: { // CHECK: [[a:_.*]] = const 5_usize; - // CHECK: [[b:_.*]] = &raw const [[a]]; - // CHECK: [[d:_.*]] = &[[b]]; - // CHECK: [[c:_.*]] = copy [[a]]; + // CHECK-NEXT: [[b:_.*]] = &raw const [[a]]; + // CHECK-NEXT: DBG: AssignRef([[d:_.*]], [[b]]) + // CHECK-NEXT: [[c:_.*]] = copy [[a]]; let a = 5_usize; let b = &raw const a; @@ -479,9 +476,8 @@ fn reference_propagation_const_ptr(single: *const T, mut multiple: *con // CHECK: bb10: { // CHECK: [[a:_.*]] = const 5_usize; // CHECK: [[b:_.*]] = &raw const [[a]]; - // CHECK: [[d:_.*]] = &mut [[b]]; - // FIXME this could be [[a]] - // CHECK: [[c:_.*]] = copy (*[[b]]); + // CHECK-NEXT: DBG: AssignRef([[d:_.*]], [[b]]) + // CHECK: [[c:_.*]] = copy [[a]]; let a = 5_usize; let mut b = &raw const a; @@ -619,10 +615,9 @@ fn reference_propagation_mut_ptr(single: *mut T, mut multiple: *mut T) unsafe { // CHECK: bb8: { // CHECK: [[a:_.*]] = const 5_usize; - // CHECK: [[b:_.*]] = &raw mut [[a]]; - // CHECK: [[d:_.*]] = &[[b]]; - // FIXME this could be [[a]] - // CHECK: [[c:_.*]] = copy (*[[b]]); + // CHECK-NEXT: [[b:_.*]] = &raw mut [[a]]; + // CHECK-NEXT: DBG: AssignRef([[d:_.*]], [[b]]) + // CHECK-NEXT: [[c:_.*]] = copy [[a]]; let mut a = 5_usize; let b = &raw mut a; @@ -635,10 +630,9 @@ fn reference_propagation_mut_ptr(single: *mut T, mut multiple: *mut T) unsafe { // CHECK: bb9: { // CHECK: [[a:_.*]] = const 5_usize; - // CHECK: [[b:_.*]] = &raw mut [[a]]; - // CHECK: [[d:_.*]] = &mut [[b]]; - // FIXME this could be [[a]] - // CHECK: [[c:_.*]] = copy (*[[b]]); + // CHECK-NEXT: [[b:_.*]] = &raw mut [[a]]; + // CHECK-NEXT: DBG: AssignRef([[d:_.*]], [[b]]) + // CHECK: [[c:_.*]] = copy [[a]]; let mut a = 5_usize; let mut b = &raw mut a; diff --git a/tests/mir-opt/uninhabited_not_read.main.SimplifyLocals-final.after.mir b/tests/mir-opt/uninhabited_not_read.main.SimplifyLocals-final.after.mir index 6bf4be652bef3..76f2b01256300 100644 --- a/tests/mir-opt/uninhabited_not_read.main.SimplifyLocals-final.after.mir +++ b/tests/mir-opt/uninhabited_not_read.main.SimplifyLocals-final.after.mir @@ -28,21 +28,17 @@ fn main() -> () { bb0: { StorageLive(_1); _1 = const 3_u8; - StorageLive(_2); StorageLive(_3); _3 = &raw const _1; _2 = move _3 as *const ! (PtrToPtr); StorageDead(_3); - StorageDead(_2); StorageDead(_1); StorageLive(_4); _4 = const 3_u8; - StorageLive(_5); StorageLive(_6); _6 = &raw const _4; _5 = move _6 as *const ! (PtrToPtr); StorageDead(_6); - StorageDead(_5); StorageDead(_4); return; } diff --git a/tests/ui/extern/extern-types-field-offset.rs b/tests/ui/extern/extern-types-field-offset.rs index 75f3eab3e275f..fab853c09cc04 100644 --- a/tests/ui/extern/extern-types-field-offset.rs +++ b/tests/ui/extern/extern-types-field-offset.rs @@ -22,12 +22,17 @@ fn main() { let x: &Newtype = unsafe { &*(&buf as *const _ as *const Newtype) }; // Projecting to the newtype works, because it is always at offset 0. let field = &x.0; + // Avoid being eliminated by DSE. + std::hint::black_box(field); let x: &S = unsafe { &*(&buf as *const _ as *const S) }; // Accessing sized fields is perfectly fine, even at non-zero offsets. let field = &x.i; + std::hint::black_box(field); let field = &x.j; + std::hint::black_box(field); // This needs to compute the field offset, but we don't know the type's alignment, // so this panics. let field = &x.a; + std::hint::black_box(field); }