From 18144b66e1515fa1391b7c7034ba55c47511fb9e Mon Sep 17 00:00:00 2001 From: kadmin Date: Mon, 10 May 2021 04:13:02 +0000 Subject: [PATCH 1/9] Create initial version of opt --- .../rustc_mir/src/transform/large_enums.rs | 212 ++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 compiler/rustc_mir/src/transform/large_enums.rs diff --git a/compiler/rustc_mir/src/transform/large_enums.rs b/compiler/rustc_mir/src/transform/large_enums.rs new file mode 100644 index 0000000000000..b742b7a45e66e --- /dev/null +++ b/compiler/rustc_mir/src/transform/large_enums.rs @@ -0,0 +1,212 @@ +use crate::transform::MirPass; +use crate::util::patch::MirPatch; +use rustc_data_structures::stable_map::FxHashMap; +use rustc_middle::mir::*; +use rustc_middle::ty::{self, Const, List, Ty, TyCtxt}; +use rustc_span::def_id::DefId; +use rustc_target::abi::{Size, Variants}; + +/// A pass that seeks to optimize unnecessary moves of large enum types, if there is a large +/// enough discrepanc between them +pub struct EnumSizeOpt; + +impl<'tcx, const D: u64> MirPass<'tcx> for EnumSizeOpt { + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + self.optim(tcx, body); + } +} + +impl EnumSizeOpt { + fn candidate<'tcx>( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>, + body_did: DefId, + ) -> Option<(Size, u64, Vec)> { + match ty.kind() { + ty::Adt(adt_def, _substs) if adt_def.is_enum() => { + let p_e = tcx.param_env(body_did); + // FIXME(jknodt) handle error better below + let layout = tcx.layout_of(p_e.and(ty)).unwrap(); + let variants = &layout.variants; + match variants { + Variants::Single { .. } => None, + Variants::Multiple { variants, .. } if variants.len() <= 1 => None, + Variants::Multiple { variants, .. } => { + let min = variants.iter().map(|v| v.size).min().unwrap(); + let max = variants.iter().map(|v| v.size).max().unwrap(); + if max.bytes() - min.bytes() < D { + return None; + } + Some(( + layout.size, + variants.len() as u64, + variants.iter().map(|v| v.size).collect(), + )) + } + } + } + _ => None, + } + } + fn optim(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + let mut match_cache = FxHashMap::default(); + let body_did = body.source.def_id(); + let mut patch = MirPatch::new(body); + let (bbs, local_decls) = body.basic_blocks_and_local_decls_mut(); + for bb in bbs { + bb.expand_statements(|st| { + match &st.kind { + StatementKind::Assign(box ( + lhs, + Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)), + )) => { + let ty = lhs.ty(local_decls, tcx).ty; + let (total_size, num_variants, sizes) = + if let Some((ts, nv, s)) = match_cache.get(ty) { + (*ts, *nv, s) + } else if let Some((ts, nv, s)) = Self::candidate(tcx, ty, body_did) { + // FIXME(jknodt) use entry API. + match_cache.insert(ty, (ts, nv, s)); + let (ts, nv, s) = match_cache.get(ty).unwrap(); + (*ts, *nv, s) + } else { + return None; + }; + + let source_info = st.source_info; + let span = source_info.span; + + let tmp_ty = tcx.mk_ty(ty::Array( + tcx.types.usize, + Const::from_usize(tcx, num_variants), + )); + + let new_local = patch.new_temp(tmp_ty, span); + let store_live = + Statement { source_info, kind: StatementKind::StorageLive(new_local) }; + + let place = Place { local: new_local, projection: List::empty() }; + let mut data = + vec![0; std::mem::size_of::() * num_variants as usize]; + data.copy_from_slice(unsafe { std::mem::transmute(&sizes[..]) }); + let alloc = interpret::Allocation::from_bytes( + data, + tcx.data_layout.ptr_sized_integer().align(&tcx.data_layout).abi, + ); + let alloc = tcx.intern_const_alloc(alloc); + let constant_vals = Constant { + span, + user_ty: None, + literal: ConstantKind::Val( + interpret::ConstValue::ByRef { alloc, offset: Size::ZERO }, + tmp_ty, + ), + }; + let rval = Rvalue::Use(Operand::Constant(box (constant_vals))); + + let const_assign = Statement { + source_info, + kind: StatementKind::Assign(box (place, rval)), + }; + + // FIXME(jknodt) do I need to add a storage live here for this place? + let discr_place = Place { + local: patch.new_temp(tcx.types.usize, span), + projection: List::empty(), + }; + + let store_discr = Statement { + source_info, + kind: StatementKind::Assign(box ( + discr_place, + Rvalue::Discriminant(*rhs), + )), + }; + + // FIXME(jknodt) do I need to add a storage live here for this place? + let size_place = Place { + local: patch.new_temp(tcx.types.usize, span), + projection: List::empty(), + }; + + let store_size = Statement { + source_info, + kind: StatementKind::Assign(box ( + size_place, + Rvalue::Use(Operand::Copy(Place { + local: discr_place.local, + projection: tcx + .intern_place_elems(&[PlaceElem::Index(size_place.local)]), + })), + )), + }; + + // FIXME(jknodt) do I need to add a storage live here for this place? + let dst = Place { + local: patch.new_temp(tcx.mk_mut_ptr(tcx.types.u8), span), + projection: List::empty(), + }; + + let dst_ptr = Statement { + source_info, + kind: StatementKind::Assign(box ( + dst, + Rvalue::AddressOf(Mutability::Mut, *lhs), + )), + }; + + // FIXME(jknodt) do I need to add a storage live here for this place? + let src = Place { + local: patch.new_temp(tcx.mk_imm_ptr(tcx.types.u8), span), + projection: List::empty(), + }; + + let src_ptr = Statement { + source_info, + kind: StatementKind::Assign(box ( + src, + Rvalue::AddressOf(Mutability::Mut, *rhs), + )), + }; + + let copy_bytes = Statement { + source_info, + kind: StatementKind::CopyNonOverlapping(box CopyNonOverlapping { + src: Operand::Copy(src), + dst: Operand::Copy(src), + count: Operand::Constant( + box (Constant { + span, + user_ty: None, + literal: ConstantKind::Val( + interpret::ConstValue::from_u64(total_size.bytes()), + tcx.types.usize, + ), + }), + ), + }), + }; + + let store_dead = + Statement { source_info, kind: StatementKind::StorageDead(new_local) }; + let iter = std::array::IntoIter::new([ + store_live, + const_assign, + store_discr, + store_size, + dst_ptr, + src_ptr, + copy_bytes, + store_dead, + ]); + + st.make_nop(); + Some(iter) + } + _ => return None, + } + }); + } + patch.apply(body); + } +} From 96db5e9c7b2f8b97b75a5afeae21e0e0abf7bdfe Mon Sep 17 00:00:00 2001 From: kadmin Date: Fri, 28 May 2021 04:17:00 +0000 Subject: [PATCH 2/9] Add comments Still need to make it so that it maps discriminants to variant indexes. Maybe instead I can map the variant indexes to discriminants? --- .../rustc_mir/src/transform/large_enums.rs | 82 +++++++++++-------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_mir/src/transform/large_enums.rs b/compiler/rustc_mir/src/transform/large_enums.rs index b742b7a45e66e..a8377c95dcb39 100644 --- a/compiler/rustc_mir/src/transform/large_enums.rs +++ b/compiler/rustc_mir/src/transform/large_enums.rs @@ -4,7 +4,7 @@ use rustc_data_structures::stable_map::FxHashMap; use rustc_middle::mir::*; use rustc_middle::ty::{self, Const, List, Ty, TyCtxt}; use rustc_span::def_id::DefId; -use rustc_target::abi::{Size, Variants}; +use rustc_target::abi::{Size, TagEncoding, Variants}; /// A pass that seeks to optimize unnecessary moves of large enum types, if there is a large /// enough discrepanc between them @@ -31,17 +31,25 @@ impl EnumSizeOpt { match variants { Variants::Single { .. } => None, Variants::Multiple { variants, .. } if variants.len() <= 1 => None, + Variants::Multiple { tag_encoding, .. } + if matches!(tag_encoding, TagEncoding::Niche { .. }) => + { + None + } Variants::Multiple { variants, .. } => { let min = variants.iter().map(|v| v.size).min().unwrap(); let max = variants.iter().map(|v| v.size).max().unwrap(); if max.bytes() - min.bytes() < D { return None; } - Some(( - layout.size, - variants.len() as u64, - variants.iter().map(|v| v.size).collect(), - )) + let mut discr_sizes = vec![Size::ZERO; adt_def.discriminants(tcx).count()]; + for (var_idx, layout) in variants.iter_enumerated() { + let disc_idx = + adt_def.discriminant_for_variant(tcx, var_idx).val as usize; + assert_eq!(discr_sizes[disc_idx], Size::ZERO); + discr_sizes[disc_idx] = layout.size; + } + Some((layout.size, variants.len() as u64, discr_sizes)) } } } @@ -49,7 +57,7 @@ impl EnumSizeOpt { } } fn optim(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let mut match_cache = FxHashMap::default(); + let mut alloc_cache = FxHashMap::default(); let body_did = body.source.def_id(); let mut patch = MirPatch::new(body); let (bbs, local_decls) = body.basic_blocks_and_local_decls_mut(); @@ -61,39 +69,45 @@ impl EnumSizeOpt { Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)), )) => { let ty = lhs.ty(local_decls, tcx).ty; + let source_info = st.source_info; + let span = source_info.span; + let (total_size, num_variants, sizes) = - if let Some((ts, nv, s)) = match_cache.get(ty) { - (*ts, *nv, s) - } else if let Some((ts, nv, s)) = Self::candidate(tcx, ty, body_did) { - // FIXME(jknodt) use entry API. - match_cache.insert(ty, (ts, nv, s)); - let (ts, nv, s) = match_cache.get(ty).unwrap(); - (*ts, *nv, s) + if let Some((ts, nv, s)) = Self::candidate(tcx, ty, body_did) { + (ts, nv, s) } else { return None; }; - let source_info = st.source_info; - let span = source_info.span; + let alloc = if let Some(alloc) = alloc_cache.get(ty) { + alloc + } else { + let mut data = + vec![0; std::mem::size_of::() * num_variants as usize]; + data.copy_from_slice(unsafe { std::mem::transmute(&sizes[..]) }); + let alloc = interpret::Allocation::from_bytes( + data, + tcx.data_layout.ptr_sized_integer().align(&tcx.data_layout).abi, + Mutability::Not, + ); + let alloc = tcx.intern_const_alloc(alloc); + alloc_cache.insert(ty, alloc); + // FIXME(jknodt) use entry API + alloc_cache.get(ty).unwrap() + }; let tmp_ty = tcx.mk_ty(ty::Array( tcx.types.usize, Const::from_usize(tcx, num_variants), )); - let new_local = patch.new_temp(tmp_ty, span); - let store_live = - Statement { source_info, kind: StatementKind::StorageLive(new_local) }; - - let place = Place { local: new_local, projection: List::empty() }; - let mut data = - vec![0; std::mem::size_of::() * num_variants as usize]; - data.copy_from_slice(unsafe { std::mem::transmute(&sizes[..]) }); - let alloc = interpret::Allocation::from_bytes( - data, - tcx.data_layout.ptr_sized_integer().align(&tcx.data_layout).abi, - ); - let alloc = tcx.intern_const_alloc(alloc); + let size_array_local = patch.new_temp(tmp_ty, span); + let store_live = Statement { + source_info, + kind: StatementKind::StorageLive(size_array_local), + }; + + let place = Place { local: size_array_local, projection: List::empty() }; let constant_vals = Constant { span, user_ty: None, @@ -134,9 +148,9 @@ impl EnumSizeOpt { kind: StatementKind::Assign(box ( size_place, Rvalue::Use(Operand::Copy(Place { - local: discr_place.local, + local: size_array_local, projection: tcx - .intern_place_elems(&[PlaceElem::Index(size_place.local)]), + .intern_place_elems(&[PlaceElem::Index(discr_place.local)]), })), )), }; @@ -187,8 +201,10 @@ impl EnumSizeOpt { }), }; - let store_dead = - Statement { source_info, kind: StatementKind::StorageDead(new_local) }; + let store_dead = Statement { + source_info, + kind: StatementKind::StorageDead(size_array_local), + }; let iter = std::array::IntoIter::new([ store_live, const_assign, From 33b4d203382f37917f5d5e1bc9057582529a9e90 Mon Sep 17 00:00:00 2001 From: kadmin Date: Tue, 1 Jun 2021 02:30:02 +0000 Subject: [PATCH 3/9] Clean up MIR transform --- .../rustc_mir/src/transform/large_enums.rs | 60 +++++++++++++++---- compiler/rustc_mir_transform/src/lib.rs | 2 + 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_mir/src/transform/large_enums.rs b/compiler/rustc_mir/src/transform/large_enums.rs index a8377c95dcb39..f5bf40846e039 100644 --- a/compiler/rustc_mir/src/transform/large_enums.rs +++ b/compiler/rustc_mir/src/transform/large_enums.rs @@ -26,7 +26,8 @@ impl EnumSizeOpt { ty::Adt(adt_def, _substs) if adt_def.is_enum() => { let p_e = tcx.param_env(body_did); // FIXME(jknodt) handle error better below - let layout = tcx.layout_of(p_e.and(ty)).unwrap(); + let layout = + if let Ok(layout) = tcx.layout_of(p_e.and(ty)) { layout } else { return None }; let variants = &layout.variants; match variants { Variants::Single { .. } => None, @@ -84,7 +85,16 @@ impl EnumSizeOpt { } else { let mut data = vec![0; std::mem::size_of::() * num_variants as usize]; - data.copy_from_slice(unsafe { std::mem::transmute(&sizes[..]) }); + + let mut curr = 0; + for byte in sizes + .iter() + .flat_map(|sz| sz.bytes().to_ne_bytes()) + .take(data.len()) + { + data[curr] = byte; + curr += 1; + } let alloc = interpret::Allocation::from_bytes( data, tcx.data_layout.ptr_sized_integer().align(&tcx.data_layout).abi, @@ -123,9 +133,9 @@ impl EnumSizeOpt { kind: StatementKind::Assign(box (place, rval)), }; - // FIXME(jknodt) do I need to add a storage live here for this place? let discr_place = Place { - local: patch.new_temp(tcx.types.usize, span), + // How do I get the discriminant type? + local: patch.new_temp(tcx.types.isize, span), projection: List::empty(), }; @@ -155,9 +165,8 @@ impl EnumSizeOpt { )), }; - // FIXME(jknodt) do I need to add a storage live here for this place? let dst = Place { - local: patch.new_temp(tcx.mk_mut_ptr(tcx.types.u8), span), + local: patch.new_temp(tcx.mk_mut_ptr(ty), span), projection: List::empty(), }; @@ -169,9 +178,22 @@ impl EnumSizeOpt { )), }; - // FIXME(jknodt) do I need to add a storage live here for this place? + let dst_cast_ty = tcx.mk_mut_ptr(tcx.types.u8); + let dst_cast_place = Place { + local: patch.new_temp(dst_cast_ty, span), + projection: List::empty(), + }; + + let dst_cast = Statement { + source_info, + kind: StatementKind::Assign(box ( + dst_cast_place, + Rvalue::Cast(CastKind::Misc, Operand::Copy(dst), dst_cast_ty), + )), + }; + let src = Place { - local: patch.new_temp(tcx.mk_imm_ptr(tcx.types.u8), span), + local: patch.new_temp(tcx.mk_imm_ptr(ty), span), projection: List::empty(), }; @@ -179,15 +201,29 @@ impl EnumSizeOpt { source_info, kind: StatementKind::Assign(box ( src, - Rvalue::AddressOf(Mutability::Mut, *rhs), + Rvalue::AddressOf(Mutability::Not, *rhs), + )), + }; + + let src_cast_ty = tcx.mk_imm_ptr(tcx.types.u8); + let src_cast_place = Place { + local: patch.new_temp(src_cast_ty, span), + projection: List::empty(), + }; + + let src_cast = Statement { + source_info, + kind: StatementKind::Assign(box ( + src_cast_place, + Rvalue::Cast(CastKind::Misc, Operand::Copy(src), src_cast_ty), )), }; let copy_bytes = Statement { source_info, kind: StatementKind::CopyNonOverlapping(box CopyNonOverlapping { - src: Operand::Copy(src), - dst: Operand::Copy(src), + src: Operand::Copy(src_cast_place), + dst: Operand::Copy(dst_cast_place), count: Operand::Constant( box (Constant { span, @@ -211,7 +247,9 @@ impl EnumSizeOpt { store_discr, store_size, dst_ptr, + dst_cast, src_ptr, + src_cast, copy_bytes, store_dead, ]); diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 9070a7368b168..00ec4b3e75457 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -2,6 +2,8 @@ #![feature(box_patterns)] #![feature(drain_filter)] #![feature(let_chains)] +#![feature(let_else)] +#![feature(entry_insert)] #![feature(map_try_insert)] #![feature(min_specialization)] #![feature(never_type)] From f7cbf2eb410915149e983b5a934567d0512e10e5 Mon Sep 17 00:00:00 2001 From: kadmin Date: Wed, 2 Jun 2021 03:47:05 +0000 Subject: [PATCH 4/9] Update with comments Changing a bunch of struct constructors to `from`, no extra destructuring, getting the type of the discriminant. --- .../rustc_mir/src/transform/large_enums.rs | 76 ++++++++++--------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_mir/src/transform/large_enums.rs b/compiler/rustc_mir/src/transform/large_enums.rs index f5bf40846e039..efda87a154771 100644 --- a/compiler/rustc_mir/src/transform/large_enums.rs +++ b/compiler/rustc_mir/src/transform/large_enums.rs @@ -1,8 +1,8 @@ use crate::transform::MirPass; -use crate::util::patch::MirPatch; use rustc_data_structures::stable_map::FxHashMap; use rustc_middle::mir::*; -use rustc_middle::ty::{self, Const, List, Ty, TyCtxt}; +use rustc_middle::ty::util::IntTypeExt; +use rustc_middle::ty::{self, Const, Ty, TyCtxt}; use rustc_span::def_id::DefId; use rustc_target::abi::{Size, TagEncoding, Variants}; @@ -60,7 +60,6 @@ impl EnumSizeOpt { fn optim(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let mut alloc_cache = FxHashMap::default(); let body_did = body.source.def_id(); - let mut patch = MirPatch::new(body); let (bbs, local_decls) = body.basic_blocks_and_local_decls_mut(); for bb in bbs { bb.expand_statements(|st| { @@ -70,15 +69,17 @@ impl EnumSizeOpt { Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)), )) => { let ty = lhs.ty(local_decls, tcx).ty; + let source_info = st.source_info; let span = source_info.span; let (total_size, num_variants, sizes) = - if let Some((ts, nv, s)) = Self::candidate(tcx, ty, body_did) { - (ts, nv, s) + if let Some(cand) = Self::candidate(tcx, ty, body_did) { + cand } else { return None; }; + let adt_def = ty.ty_adt_def().unwrap(); let alloc = if let Some(alloc) = alloc_cache.get(ty) { alloc @@ -111,13 +112,13 @@ impl EnumSizeOpt { Const::from_usize(tcx, num_variants), )); - let size_array_local = patch.new_temp(tmp_ty, span); + let size_array_local = local_decls.push(LocalDecl::new(tmp_ty, span)); let store_live = Statement { source_info, kind: StatementKind::StorageLive(size_array_local), }; - let place = Place { local: size_array_local, projection: List::empty() }; + let place = Place::from(size_array_local); let constant_vals = Constant { span, user_ty: None, @@ -133,11 +134,10 @@ impl EnumSizeOpt { kind: StatementKind::Assign(box (place, rval)), }; - let discr_place = Place { - // How do I get the discriminant type? - local: patch.new_temp(tcx.types.isize, span), - projection: List::empty(), - }; + let discr_place = Place::from( + local_decls + .push(LocalDecl::new(adt_def.repr.discr_type().to_ty(tcx), span)), + ); let store_discr = Statement { source_info, @@ -147,28 +147,40 @@ impl EnumSizeOpt { )), }; - // FIXME(jknodt) do I need to add a storage live here for this place? - let size_place = Place { - local: patch.new_temp(tcx.types.usize, span), - projection: List::empty(), + let discr_cast_place = + Place::from(local_decls.push(LocalDecl::new(tcx.types.usize, span))); + + let cast_discr = Statement { + source_info, + kind: StatementKind::Assign(box ( + discr_cast_place, + Rvalue::Cast( + CastKind::Misc, + Operand::Copy(discr_place), + tcx.types.usize, + ), + )), }; + // FIXME(jknodt) do I need to add a storage live here for this place? + let size_place = + Place::from(local_decls.push(LocalDecl::new(tcx.types.usize, span))); + let store_size = Statement { source_info, kind: StatementKind::Assign(box ( size_place, Rvalue::Use(Operand::Copy(Place { local: size_array_local, - projection: tcx - .intern_place_elems(&[PlaceElem::Index(discr_place.local)]), + projection: tcx.intern_place_elems(&[PlaceElem::Index( + discr_cast_place.local, + )]), })), )), }; - let dst = Place { - local: patch.new_temp(tcx.mk_mut_ptr(ty), span), - projection: List::empty(), - }; + let dst = + Place::from(local_decls.push(LocalDecl::new(tcx.mk_mut_ptr(ty), span))); let dst_ptr = Statement { source_info, @@ -179,10 +191,8 @@ impl EnumSizeOpt { }; let dst_cast_ty = tcx.mk_mut_ptr(tcx.types.u8); - let dst_cast_place = Place { - local: patch.new_temp(dst_cast_ty, span), - projection: List::empty(), - }; + let dst_cast_place = + Place::from(local_decls.push(LocalDecl::new(dst_cast_ty, span))); let dst_cast = Statement { source_info, @@ -192,10 +202,8 @@ impl EnumSizeOpt { )), }; - let src = Place { - local: patch.new_temp(tcx.mk_imm_ptr(ty), span), - projection: List::empty(), - }; + let src = + Place::from(local_decls.push(LocalDecl::new(tcx.mk_imm_ptr(ty), span))); let src_ptr = Statement { source_info, @@ -206,10 +214,8 @@ impl EnumSizeOpt { }; let src_cast_ty = tcx.mk_imm_ptr(tcx.types.u8); - let src_cast_place = Place { - local: patch.new_temp(src_cast_ty, span), - projection: List::empty(), - }; + let src_cast_place = + Place::from(local_decls.push(LocalDecl::new(src_cast_ty, span))); let src_cast = Statement { source_info, @@ -245,6 +251,7 @@ impl EnumSizeOpt { store_live, const_assign, store_discr, + cast_discr, store_size, dst_ptr, dst_cast, @@ -261,6 +268,5 @@ impl EnumSizeOpt { } }); } - patch.apply(body); } } From 3e97cef7e5696a57f1b528b2bf551a2e3721100d Mon Sep 17 00:00:00 2001 From: kadmin Date: Mon, 7 Jun 2021 08:37:41 +0000 Subject: [PATCH 5/9] Set mir-opt-level = 0 on some codegen tests Since we're changing a bunch of stuff, necessary to remove some codegen tests which look for specific things. Also attempting to restart a test which timed out, maybe due to fastly failing? --- .../rustc_mir/src/transform/large_enums.rs | 62 ++++++++++--------- tests/codegen/consts.rs | 2 +- tests/codegen/function-arguments.rs | 2 +- 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_mir/src/transform/large_enums.rs b/compiler/rustc_mir/src/transform/large_enums.rs index efda87a154771..51bf880313a63 100644 --- a/compiler/rustc_mir/src/transform/large_enums.rs +++ b/compiler/rustc_mir/src/transform/large_enums.rs @@ -4,7 +4,8 @@ use rustc_middle::mir::*; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, Const, Ty, TyCtxt}; use rustc_span::def_id::DefId; -use rustc_target::abi::{Size, TagEncoding, Variants}; +use rustc_target::abi::{HasDataLayout, Size, TagEncoding, Variants}; +use std::array::IntoIter; /// A pass that seeks to optimize unnecessary moves of large enum types, if there is a large /// enough discrepanc between them @@ -21,11 +22,10 @@ impl EnumSizeOpt { tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body_did: DefId, - ) -> Option<(Size, u64, Vec)> { + ) -> Option<(u64, Vec)> { match ty.kind() { ty::Adt(adt_def, _substs) if adt_def.is_enum() => { let p_e = tcx.param_env(body_did); - // FIXME(jknodt) handle error better below let layout = if let Ok(layout) = tcx.layout_of(p_e.and(ty)) { layout } else { return None }; let variants = &layout.variants; @@ -50,7 +50,7 @@ impl EnumSizeOpt { assert_eq!(discr_sizes[disc_idx], Size::ZERO); discr_sizes[disc_idx] = layout.size; } - Some((layout.size, variants.len() as u64, discr_sizes)) + Some((variants.len() as u64, discr_sizes)) } } } @@ -73,28 +73,44 @@ impl EnumSizeOpt { let source_info = st.source_info; let span = source_info.span; - let (total_size, num_variants, sizes) = + let (num_variants, sizes) = if let Some(cand) = Self::candidate(tcx, ty, body_did) { cand } else { return None; }; let adt_def = ty.ty_adt_def().unwrap(); - let alloc = if let Some(alloc) = alloc_cache.get(ty) { alloc } else { - let mut data = - vec![0; std::mem::size_of::() * num_variants as usize]; - + let data_layout = tcx.data_layout(); + let ptr_sized_int = data_layout.ptr_sized_integer(); + let target_bytes = ptr_sized_int.size().bytes() as usize; + let mut data = vec![0; target_bytes * num_variants as usize]; let mut curr = 0; - for byte in sizes - .iter() - .flat_map(|sz| sz.bytes().to_ne_bytes()) - .take(data.len()) - { - data[curr] = byte; - curr += 1; + macro_rules! encode_store { + ($endian: expr, $bytes: expr) => { + let bytes = match $endian { + rustc_target::abi::Endian::Little => $bytes.to_le_bytes(), + rustc_target::abi::Endian::Big => $bytes.to_be_bytes(), + }; + for b in bytes { + data[curr] = b; + curr += 1; + } + }; + } + + for sz in sizes { + match ptr_sized_int { + rustc_target::abi::Integer::I32 => { + encode_store!(data_layout.endian, sz.bytes() as u32); + } + rustc_target::abi::Integer::I64 => { + encode_store!(data_layout.endian, sz.bytes()); + } + _ => unreachable!(), + }; } let alloc = interpret::Allocation::from_bytes( data, @@ -162,7 +178,6 @@ impl EnumSizeOpt { )), }; - // FIXME(jknodt) do I need to add a storage live here for this place? let size_place = Place::from(local_decls.push(LocalDecl::new(tcx.types.usize, span))); @@ -230,16 +245,7 @@ impl EnumSizeOpt { kind: StatementKind::CopyNonOverlapping(box CopyNonOverlapping { src: Operand::Copy(src_cast_place), dst: Operand::Copy(dst_cast_place), - count: Operand::Constant( - box (Constant { - span, - user_ty: None, - literal: ConstantKind::Val( - interpret::ConstValue::from_u64(total_size.bytes()), - tcx.types.usize, - ), - }), - ), + count: Operand::Copy(size_place), }), }; @@ -247,7 +253,7 @@ impl EnumSizeOpt { source_info, kind: StatementKind::StorageDead(size_array_local), }; - let iter = std::array::IntoIter::new([ + let iter = IntoIter::new([ store_live, const_assign, store_discr, diff --git a/tests/codegen/consts.rs b/tests/codegen/consts.rs index 260d9de867087..9d75356b03dc9 100644 --- a/tests/codegen/consts.rs +++ b/tests/codegen/consts.rs @@ -1,4 +1,4 @@ -// compile-flags: -C no-prepopulate-passes +// compile-flags: -C no-prepopulate-passes -Zmir-opt-level=0 // min-llvm-version: 14.0 #![crate_type = "lib"] diff --git a/tests/codegen/function-arguments.rs b/tests/codegen/function-arguments.rs index 96dfde18683e3..020d9234e57cc 100644 --- a/tests/codegen/function-arguments.rs +++ b/tests/codegen/function-arguments.rs @@ -1,4 +1,4 @@ -// compile-flags: -O -C no-prepopulate-passes +// compile-flags: -O -C no-prepopulate-passes -Zmir-opt-level=0 #![crate_type = "lib"] From 5d9f5145ac9ce07d79aeb75ad049cab957b0fb92 Mon Sep 17 00:00:00 2001 From: kadmin Date: Wed, 16 Jun 2021 05:46:56 +0000 Subject: [PATCH 6/9] Rm allocation in candidate Instead of storing an extra array for discriminant values, create an allocation there and store those in an allocation immediately. --- .../rustc_mir/src/transform/large_enums.rs | 278 ----------------- .../rustc_mir_transform/src/large_enums.rs | 283 ++++++++++++++++++ compiler/rustc_mir_transform/src/lib.rs | 3 +- tests/codegen/consts.rs | 2 +- tests/codegen/function-arguments.rs | 2 +- .../enum_opt.cand.EnumSizeOpt.32bit.diff | 55 ++++ .../enum_opt.cand.EnumSizeOpt.64bit.diff | 55 ++++ .../enum_opt.invalid.EnumSizeOpt.32bit.diff | 35 +++ .../enum_opt.invalid.EnumSizeOpt.64bit.diff | 35 +++ tests/mir-opt/enum_opt.rs | 79 +++++ .../enum_opt.trunc.EnumSizeOpt.32bit.diff | 46 +++ .../enum_opt.trunc.EnumSizeOpt.64bit.diff | 46 +++ .../enum_opt.unin.EnumSizeOpt.32bit.diff | 54 ++++ .../enum_opt.unin.EnumSizeOpt.64bit.diff | 54 ++++ 14 files changed, 746 insertions(+), 281 deletions(-) delete mode 100644 compiler/rustc_mir/src/transform/large_enums.rs create mode 100644 compiler/rustc_mir_transform/src/large_enums.rs create mode 100644 tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff create mode 100644 tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff create mode 100644 tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff create mode 100644 tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff create mode 100644 tests/mir-opt/enum_opt.rs create mode 100644 tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff create mode 100644 tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff create mode 100644 tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff create mode 100644 tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff diff --git a/compiler/rustc_mir/src/transform/large_enums.rs b/compiler/rustc_mir/src/transform/large_enums.rs deleted file mode 100644 index 51bf880313a63..0000000000000 --- a/compiler/rustc_mir/src/transform/large_enums.rs +++ /dev/null @@ -1,278 +0,0 @@ -use crate::transform::MirPass; -use rustc_data_structures::stable_map::FxHashMap; -use rustc_middle::mir::*; -use rustc_middle::ty::util::IntTypeExt; -use rustc_middle::ty::{self, Const, Ty, TyCtxt}; -use rustc_span::def_id::DefId; -use rustc_target::abi::{HasDataLayout, Size, TagEncoding, Variants}; -use std::array::IntoIter; - -/// A pass that seeks to optimize unnecessary moves of large enum types, if there is a large -/// enough discrepanc between them -pub struct EnumSizeOpt; - -impl<'tcx, const D: u64> MirPass<'tcx> for EnumSizeOpt { - fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - self.optim(tcx, body); - } -} - -impl EnumSizeOpt { - fn candidate<'tcx>( - tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>, - body_did: DefId, - ) -> Option<(u64, Vec)> { - match ty.kind() { - ty::Adt(adt_def, _substs) if adt_def.is_enum() => { - let p_e = tcx.param_env(body_did); - let layout = - if let Ok(layout) = tcx.layout_of(p_e.and(ty)) { layout } else { return None }; - let variants = &layout.variants; - match variants { - Variants::Single { .. } => None, - Variants::Multiple { variants, .. } if variants.len() <= 1 => None, - Variants::Multiple { tag_encoding, .. } - if matches!(tag_encoding, TagEncoding::Niche { .. }) => - { - None - } - Variants::Multiple { variants, .. } => { - let min = variants.iter().map(|v| v.size).min().unwrap(); - let max = variants.iter().map(|v| v.size).max().unwrap(); - if max.bytes() - min.bytes() < D { - return None; - } - let mut discr_sizes = vec![Size::ZERO; adt_def.discriminants(tcx).count()]; - for (var_idx, layout) in variants.iter_enumerated() { - let disc_idx = - adt_def.discriminant_for_variant(tcx, var_idx).val as usize; - assert_eq!(discr_sizes[disc_idx], Size::ZERO); - discr_sizes[disc_idx] = layout.size; - } - Some((variants.len() as u64, discr_sizes)) - } - } - } - _ => None, - } - } - fn optim(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let mut alloc_cache = FxHashMap::default(); - let body_did = body.source.def_id(); - let (bbs, local_decls) = body.basic_blocks_and_local_decls_mut(); - for bb in bbs { - bb.expand_statements(|st| { - match &st.kind { - StatementKind::Assign(box ( - lhs, - Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)), - )) => { - let ty = lhs.ty(local_decls, tcx).ty; - - let source_info = st.source_info; - let span = source_info.span; - - let (num_variants, sizes) = - if let Some(cand) = Self::candidate(tcx, ty, body_did) { - cand - } else { - return None; - }; - let adt_def = ty.ty_adt_def().unwrap(); - let alloc = if let Some(alloc) = alloc_cache.get(ty) { - alloc - } else { - let data_layout = tcx.data_layout(); - let ptr_sized_int = data_layout.ptr_sized_integer(); - let target_bytes = ptr_sized_int.size().bytes() as usize; - let mut data = vec![0; target_bytes * num_variants as usize]; - let mut curr = 0; - macro_rules! encode_store { - ($endian: expr, $bytes: expr) => { - let bytes = match $endian { - rustc_target::abi::Endian::Little => $bytes.to_le_bytes(), - rustc_target::abi::Endian::Big => $bytes.to_be_bytes(), - }; - for b in bytes { - data[curr] = b; - curr += 1; - } - }; - } - - for sz in sizes { - match ptr_sized_int { - rustc_target::abi::Integer::I32 => { - encode_store!(data_layout.endian, sz.bytes() as u32); - } - rustc_target::abi::Integer::I64 => { - encode_store!(data_layout.endian, sz.bytes()); - } - _ => unreachable!(), - }; - } - let alloc = interpret::Allocation::from_bytes( - data, - tcx.data_layout.ptr_sized_integer().align(&tcx.data_layout).abi, - Mutability::Not, - ); - let alloc = tcx.intern_const_alloc(alloc); - alloc_cache.insert(ty, alloc); - // FIXME(jknodt) use entry API - alloc_cache.get(ty).unwrap() - }; - - let tmp_ty = tcx.mk_ty(ty::Array( - tcx.types.usize, - Const::from_usize(tcx, num_variants), - )); - - let size_array_local = local_decls.push(LocalDecl::new(tmp_ty, span)); - let store_live = Statement { - source_info, - kind: StatementKind::StorageLive(size_array_local), - }; - - let place = Place::from(size_array_local); - let constant_vals = Constant { - span, - user_ty: None, - literal: ConstantKind::Val( - interpret::ConstValue::ByRef { alloc, offset: Size::ZERO }, - tmp_ty, - ), - }; - let rval = Rvalue::Use(Operand::Constant(box (constant_vals))); - - let const_assign = Statement { - source_info, - kind: StatementKind::Assign(box (place, rval)), - }; - - let discr_place = Place::from( - local_decls - .push(LocalDecl::new(adt_def.repr.discr_type().to_ty(tcx), span)), - ); - - let store_discr = Statement { - source_info, - kind: StatementKind::Assign(box ( - discr_place, - Rvalue::Discriminant(*rhs), - )), - }; - - let discr_cast_place = - Place::from(local_decls.push(LocalDecl::new(tcx.types.usize, span))); - - let cast_discr = Statement { - source_info, - kind: StatementKind::Assign(box ( - discr_cast_place, - Rvalue::Cast( - CastKind::Misc, - Operand::Copy(discr_place), - tcx.types.usize, - ), - )), - }; - - let size_place = - Place::from(local_decls.push(LocalDecl::new(tcx.types.usize, span))); - - let store_size = Statement { - source_info, - kind: StatementKind::Assign(box ( - size_place, - Rvalue::Use(Operand::Copy(Place { - local: size_array_local, - projection: tcx.intern_place_elems(&[PlaceElem::Index( - discr_cast_place.local, - )]), - })), - )), - }; - - let dst = - Place::from(local_decls.push(LocalDecl::new(tcx.mk_mut_ptr(ty), span))); - - let dst_ptr = Statement { - source_info, - kind: StatementKind::Assign(box ( - dst, - Rvalue::AddressOf(Mutability::Mut, *lhs), - )), - }; - - let dst_cast_ty = tcx.mk_mut_ptr(tcx.types.u8); - let dst_cast_place = - Place::from(local_decls.push(LocalDecl::new(dst_cast_ty, span))); - - let dst_cast = Statement { - source_info, - kind: StatementKind::Assign(box ( - dst_cast_place, - Rvalue::Cast(CastKind::Misc, Operand::Copy(dst), dst_cast_ty), - )), - }; - - let src = - Place::from(local_decls.push(LocalDecl::new(tcx.mk_imm_ptr(ty), span))); - - let src_ptr = Statement { - source_info, - kind: StatementKind::Assign(box ( - src, - Rvalue::AddressOf(Mutability::Not, *rhs), - )), - }; - - let src_cast_ty = tcx.mk_imm_ptr(tcx.types.u8); - let src_cast_place = - Place::from(local_decls.push(LocalDecl::new(src_cast_ty, span))); - - let src_cast = Statement { - source_info, - kind: StatementKind::Assign(box ( - src_cast_place, - Rvalue::Cast(CastKind::Misc, Operand::Copy(src), src_cast_ty), - )), - }; - - let copy_bytes = Statement { - source_info, - kind: StatementKind::CopyNonOverlapping(box CopyNonOverlapping { - src: Operand::Copy(src_cast_place), - dst: Operand::Copy(dst_cast_place), - count: Operand::Copy(size_place), - }), - }; - - let store_dead = Statement { - source_info, - kind: StatementKind::StorageDead(size_array_local), - }; - let iter = IntoIter::new([ - store_live, - const_assign, - store_discr, - cast_discr, - store_size, - dst_ptr, - dst_cast, - src_ptr, - src_cast, - copy_bytes, - store_dead, - ]); - - st.make_nop(); - Some(iter) - } - _ => return None, - } - }); - } - } -} diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs new file mode 100644 index 0000000000000..1919720de4996 --- /dev/null +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -0,0 +1,283 @@ +use crate::rustc_middle::ty::util::IntTypeExt; +use crate::MirPass; +use rustc_data_structures::stable_map::FxHashMap; +use rustc_middle::mir::interpret::AllocId; +use rustc_middle::mir::*; +use rustc_middle::ty::{self, AdtDef, Const, ParamEnv, Ty, TyCtxt}; +use rustc_target::abi::{HasDataLayout, Size, TagEncoding, Variants}; + +/// A pass that seeks to optimize unnecessary moves of large enum types, if there is a large +/// enough discrepancy between them. +/// +/// i.e. If there is are two variants: +/// ``` +/// enum Example { +/// Small, +/// Large([u32; 1024]), +/// } +/// ``` +/// Instead of emitting moves of the large variant, +/// Perform a memcpy instead. +/// Based off of [this HackMD](https://hackmd.io/@ft4bxUsFT5CEUBmRKYHr7w/rJM8BBPzD). +pub struct EnumSizeOpt { + pub(crate) discrepancy: u64, +} + +impl<'tcx> MirPass<'tcx> for EnumSizeOpt { + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + let sess = tcx.sess; + if (!sess.opts.debugging_opts.unsound_mir_opts) || sess.mir_opt_level() < 3 { + return; + } + self.optim(tcx, body); + } +} + +impl EnumSizeOpt { + fn candidate<'tcx>( + &self, + tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, + ty: Ty<'tcx>, + alloc_cache: &mut FxHashMap, AllocId>, + ) -> Option<(AdtDef<'tcx>, usize, AllocId)> { + let adt_def = match ty.kind() { + ty::Adt(adt_def, _substs) if adt_def.is_enum() => adt_def, + _ => return None, + }; + let layout = tcx.layout_of(param_env.and(ty)).ok()?; + let variants = match &layout.variants { + Variants::Single { .. } => return None, + Variants::Multiple { tag_encoding, .. } + if matches!(tag_encoding, TagEncoding::Niche { .. }) => + { + return None; + } + Variants::Multiple { variants, .. } if variants.len() <= 1 => return None, + Variants::Multiple { variants, .. } => variants, + }; + let min = variants.iter().map(|v| v.size()).min().unwrap(); + let max = variants.iter().map(|v| v.size()).max().unwrap(); + if max.bytes() - min.bytes() < self.discrepancy { + return None; + } + + let num_discrs = adt_def.discriminants(tcx).count(); + if variants.iter_enumerated().any(|(var_idx, _)| { + let discr_for_var = adt_def.discriminant_for_variant(tcx, var_idx).val; + (discr_for_var > usize::MAX as u128) || (discr_for_var as usize >= num_discrs) + }) { + return None; + } + if let Some(alloc_id) = alloc_cache.get(&ty) { + return Some((*adt_def, num_discrs, *alloc_id)); + } + + let data_layout = tcx.data_layout(); + let ptr_sized_int = data_layout.ptr_sized_integer(); + let target_bytes = ptr_sized_int.size().bytes() as usize; + let mut data = vec![0; target_bytes * num_discrs]; + macro_rules! encode_store { + ($curr_idx: expr, $endian: expr, $bytes: expr) => { + let bytes = match $endian { + rustc_target::abi::Endian::Little => $bytes.to_le_bytes(), + rustc_target::abi::Endian::Big => $bytes.to_be_bytes(), + }; + for (i, b) in bytes.into_iter().enumerate() { + data[$curr_idx + i] = b; + } + }; + } + + for (var_idx, layout) in variants.iter_enumerated() { + let curr_idx = + target_bytes * adt_def.discriminant_for_variant(tcx, var_idx).val as usize; + let sz = layout.size(); + match ptr_sized_int { + rustc_target::abi::Integer::I32 => { + encode_store!(curr_idx, data_layout.endian, sz.bytes() as u32); + } + rustc_target::abi::Integer::I64 => { + encode_store!(curr_idx, data_layout.endian, sz.bytes()); + } + _ => unreachable!(), + }; + } + let alloc = interpret::Allocation::from_bytes( + data, + tcx.data_layout.ptr_sized_integer().align(&tcx.data_layout).abi, + Mutability::Not, + ); + let alloc = tcx.create_memory_alloc(tcx.intern_const_alloc(alloc)); + Some((*adt_def, num_discrs, *alloc_cache.entry(ty).or_insert(alloc))) + } + fn optim<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + let mut alloc_cache = FxHashMap::default(); + let body_did = body.source.def_id(); + let param_env = tcx.param_env(body_did); + let (bbs, local_decls) = body.basic_blocks_and_local_decls_mut(); + for bb in bbs { + bb.expand_statements(|st| { + if let StatementKind::Assign(box ( + lhs, + Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)), + )) = &st.kind + { + let ty = lhs.ty(local_decls, tcx).ty; + + let source_info = st.source_info; + let span = source_info.span; + + let (adt_def, num_variants, alloc_id) = + self.candidate(tcx, param_env, ty, &mut alloc_cache)?; + let alloc = tcx.global_alloc(alloc_id).unwrap_memory(); + + let tmp_ty = tcx.mk_ty(ty::Array( + tcx.types.usize, + Const::from_usize(tcx, num_variants as u64), + )); + + let size_array_local = local_decls.push(LocalDecl::new(tmp_ty, span)); + let store_live = Statement { + source_info, + kind: StatementKind::StorageLive(size_array_local), + }; + + let place = Place::from(size_array_local); + let constant_vals = Constant { + span, + user_ty: None, + literal: ConstantKind::Val( + interpret::ConstValue::ByRef { alloc, offset: Size::ZERO }, + tmp_ty, + ), + }; + let rval = Rvalue::Use(Operand::Constant(box (constant_vals))); + + let const_assign = + Statement { source_info, kind: StatementKind::Assign(box (place, rval)) }; + + let discr_place = Place::from( + local_decls + .push(LocalDecl::new(adt_def.repr().discr_type().to_ty(tcx), span)), + ); + + let store_discr = Statement { + source_info, + kind: StatementKind::Assign(box (discr_place, Rvalue::Discriminant(*rhs))), + }; + + let discr_cast_place = + Place::from(local_decls.push(LocalDecl::new(tcx.types.usize, span))); + + let cast_discr = Statement { + source_info, + kind: StatementKind::Assign(box ( + discr_cast_place, + Rvalue::Cast( + CastKind::Misc, + Operand::Copy(discr_place), + tcx.types.usize, + ), + )), + }; + + let size_place = + Place::from(local_decls.push(LocalDecl::new(tcx.types.usize, span))); + + let store_size = Statement { + source_info, + kind: StatementKind::Assign(box ( + size_place, + Rvalue::Use(Operand::Copy(Place { + local: size_array_local, + projection: tcx.intern_place_elems(&[PlaceElem::Index( + discr_cast_place.local, + )]), + })), + )), + }; + + let dst = + Place::from(local_decls.push(LocalDecl::new(tcx.mk_mut_ptr(ty), span))); + + let dst_ptr = Statement { + source_info, + kind: StatementKind::Assign(box ( + dst, + Rvalue::AddressOf(Mutability::Mut, *lhs), + )), + }; + + let dst_cast_ty = tcx.mk_mut_ptr(tcx.types.u8); + let dst_cast_place = + Place::from(local_decls.push(LocalDecl::new(dst_cast_ty, span))); + + let dst_cast = Statement { + source_info, + kind: StatementKind::Assign(box ( + dst_cast_place, + Rvalue::Cast(CastKind::Misc, Operand::Copy(dst), dst_cast_ty), + )), + }; + + let src = + Place::from(local_decls.push(LocalDecl::new(tcx.mk_imm_ptr(ty), span))); + + let src_ptr = Statement { + source_info, + kind: StatementKind::Assign(box ( + src, + Rvalue::AddressOf(Mutability::Not, *rhs), + )), + }; + + let src_cast_ty = tcx.mk_imm_ptr(tcx.types.u8); + let src_cast_place = + Place::from(local_decls.push(LocalDecl::new(src_cast_ty, span))); + + let src_cast = Statement { + source_info, + kind: StatementKind::Assign(box ( + src_cast_place, + Rvalue::Cast(CastKind::Misc, Operand::Copy(src), src_cast_ty), + )), + }; + + let copy_bytes = Statement { + source_info, + kind: StatementKind::CopyNonOverlapping(box CopyNonOverlapping { + src: Operand::Copy(src_cast_place), + dst: Operand::Copy(dst_cast_place), + count: Operand::Copy(size_place), + }), + }; + + let store_dead = Statement { + source_info, + kind: StatementKind::StorageDead(size_array_local), + }; + let iter = [ + store_live, + const_assign, + store_discr, + cast_discr, + store_size, + dst_ptr, + dst_cast, + src_ptr, + src_cast, + copy_bytes, + store_dead, + ] + .into_iter(); + + st.make_nop(); + Some(iter) + } else { + None + } + }); + } + } +} diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 00ec4b3e75457..8cd268eb6ce13 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -3,7 +3,6 @@ #![feature(drain_filter)] #![feature(let_chains)] #![feature(let_else)] -#![feature(entry_insert)] #![feature(map_try_insert)] #![feature(min_specialization)] #![feature(never_type)] @@ -75,6 +74,7 @@ mod function_item_references; mod generator; mod inline; mod instcombine; +mod large_enums; mod lower_intrinsics; mod lower_slice_len; mod match_branches; @@ -547,6 +547,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { tcx, body, &[ + &large_enums::EnumSizeOpt { discrepancy: 128 }, &reveal_all::RevealAll, // has to be done before inlining, since inlined code is in RevealAll mode. &lower_slice_len::LowerSliceLenCalls, // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first &unreachable_prop::UnreachablePropagation, diff --git a/tests/codegen/consts.rs b/tests/codegen/consts.rs index 9d75356b03dc9..260d9de867087 100644 --- a/tests/codegen/consts.rs +++ b/tests/codegen/consts.rs @@ -1,4 +1,4 @@ -// compile-flags: -C no-prepopulate-passes -Zmir-opt-level=0 +// compile-flags: -C no-prepopulate-passes // min-llvm-version: 14.0 #![crate_type = "lib"] diff --git a/tests/codegen/function-arguments.rs b/tests/codegen/function-arguments.rs index 020d9234e57cc..96dfde18683e3 100644 --- a/tests/codegen/function-arguments.rs +++ b/tests/codegen/function-arguments.rs @@ -1,4 +1,4 @@ -// compile-flags: -O -C no-prepopulate-passes -Zmir-opt-level=0 +// compile-flags: -O -C no-prepopulate-passes #![crate_type = "lib"] diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff new file mode 100644 index 0000000000000..d9923ec7cba7d --- /dev/null +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff @@ -0,0 +1,55 @@ +- // MIR for `cand` before EnumSizeOpt ++ // MIR for `cand` after EnumSizeOpt + + fn cand() -> () { + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:49:15: 49:15 + let mut _1: Candidate; // in scope 0 at $DIR/enum_opt.rs:50:7: 50:12 + let mut _2: Candidate; // in scope 0 at $DIR/enum_opt.rs:51:7: 51:34 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:51:24: 51:33 ++ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 ++ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 ++ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 ++ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 ++ let mut _8: *mut Candidate; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 ++ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 ++ let mut _10: *const Candidate; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 ++ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 + scope 1 { + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:50:7: 50:12 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:50:7: 50:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:50:15: 50:34 + ((_1 as Small).0: u8) = const 1_u8; // scope 0 at $DIR/enum_opt.rs:50:15: 50:34 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:50:15: 50:34 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:51:24: 51:33 + _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:51:24: 51:33 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:51:33: 51:34 +- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _4 = const [2_usize, 8196_usize]; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:51:33: 51:34 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:49:15: 52:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:52:1: 52:2 + return; // scope 0 at $DIR/enum_opt.rs:52:2: 52:2 + } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/enum_opt.rs:49:1: 52:2 + } + } + diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff new file mode 100644 index 0000000000000..e79d2f67a8398 --- /dev/null +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff @@ -0,0 +1,55 @@ +- // MIR for `cand` before EnumSizeOpt ++ // MIR for `cand` after EnumSizeOpt + + fn cand() -> () { + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:49:15: 49:15 + let mut _1: Candidate; // in scope 0 at $DIR/enum_opt.rs:50:7: 50:12 + let mut _2: Candidate; // in scope 0 at $DIR/enum_opt.rs:51:7: 51:34 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:51:24: 51:33 ++ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 ++ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 ++ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 ++ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 ++ let mut _8: *mut Candidate; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 ++ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 ++ let mut _10: *const Candidate; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 ++ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 + scope 1 { + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:50:7: 50:12 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:50:7: 50:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:50:15: 50:34 + ((_1 as Small).0: u8) = const 1_u8; // scope 0 at $DIR/enum_opt.rs:50:15: 50:34 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:50:15: 50:34 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:51:24: 51:33 + _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:51:24: 51:33 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:51:33: 51:34 +- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _4 = const [2_usize, 8200_usize]; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 ++ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:51:33: 51:34 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:49:15: 52:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:52:1: 52:2 + return; // scope 0 at $DIR/enum_opt.rs:52:2: 52:2 + } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/enum_opt.rs:49:1: 52:2 + } + } + diff --git a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff new file mode 100644 index 0000000000000..d8b6a79401518 --- /dev/null +++ b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff @@ -0,0 +1,35 @@ +- // MIR for `invalid` before EnumSizeOpt ++ // MIR for `invalid` after EnumSizeOpt + + fn invalid() -> () { + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:55:18: 55:18 + let mut _1: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:56:7: 56:12 + let mut _2: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:57:7: 57:36 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:57:26: 57:35 + scope 1 { + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:56:7: 56:12 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:56:7: 56:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:56:15: 56:29 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:56:15: 56:29 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:57:26: 57:35 + _3 = [const 0_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:57:26: 57:35 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:57:35: 57:36 + _1 = move _2; // scope 1 at $DIR/enum_opt.rs:57:3: 57:36 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:57:35: 57:36 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:55:18: 58:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:58:1: 58:2 + return; // scope 0 at $DIR/enum_opt.rs:58:2: 58:2 + } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/enum_opt.rs:55:1: 58:2 + } + } + diff --git a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff new file mode 100644 index 0000000000000..d8b6a79401518 --- /dev/null +++ b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff @@ -0,0 +1,35 @@ +- // MIR for `invalid` before EnumSizeOpt ++ // MIR for `invalid` after EnumSizeOpt + + fn invalid() -> () { + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:55:18: 55:18 + let mut _1: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:56:7: 56:12 + let mut _2: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:57:7: 57:36 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:57:26: 57:35 + scope 1 { + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:56:7: 56:12 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:56:7: 56:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:56:15: 56:29 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:56:15: 56:29 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:57:26: 57:35 + _3 = [const 0_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:57:26: 57:35 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:57:35: 57:36 + _1 = move _2; // scope 1 at $DIR/enum_opt.rs:57:3: 57:36 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:57:35: 57:36 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:55:18: 58:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:58:1: 58:2 + return; // scope 0 at $DIR/enum_opt.rs:58:2: 58:2 + } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/enum_opt.rs:55:1: 58:2 + } + } + diff --git a/tests/mir-opt/enum_opt.rs b/tests/mir-opt/enum_opt.rs new file mode 100644 index 0000000000000..bc72c93da09f3 --- /dev/null +++ b/tests/mir-opt/enum_opt.rs @@ -0,0 +1,79 @@ +// EMIT_MIR_FOR_EACH_BIT_WIDTH +// compile-flags: -Zunsound-mir-opts -Zmir-opt-level=3 +#![feature(arbitrary_enum_discriminant, repr128)] + +// Tests that an enum with a variant with no data gets correctly transformed. +pub enum NoData { + None, + Large([u64; 1024]), +} + +// Tests that an enum with a variant with data that is a valid candidate gets transformed. +pub enum Candidate { + Small(u8), + Large([u64; 1024]), +} + +// Tests that an enum which has a discriminant much higher than the variant does not get +// tformed. +#[repr(u32)] +pub enum InvalidIdxs { + A = 302, + Large([u64; 1024]), +} + +// Tests that an enum with too high of a discriminant index (not in bounds of usize) does not +// get tformed. +#[repr(u128)] +pub enum Truncatable { + A = 0, + B([u8; 1024]) = 1, + C([u8; 4096]) = 0x10000000000000001, +} + +// Tests that an enum with discriminants in random order still gets tformed correctly. +#[repr(u32)] +pub enum RandOrderDiscr { + A = 13, + B([u8; 1024]) = 5, + C = 7, +} + +// EMIT_MIR enum_opt.unin.EnumSizeOpt.diff +pub fn unin() { + let mut a = NoData::None; + a = NoData::Large([1; 1024]); +} + +// EMIT_MIR enum_opt.cand.EnumSizeOpt.diff +pub fn cand() { + let mut a = Candidate::Small(1); + a = Candidate::Large([1; 1024]); +} + +// EMIT_MIR enum_opt.invalid.EnumSizeOpt.diff +pub fn invalid() { + let mut a = InvalidIdxs::A; + a = InvalidIdxs::Large([0; 1024]); +} + +// EMIT_MIR enum_opt.trunc.EnumSizeOpt.diff +pub fn trunc() { + let mut a = Truncatable::A; + a = Truncatable::B([0; 1024]); + a = Truncatable::C([0; 4096]); +} + +pub fn rand_order() { + let mut a = RandOrderDiscr::A; + a = RandOrderDiscr::B([0; 1024]); + a = RandOrderDiscr::C; +} + +pub fn main() { + unin(); + cand(); + invalid(); + trunc(); + rand_order(); +} diff --git a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff new file mode 100644 index 0000000000000..650c6695f3f00 --- /dev/null +++ b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff @@ -0,0 +1,46 @@ +- // MIR for `trunc` before EnumSizeOpt ++ // MIR for `trunc` after EnumSizeOpt + + fn trunc() -> () { + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:61:16: 61:16 + let mut _1: Truncatable; // in scope 0 at $DIR/enum_opt.rs:62:7: 62:12 + let mut _2: Truncatable; // in scope 0 at $DIR/enum_opt.rs:63:7: 63:32 + let mut _3: [u8; 1024]; // in scope 0 at $DIR/enum_opt.rs:63:22: 63:31 + let mut _4: Truncatable; // in scope 0 at $DIR/enum_opt.rs:64:7: 64:32 + let mut _5: [u8; 4096]; // in scope 0 at $DIR/enum_opt.rs:64:22: 64:31 + scope 1 { + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:62:7: 62:12 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:62:7: 62:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:62:15: 62:29 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:62:15: 62:29 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:63:22: 63:31 + _3 = [const 0_u8; 1024]; // scope 1 at $DIR/enum_opt.rs:63:22: 63:31 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 + ((_2 as B).0: [u8; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:63:31: 63:32 + _1 = move _2; // scope 1 at $DIR/enum_opt.rs:63:3: 63:32 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:63:31: 63:32 + StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + StorageLive(_5); // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 + _5 = [const 0_u8; 4096]; // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 + Deinit(_4); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + ((_4 as C).0: [u8; 4096]) = move _5; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + discriminant(_4) = 2; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + StorageDead(_5); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 + _1 = move _4; // scope 1 at $DIR/enum_opt.rs:64:3: 64:32 + StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:61:16: 65:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:65:1: 65:2 + return; // scope 0 at $DIR/enum_opt.rs:65:2: 65:2 + } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/enum_opt.rs:61:1: 65:2 + } + } + diff --git a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff new file mode 100644 index 0000000000000..650c6695f3f00 --- /dev/null +++ b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff @@ -0,0 +1,46 @@ +- // MIR for `trunc` before EnumSizeOpt ++ // MIR for `trunc` after EnumSizeOpt + + fn trunc() -> () { + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:61:16: 61:16 + let mut _1: Truncatable; // in scope 0 at $DIR/enum_opt.rs:62:7: 62:12 + let mut _2: Truncatable; // in scope 0 at $DIR/enum_opt.rs:63:7: 63:32 + let mut _3: [u8; 1024]; // in scope 0 at $DIR/enum_opt.rs:63:22: 63:31 + let mut _4: Truncatable; // in scope 0 at $DIR/enum_opt.rs:64:7: 64:32 + let mut _5: [u8; 4096]; // in scope 0 at $DIR/enum_opt.rs:64:22: 64:31 + scope 1 { + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:62:7: 62:12 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:62:7: 62:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:62:15: 62:29 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:62:15: 62:29 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:63:22: 63:31 + _3 = [const 0_u8; 1024]; // scope 1 at $DIR/enum_opt.rs:63:22: 63:31 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 + ((_2 as B).0: [u8; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:63:31: 63:32 + _1 = move _2; // scope 1 at $DIR/enum_opt.rs:63:3: 63:32 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:63:31: 63:32 + StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + StorageLive(_5); // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 + _5 = [const 0_u8; 4096]; // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 + Deinit(_4); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + ((_4 as C).0: [u8; 4096]) = move _5; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + discriminant(_4) = 2; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + StorageDead(_5); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 + _1 = move _4; // scope 1 at $DIR/enum_opt.rs:64:3: 64:32 + StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:61:16: 65:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:65:1: 65:2 + return; // scope 0 at $DIR/enum_opt.rs:65:2: 65:2 + } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/enum_opt.rs:61:1: 65:2 + } + } + diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff new file mode 100644 index 0000000000000..c034c127ecad0 --- /dev/null +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff @@ -0,0 +1,54 @@ +- // MIR for `unin` before EnumSizeOpt ++ // MIR for `unin` after EnumSizeOpt + + fn unin() -> () { + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:43:15: 43:15 + let mut _1: NoData; // in scope 0 at $DIR/enum_opt.rs:44:7: 44:12 + let mut _2: NoData; // in scope 0 at $DIR/enum_opt.rs:45:7: 45:31 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:45:21: 45:30 ++ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 ++ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 ++ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 ++ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 ++ let mut _8: *mut NoData; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 ++ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 ++ let mut _10: *const NoData; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 ++ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 + scope 1 { + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:44:7: 44:12 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:44:7: 44:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:44:15: 44:27 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:44:15: 44:27 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:45:21: 45:30 + _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:45:21: 45:30 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:45:30: 45:31 +- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _4 = const [4_usize, 8196_usize]; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:45:30: 45:31 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:43:15: 46:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:46:1: 46:2 + return; // scope 0 at $DIR/enum_opt.rs:46:2: 46:2 + } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/enum_opt.rs:43:1: 46:2 + } + } + diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff new file mode 100644 index 0000000000000..9389c0f12a048 --- /dev/null +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff @@ -0,0 +1,54 @@ +- // MIR for `unin` before EnumSizeOpt ++ // MIR for `unin` after EnumSizeOpt + + fn unin() -> () { + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:43:15: 43:15 + let mut _1: NoData; // in scope 0 at $DIR/enum_opt.rs:44:7: 44:12 + let mut _2: NoData; // in scope 0 at $DIR/enum_opt.rs:45:7: 45:31 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:45:21: 45:30 ++ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 ++ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 ++ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 ++ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 ++ let mut _8: *mut NoData; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 ++ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 ++ let mut _10: *const NoData; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 ++ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 + scope 1 { + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:44:7: 44:12 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:44:7: 44:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:44:15: 44:27 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:44:15: 44:27 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:45:21: 45:30 + _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:45:21: 45:30 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:45:30: 45:31 +- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _4 = const [8_usize, 8200_usize]; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 ++ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:45:30: 45:31 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:43:15: 46:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:46:1: 46:2 + return; // scope 0 at $DIR/enum_opt.rs:46:2: 46:2 + } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/enum_opt.rs:43:1: 46:2 + } + } + From 610e1a1e05e7160d775f433855138f6063169c56 Mon Sep 17 00:00:00 2001 From: kadmin Date: Tue, 19 Apr 2022 15:39:49 +0000 Subject: [PATCH 7/9] Add tag for ignoring wasm --- .../enum_opt.cand.EnumSizeOpt.32bit.diff | 82 +++++++++---------- .../enum_opt.cand.EnumSizeOpt.64bit.diff | 82 +++++++++---------- .../enum_opt.invalid.EnumSizeOpt.32bit.diff | 42 +++++----- .../enum_opt.invalid.EnumSizeOpt.64bit.diff | 42 +++++----- tests/mir-opt/enum_opt.rs | 1 + .../enum_opt.trunc.EnumSizeOpt.32bit.diff | 64 +++++++-------- .../enum_opt.trunc.EnumSizeOpt.64bit.diff | 64 +++++++-------- .../enum_opt.unin.EnumSizeOpt.32bit.diff | 80 +++++++++--------- .../enum_opt.unin.EnumSizeOpt.64bit.diff | 80 +++++++++--------- 9 files changed, 269 insertions(+), 268 deletions(-) diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff index d9923ec7cba7d..859fddd65c1ae 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff @@ -2,54 +2,54 @@ + // MIR for `cand` after EnumSizeOpt fn cand() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:49:15: 49:15 - let mut _1: Candidate; // in scope 0 at $DIR/enum_opt.rs:50:7: 50:12 - let mut _2: Candidate; // in scope 0 at $DIR/enum_opt.rs:51:7: 51:34 - let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:51:24: 51:33 -+ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 -+ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 -+ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 -+ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 -+ let mut _8: *mut Candidate; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 -+ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 -+ let mut _10: *const Candidate; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 -+ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:50:15: 50:15 + let mut _1: Candidate; // in scope 0 at $DIR/enum_opt.rs:51:7: 51:12 + let mut _2: Candidate; // in scope 0 at $DIR/enum_opt.rs:52:7: 52:34 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:52:24: 52:33 ++ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 ++ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 ++ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 ++ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 ++ let mut _8: *mut Candidate; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 ++ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 ++ let mut _10: *const Candidate; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 ++ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:50:7: 50:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:51:7: 51:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:50:7: 50:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:50:15: 50:34 - ((_1 as Small).0: u8) = const 1_u8; // scope 0 at $DIR/enum_opt.rs:50:15: 50:34 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:50:15: 50:34 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:51:24: 51:33 - _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:51:24: 51:33 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:51:33: 51:34 -- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _4 = const [2_usize, 8196_usize]; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:51:33: 51:34 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:49:15: 52:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:52:1: 52:2 - return; // scope 0 at $DIR/enum_opt.rs:52:2: 52:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:51:7: 51:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:51:15: 51:34 + ((_1 as Small).0: u8) = const 1_u8; // scope 0 at $DIR/enum_opt.rs:51:15: 51:34 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:51:15: 51:34 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:52:24: 52:33 + _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:52:24: 52:33 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:52:33: 52:34 +- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _4 = const [2_usize, 8196_usize]; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:52:33: 52:34 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:50:15: 53:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:53:1: 53:2 + return; // scope 0 at $DIR/enum_opt.rs:53:2: 53:2 } bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:49:1: 52:2 + resume; // scope 0 at $DIR/enum_opt.rs:50:1: 53:2 } } diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff index e79d2f67a8398..c3325f2d81f6e 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff @@ -2,54 +2,54 @@ + // MIR for `cand` after EnumSizeOpt fn cand() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:49:15: 49:15 - let mut _1: Candidate; // in scope 0 at $DIR/enum_opt.rs:50:7: 50:12 - let mut _2: Candidate; // in scope 0 at $DIR/enum_opt.rs:51:7: 51:34 - let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:51:24: 51:33 -+ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 -+ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 -+ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 -+ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 -+ let mut _8: *mut Candidate; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 -+ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 -+ let mut _10: *const Candidate; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 -+ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:51:3: 51:34 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:50:15: 50:15 + let mut _1: Candidate; // in scope 0 at $DIR/enum_opt.rs:51:7: 51:12 + let mut _2: Candidate; // in scope 0 at $DIR/enum_opt.rs:52:7: 52:34 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:52:24: 52:33 ++ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 ++ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 ++ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 ++ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 ++ let mut _8: *mut Candidate; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 ++ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 ++ let mut _10: *const Candidate; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 ++ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:50:7: 50:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:51:7: 51:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:50:7: 50:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:50:15: 50:34 - ((_1 as Small).0: u8) = const 1_u8; // scope 0 at $DIR/enum_opt.rs:50:15: 50:34 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:50:15: 50:34 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:51:24: 51:33 - _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:51:24: 51:33 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:51:7: 51:34 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:51:33: 51:34 -- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _4 = const [2_usize, 8200_usize]; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 -+ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:51:3: 51:34 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:51:33: 51:34 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:49:15: 52:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:52:1: 52:2 - return; // scope 0 at $DIR/enum_opt.rs:52:2: 52:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:51:7: 51:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:51:15: 51:34 + ((_1 as Small).0: u8) = const 1_u8; // scope 0 at $DIR/enum_opt.rs:51:15: 51:34 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:51:15: 51:34 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:52:24: 52:33 + _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:52:24: 52:33 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:52:33: 52:34 +- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _4 = const [2_usize, 8200_usize]; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 ++ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:52:33: 52:34 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:50:15: 53:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:53:1: 53:2 + return; // scope 0 at $DIR/enum_opt.rs:53:2: 53:2 } bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:49:1: 52:2 + resume; // scope 0 at $DIR/enum_opt.rs:50:1: 53:2 } } diff --git a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff index d8b6a79401518..bc16a780683af 100644 --- a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff @@ -2,34 +2,34 @@ + // MIR for `invalid` after EnumSizeOpt fn invalid() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:55:18: 55:18 - let mut _1: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:56:7: 56:12 - let mut _2: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:57:7: 57:36 - let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:57:26: 57:35 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:56:18: 56:18 + let mut _1: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:57:7: 57:12 + let mut _2: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:58:7: 58:36 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:58:26: 58:35 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:56:7: 56:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:57:7: 57:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:56:7: 56:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:56:15: 56:29 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:56:15: 56:29 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:57:26: 57:35 - _3 = [const 0_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:57:26: 57:35 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:57:35: 57:36 - _1 = move _2; // scope 1 at $DIR/enum_opt.rs:57:3: 57:36 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:57:35: 57:36 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:55:18: 58:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:58:1: 58:2 - return; // scope 0 at $DIR/enum_opt.rs:58:2: 58:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:57:7: 57:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:57:15: 57:29 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:57:15: 57:29 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:58:26: 58:35 + _3 = [const 0_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:58:26: 58:35 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:58:35: 58:36 + _1 = move _2; // scope 1 at $DIR/enum_opt.rs:58:3: 58:36 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:58:35: 58:36 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:56:18: 59:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:59:1: 59:2 + return; // scope 0 at $DIR/enum_opt.rs:59:2: 59:2 } bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:55:1: 58:2 + resume; // scope 0 at $DIR/enum_opt.rs:56:1: 59:2 } } diff --git a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff index d8b6a79401518..bc16a780683af 100644 --- a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff @@ -2,34 +2,34 @@ + // MIR for `invalid` after EnumSizeOpt fn invalid() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:55:18: 55:18 - let mut _1: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:56:7: 56:12 - let mut _2: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:57:7: 57:36 - let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:57:26: 57:35 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:56:18: 56:18 + let mut _1: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:57:7: 57:12 + let mut _2: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:58:7: 58:36 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:58:26: 58:35 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:56:7: 56:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:57:7: 57:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:56:7: 56:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:56:15: 56:29 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:56:15: 56:29 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:57:26: 57:35 - _3 = [const 0_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:57:26: 57:35 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:57:7: 57:36 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:57:35: 57:36 - _1 = move _2; // scope 1 at $DIR/enum_opt.rs:57:3: 57:36 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:57:35: 57:36 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:55:18: 58:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:58:1: 58:2 - return; // scope 0 at $DIR/enum_opt.rs:58:2: 58:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:57:7: 57:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:57:15: 57:29 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:57:15: 57:29 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:58:26: 58:35 + _3 = [const 0_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:58:26: 58:35 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:58:35: 58:36 + _1 = move _2; // scope 1 at $DIR/enum_opt.rs:58:3: 58:36 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:58:35: 58:36 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:56:18: 59:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:59:1: 59:2 + return; // scope 0 at $DIR/enum_opt.rs:59:2: 59:2 } bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:55:1: 58:2 + resume; // scope 0 at $DIR/enum_opt.rs:56:1: 59:2 } } diff --git a/tests/mir-opt/enum_opt.rs b/tests/mir-opt/enum_opt.rs index bc72c93da09f3..65f77af0592ea 100644 --- a/tests/mir-opt/enum_opt.rs +++ b/tests/mir-opt/enum_opt.rs @@ -1,5 +1,6 @@ // EMIT_MIR_FOR_EACH_BIT_WIDTH // compile-flags: -Zunsound-mir-opts -Zmir-opt-level=3 +// ignore-wasm32-bare compiled with panic=abort by default #![feature(arbitrary_enum_discriminant, repr128)] // Tests that an enum with a variant with no data gets correctly transformed. diff --git a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff index 650c6695f3f00..654e385bfe785 100644 --- a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff @@ -2,45 +2,45 @@ + // MIR for `trunc` after EnumSizeOpt fn trunc() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:61:16: 61:16 - let mut _1: Truncatable; // in scope 0 at $DIR/enum_opt.rs:62:7: 62:12 - let mut _2: Truncatable; // in scope 0 at $DIR/enum_opt.rs:63:7: 63:32 - let mut _3: [u8; 1024]; // in scope 0 at $DIR/enum_opt.rs:63:22: 63:31 - let mut _4: Truncatable; // in scope 0 at $DIR/enum_opt.rs:64:7: 64:32 - let mut _5: [u8; 4096]; // in scope 0 at $DIR/enum_opt.rs:64:22: 64:31 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:62:16: 62:16 + let mut _1: Truncatable; // in scope 0 at $DIR/enum_opt.rs:63:7: 63:12 + let mut _2: Truncatable; // in scope 0 at $DIR/enum_opt.rs:64:7: 64:32 + let mut _3: [u8; 1024]; // in scope 0 at $DIR/enum_opt.rs:64:22: 64:31 + let mut _4: Truncatable; // in scope 0 at $DIR/enum_opt.rs:65:7: 65:32 + let mut _5: [u8; 4096]; // in scope 0 at $DIR/enum_opt.rs:65:22: 65:31 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:62:7: 62:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:63:7: 63:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:62:7: 62:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:62:15: 62:29 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:62:15: 62:29 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:63:22: 63:31 - _3 = [const 0_u8; 1024]; // scope 1 at $DIR/enum_opt.rs:63:22: 63:31 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 - ((_2 as B).0: [u8; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:63:31: 63:32 - _1 = move _2; // scope 1 at $DIR/enum_opt.rs:63:3: 63:32 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:63:31: 63:32 - StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - StorageLive(_5); // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 - _5 = [const 0_u8; 4096]; // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 - Deinit(_4); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - ((_4 as C).0: [u8; 4096]) = move _5; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - discriminant(_4) = 2; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - StorageDead(_5); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 - _1 = move _4; // scope 1 at $DIR/enum_opt.rs:64:3: 64:32 - StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:61:16: 65:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:65:1: 65:2 - return; // scope 0 at $DIR/enum_opt.rs:65:2: 65:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:63:7: 63:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:63:15: 63:29 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:63:15: 63:29 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 + _3 = [const 0_u8; 1024]; // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + ((_2 as B).0: [u8; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 + _1 = move _2; // scope 1 at $DIR/enum_opt.rs:64:3: 64:32 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 + StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 + StorageLive(_5); // scope 1 at $DIR/enum_opt.rs:65:22: 65:31 + _5 = [const 0_u8; 4096]; // scope 1 at $DIR/enum_opt.rs:65:22: 65:31 + Deinit(_4); // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 + ((_4 as C).0: [u8; 4096]) = move _5; // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 + discriminant(_4) = 2; // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 + StorageDead(_5); // scope 1 at $DIR/enum_opt.rs:65:31: 65:32 + _1 = move _4; // scope 1 at $DIR/enum_opt.rs:65:3: 65:32 + StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:65:31: 65:32 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:62:16: 66:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:66:1: 66:2 + return; // scope 0 at $DIR/enum_opt.rs:66:2: 66:2 } bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:61:1: 65:2 + resume; // scope 0 at $DIR/enum_opt.rs:62:1: 66:2 } } diff --git a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff index 650c6695f3f00..654e385bfe785 100644 --- a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff @@ -2,45 +2,45 @@ + // MIR for `trunc` after EnumSizeOpt fn trunc() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:61:16: 61:16 - let mut _1: Truncatable; // in scope 0 at $DIR/enum_opt.rs:62:7: 62:12 - let mut _2: Truncatable; // in scope 0 at $DIR/enum_opt.rs:63:7: 63:32 - let mut _3: [u8; 1024]; // in scope 0 at $DIR/enum_opt.rs:63:22: 63:31 - let mut _4: Truncatable; // in scope 0 at $DIR/enum_opt.rs:64:7: 64:32 - let mut _5: [u8; 4096]; // in scope 0 at $DIR/enum_opt.rs:64:22: 64:31 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:62:16: 62:16 + let mut _1: Truncatable; // in scope 0 at $DIR/enum_opt.rs:63:7: 63:12 + let mut _2: Truncatable; // in scope 0 at $DIR/enum_opt.rs:64:7: 64:32 + let mut _3: [u8; 1024]; // in scope 0 at $DIR/enum_opt.rs:64:22: 64:31 + let mut _4: Truncatable; // in scope 0 at $DIR/enum_opt.rs:65:7: 65:32 + let mut _5: [u8; 4096]; // in scope 0 at $DIR/enum_opt.rs:65:22: 65:31 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:62:7: 62:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:63:7: 63:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:62:7: 62:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:62:15: 62:29 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:62:15: 62:29 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:63:22: 63:31 - _3 = [const 0_u8; 1024]; // scope 1 at $DIR/enum_opt.rs:63:22: 63:31 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 - ((_2 as B).0: [u8; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:63:7: 63:32 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:63:31: 63:32 - _1 = move _2; // scope 1 at $DIR/enum_opt.rs:63:3: 63:32 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:63:31: 63:32 - StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - StorageLive(_5); // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 - _5 = [const 0_u8; 4096]; // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 - Deinit(_4); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - ((_4 as C).0: [u8; 4096]) = move _5; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - discriminant(_4) = 2; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - StorageDead(_5); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 - _1 = move _4; // scope 1 at $DIR/enum_opt.rs:64:3: 64:32 - StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:61:16: 65:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:65:1: 65:2 - return; // scope 0 at $DIR/enum_opt.rs:65:2: 65:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:63:7: 63:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:63:15: 63:29 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:63:15: 63:29 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 + _3 = [const 0_u8; 1024]; // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + ((_2 as B).0: [u8; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 + _1 = move _2; // scope 1 at $DIR/enum_opt.rs:64:3: 64:32 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 + StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 + StorageLive(_5); // scope 1 at $DIR/enum_opt.rs:65:22: 65:31 + _5 = [const 0_u8; 4096]; // scope 1 at $DIR/enum_opt.rs:65:22: 65:31 + Deinit(_4); // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 + ((_4 as C).0: [u8; 4096]) = move _5; // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 + discriminant(_4) = 2; // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 + StorageDead(_5); // scope 1 at $DIR/enum_opt.rs:65:31: 65:32 + _1 = move _4; // scope 1 at $DIR/enum_opt.rs:65:3: 65:32 + StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:65:31: 65:32 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:62:16: 66:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:66:1: 66:2 + return; // scope 0 at $DIR/enum_opt.rs:66:2: 66:2 } bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:61:1: 65:2 + resume; // scope 0 at $DIR/enum_opt.rs:62:1: 66:2 } } diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff index c034c127ecad0..bc72e507d5ab7 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff @@ -2,53 +2,53 @@ + // MIR for `unin` after EnumSizeOpt fn unin() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:43:15: 43:15 - let mut _1: NoData; // in scope 0 at $DIR/enum_opt.rs:44:7: 44:12 - let mut _2: NoData; // in scope 0 at $DIR/enum_opt.rs:45:7: 45:31 - let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:45:21: 45:30 -+ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 -+ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 -+ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 -+ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 -+ let mut _8: *mut NoData; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 -+ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 -+ let mut _10: *const NoData; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 -+ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:44:15: 44:15 + let mut _1: NoData; // in scope 0 at $DIR/enum_opt.rs:45:7: 45:12 + let mut _2: NoData; // in scope 0 at $DIR/enum_opt.rs:46:7: 46:31 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:46:21: 46:30 ++ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 ++ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 ++ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 ++ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 ++ let mut _8: *mut NoData; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 ++ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 ++ let mut _10: *const NoData; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 ++ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:44:7: 44:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:45:7: 45:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:44:7: 44:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:44:15: 44:27 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:44:15: 44:27 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:45:21: 45:30 - _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:45:21: 45:30 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:45:30: 45:31 -- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _4 = const [4_usize, 8196_usize]; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:45:30: 45:31 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:43:15: 46:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:46:1: 46:2 - return; // scope 0 at $DIR/enum_opt.rs:46:2: 46:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:45:7: 45:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:45:15: 45:27 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:45:15: 45:27 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:46:21: 46:30 + _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:46:21: 46:30 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:46:30: 46:31 +- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _4 = const [4_usize, 8196_usize]; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:46:30: 46:31 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:44:15: 47:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:47:1: 47:2 + return; // scope 0 at $DIR/enum_opt.rs:47:2: 47:2 } bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:43:1: 46:2 + resume; // scope 0 at $DIR/enum_opt.rs:44:1: 47:2 } } diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff index 9389c0f12a048..9001268dc2087 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff @@ -2,53 +2,53 @@ + // MIR for `unin` after EnumSizeOpt fn unin() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:43:15: 43:15 - let mut _1: NoData; // in scope 0 at $DIR/enum_opt.rs:44:7: 44:12 - let mut _2: NoData; // in scope 0 at $DIR/enum_opt.rs:45:7: 45:31 - let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:45:21: 45:30 -+ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 -+ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 -+ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 -+ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 -+ let mut _8: *mut NoData; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 -+ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 -+ let mut _10: *const NoData; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 -+ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:45:3: 45:31 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:44:15: 44:15 + let mut _1: NoData; // in scope 0 at $DIR/enum_opt.rs:45:7: 45:12 + let mut _2: NoData; // in scope 0 at $DIR/enum_opt.rs:46:7: 46:31 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:46:21: 46:30 ++ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 ++ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 ++ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 ++ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 ++ let mut _8: *mut NoData; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 ++ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 ++ let mut _10: *const NoData; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 ++ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:44:7: 44:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:45:7: 45:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:44:7: 44:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:44:15: 44:27 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:44:15: 44:27 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:45:21: 45:30 - _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:45:21: 45:30 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:45:7: 45:31 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:45:30: 45:31 -- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _4 = const [8_usize, 8200_usize]; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 -+ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:45:3: 45:31 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:45:30: 45:31 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:43:15: 46:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:46:1: 46:2 - return; // scope 0 at $DIR/enum_opt.rs:46:2: 46:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:45:7: 45:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:45:15: 45:27 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:45:15: 45:27 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:46:21: 46:30 + _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:46:21: 46:30 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:46:30: 46:31 +- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _4 = const [8_usize, 8200_usize]; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 ++ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:46:30: 46:31 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:44:15: 47:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:47:1: 47:2 + return; // scope 0 at $DIR/enum_opt.rs:47:2: 47:2 } bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:43:1: 46:2 + resume; // scope 0 at $DIR/enum_opt.rs:44:1: 47:2 } } From 15f4eec7a986e6c9125ff3e0115d70aef6d5c711 Mon Sep 17 00:00:00 2001 From: kadmin Date: Fri, 24 Jun 2022 08:48:07 +0000 Subject: [PATCH 8/9] Leave FIXME for wasm layout difference. There is a distinction between running this on wasm and i686, even though they should be identical. This technically is not _incorrect_, it's just an unexpected difference, which is worth investigating, but not for correctness. --- .../rustc_mir_transform/src/large_enums.rs | 42 ++++++---- compiler/rustc_mir_transform/src/lib.rs | 2 +- .../enum_opt.cand.EnumSizeOpt.32bit.diff | 84 +++++++++---------- .../enum_opt.cand.EnumSizeOpt.64bit.diff | 84 +++++++++---------- .../enum_opt.invalid.EnumSizeOpt.32bit.diff | 44 +++++----- .../enum_opt.invalid.EnumSizeOpt.64bit.diff | 44 +++++----- tests/mir-opt/enum_opt.rs | 16 ++-- .../enum_opt.trunc.EnumSizeOpt.32bit.diff | 66 +++++++-------- .../enum_opt.trunc.EnumSizeOpt.64bit.diff | 66 +++++++-------- .../enum_opt.unin.EnumSizeOpt.32bit.diff | 82 +++++++++--------- .../enum_opt.unin.EnumSizeOpt.64bit.diff | 82 +++++++++--------- 11 files changed, 297 insertions(+), 315 deletions(-) diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 1919720de4996..3f8662ad6971f 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -1,6 +1,6 @@ use crate::rustc_middle::ty::util::IntTypeExt; use crate::MirPass; -use rustc_data_structures::stable_map::FxHashMap; +use rustc_data_structures::fx::FxHashMap; use rustc_middle::mir::interpret::AllocId; use rustc_middle::mir::*; use rustc_middle::ty::{self, AdtDef, Const, ParamEnv, Ty, TyCtxt}; @@ -19,6 +19,10 @@ use rustc_target::abi::{HasDataLayout, Size, TagEncoding, Variants}; /// Instead of emitting moves of the large variant, /// Perform a memcpy instead. /// Based off of [this HackMD](https://hackmd.io/@ft4bxUsFT5CEUBmRKYHr7w/rJM8BBPzD). +/// +/// In summary, what this does is at runtime determine which enum variant is active, +/// and instead of copying all the bytes of the largest possible variant, +/// copy only the bytes for the currently active variant. pub struct EnumSizeOpt { pub(crate) discrepancy: u64, } @@ -26,7 +30,10 @@ pub struct EnumSizeOpt { impl<'tcx> MirPass<'tcx> for EnumSizeOpt { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let sess = tcx.sess; - if (!sess.opts.debugging_opts.unsound_mir_opts) || sess.mir_opt_level() < 3 { + // FIXME(julianknodt): one thing noticed while testing this mir-opt is that there is a + // different layout of large enums on wasm. It's not clear what is causing this layout + // difference, as it should be identical to i686 (32 bit). + if (!sess.opts.unstable_opts.unsound_mir_opts) || sess.mir_opt_level() < 3 { return; } self.optim(tcx, body); @@ -56,8 +63,8 @@ impl EnumSizeOpt { Variants::Multiple { variants, .. } if variants.len() <= 1 => return None, Variants::Multiple { variants, .. } => variants, }; - let min = variants.iter().map(|v| v.size()).min().unwrap(); - let max = variants.iter().map(|v| v.size()).max().unwrap(); + let min = variants.iter().map(|v| v.size).min().unwrap(); + let max = variants.iter().map(|v| v.size).max().unwrap(); if max.bytes() - min.bytes() < self.discrepancy { return None; } @@ -92,7 +99,7 @@ impl EnumSizeOpt { for (var_idx, layout) in variants.iter_enumerated() { let curr_idx = target_bytes * adt_def.discriminant_for_variant(tcx, var_idx).val as usize; - let sz = layout.size(); + let sz = layout.size; match ptr_sized_int { rustc_target::abi::Integer::I32 => { encode_store!(curr_idx, data_layout.endian, sz.bytes() as u32); @@ -115,8 +122,11 @@ impl EnumSizeOpt { let mut alloc_cache = FxHashMap::default(); let body_did = body.source.def_id(); let param_env = tcx.param_env(body_did); - let (bbs, local_decls) = body.basic_blocks_and_local_decls_mut(); - for bb in bbs { + + let blocks = body.basic_blocks.as_mut(); + let local_decls = &mut body.local_decls; + + for bb in blocks { bb.expand_statements(|st| { if let StatementKind::Assign(box ( lhs, @@ -175,7 +185,7 @@ impl EnumSizeOpt { kind: StatementKind::Assign(box ( discr_cast_place, Rvalue::Cast( - CastKind::Misc, + CastKind::IntToInt, Operand::Copy(discr_place), tcx.types.usize, ), @@ -217,7 +227,7 @@ impl EnumSizeOpt { source_info, kind: StatementKind::Assign(box ( dst_cast_place, - Rvalue::Cast(CastKind::Misc, Operand::Copy(dst), dst_cast_ty), + Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(dst), dst_cast_ty), )), }; @@ -240,17 +250,19 @@ impl EnumSizeOpt { source_info, kind: StatementKind::Assign(box ( src_cast_place, - Rvalue::Cast(CastKind::Misc, Operand::Copy(src), src_cast_ty), + Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(src), src_cast_ty), )), }; let copy_bytes = Statement { source_info, - kind: StatementKind::CopyNonOverlapping(box CopyNonOverlapping { - src: Operand::Copy(src_cast_place), - dst: Operand::Copy(dst_cast_place), - count: Operand::Copy(size_place), - }), + kind: StatementKind::Intrinsic( + box NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { + src: Operand::Copy(src_cast_place), + dst: Operand::Copy(dst_cast_place), + count: Operand::Copy(size_place), + }), + ), }; let store_dead = Statement { diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 8cd268eb6ce13..be3652dd3e7bd 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -1,8 +1,8 @@ #![allow(rustc::potential_query_instability)] #![feature(box_patterns)] #![feature(drain_filter)] +#![feature(box_syntax)] #![feature(let_chains)] -#![feature(let_else)] #![feature(map_try_insert)] #![feature(min_specialization)] #![feature(never_type)] diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff index 859fddd65c1ae..e0ba46c15f4a9 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff @@ -2,54 +2,50 @@ + // MIR for `cand` after EnumSizeOpt fn cand() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:50:15: 50:15 - let mut _1: Candidate; // in scope 0 at $DIR/enum_opt.rs:51:7: 51:12 - let mut _2: Candidate; // in scope 0 at $DIR/enum_opt.rs:52:7: 52:34 - let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:52:24: 52:33 -+ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 -+ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 -+ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 -+ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 -+ let mut _8: *mut Candidate; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 -+ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 -+ let mut _10: *const Candidate; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 -+ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:15: +0:15 + let mut _1: Candidate; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + let mut _2: Candidate; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:34 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:+2:24: +2:33 ++ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _8: *mut Candidate; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _10: *const Candidate; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:51:7: 51:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:+1:7: +1:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:51:7: 51:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:51:15: 51:34 - ((_1 as Small).0: u8) = const 1_u8; // scope 0 at $DIR/enum_opt.rs:51:15: 51:34 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:51:15: 51:34 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:52:24: 52:33 - _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:52:24: 52:33 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:52:33: 52:34 -- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _4 = const [2_usize, 8196_usize]; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:52:33: 52:34 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:50:15: 53:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:53:1: 53:2 - return; // scope 0 at $DIR/enum_opt.rs:53:2: 53:2 - } - - bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:50:1: 53:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:34 + ((_1 as Small).0: u8) = const 1_u8; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:34 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:34 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 + _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 +- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _4 = const [2_usize, 8196_usize]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _6 = _5 as usize (IntToInt); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _9 = _8 as *mut u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _11 = _10 as *const u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ copy_nonoverlapping(dst = _9, src = _11, count = _7); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:15: +3:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+3:1: +3:2 + return; // scope 0 at $DIR/enum_opt.rs:+3:2: +3:2 } } diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff index c3325f2d81f6e..67439dba9c947 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff @@ -2,54 +2,50 @@ + // MIR for `cand` after EnumSizeOpt fn cand() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:50:15: 50:15 - let mut _1: Candidate; // in scope 0 at $DIR/enum_opt.rs:51:7: 51:12 - let mut _2: Candidate; // in scope 0 at $DIR/enum_opt.rs:52:7: 52:34 - let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:52:24: 52:33 -+ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 -+ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 -+ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 -+ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 -+ let mut _8: *mut Candidate; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 -+ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 -+ let mut _10: *const Candidate; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 -+ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:52:3: 52:34 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:15: +0:15 + let mut _1: Candidate; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + let mut _2: Candidate; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:34 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:+2:24: +2:33 ++ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _8: *mut Candidate; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _10: *const Candidate; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:51:7: 51:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:+1:7: +1:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:51:7: 51:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:51:15: 51:34 - ((_1 as Small).0: u8) = const 1_u8; // scope 0 at $DIR/enum_opt.rs:51:15: 51:34 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:51:15: 51:34 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:52:24: 52:33 - _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:52:24: 52:33 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:52:7: 52:34 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:52:33: 52:34 -- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _4 = const [2_usize, 8200_usize]; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 -+ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:52:3: 52:34 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:52:33: 52:34 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:50:15: 53:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:53:1: 53:2 - return; // scope 0 at $DIR/enum_opt.rs:53:2: 53:2 - } - - bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:50:1: 53:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:34 + ((_1 as Small).0: u8) = const 1_u8; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:34 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:34 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 + _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 +- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _4 = const [2_usize, 8200_usize]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _6 = _5 as usize (IntToInt); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _9 = _8 as *mut u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _11 = _10 as *const u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ copy_nonoverlapping(dst = _9, src = _11, count = _7); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:15: +3:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+3:1: +3:2 + return; // scope 0 at $DIR/enum_opt.rs:+3:2: +3:2 } } diff --git a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff index bc16a780683af..db2efa195a369 100644 --- a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff @@ -2,34 +2,30 @@ + // MIR for `invalid` after EnumSizeOpt fn invalid() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:56:18: 56:18 - let mut _1: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:57:7: 57:12 - let mut _2: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:58:7: 58:36 - let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:58:26: 58:35 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:18: +0:18 + let mut _1: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + let mut _2: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:36 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:+2:26: +2:35 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:57:7: 57:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:+1:7: +1:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:57:7: 57:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:57:15: 57:29 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:57:15: 57:29 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:58:26: 58:35 - _3 = [const 0_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:58:26: 58:35 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:58:35: 58:36 - _1 = move _2; // scope 1 at $DIR/enum_opt.rs:58:3: 58:36 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:58:35: 58:36 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:56:18: 59:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:59:1: 59:2 - return; // scope 0 at $DIR/enum_opt.rs:59:2: 59:2 - } - - bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:56:1: 59:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:29 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:29 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:26: +2:35 + _3 = [const 0_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:+2:26: +2:35 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:35: +2:36 + _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:36 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:35: +2:36 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:18: +3:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+3:1: +3:2 + return; // scope 0 at $DIR/enum_opt.rs:+3:2: +3:2 } } diff --git a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff index bc16a780683af..db2efa195a369 100644 --- a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff @@ -2,34 +2,30 @@ + // MIR for `invalid` after EnumSizeOpt fn invalid() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:56:18: 56:18 - let mut _1: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:57:7: 57:12 - let mut _2: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:58:7: 58:36 - let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:58:26: 58:35 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:18: +0:18 + let mut _1: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + let mut _2: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:36 + let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:+2:26: +2:35 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:57:7: 57:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:+1:7: +1:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:57:7: 57:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:57:15: 57:29 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:57:15: 57:29 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:58:26: 58:35 - _3 = [const 0_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:58:26: 58:35 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:58:7: 58:36 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:58:35: 58:36 - _1 = move _2; // scope 1 at $DIR/enum_opt.rs:58:3: 58:36 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:58:35: 58:36 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:56:18: 59:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:59:1: 59:2 - return; // scope 0 at $DIR/enum_opt.rs:59:2: 59:2 - } - - bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:56:1: 59:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:29 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:29 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:26: +2:35 + _3 = [const 0_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:+2:26: +2:35 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 + ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:35: +2:36 + _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:36 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:35: +2:36 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:18: +3:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+3:1: +3:2 + return; // scope 0 at $DIR/enum_opt.rs:+3:2: +3:2 } } diff --git a/tests/mir-opt/enum_opt.rs b/tests/mir-opt/enum_opt.rs index 65f77af0592ea..6876c56cfa4ed 100644 --- a/tests/mir-opt/enum_opt.rs +++ b/tests/mir-opt/enum_opt.rs @@ -1,12 +1,14 @@ // EMIT_MIR_FOR_EACH_BIT_WIDTH // compile-flags: -Zunsound-mir-opts -Zmir-opt-level=3 -// ignore-wasm32-bare compiled with panic=abort by default +// ignore-wasm32 + #![feature(arbitrary_enum_discriminant, repr128)] // Tests that an enum with a variant with no data gets correctly transformed. +#[repr(C)] pub enum NoData { + Large([u8; 8192]), None, - Large([u64; 1024]), } // Tests that an enum with a variant with data that is a valid candidate gets transformed. @@ -26,7 +28,7 @@ pub enum InvalidIdxs { // Tests that an enum with too high of a discriminant index (not in bounds of usize) does not // get tformed. #[repr(u128)] -pub enum Truncatable { +pub enum NotTrunctable { A = 0, B([u8; 1024]) = 1, C([u8; 4096]) = 0x10000000000000001, @@ -43,7 +45,7 @@ pub enum RandOrderDiscr { // EMIT_MIR enum_opt.unin.EnumSizeOpt.diff pub fn unin() { let mut a = NoData::None; - a = NoData::Large([1; 1024]); + a = NoData::Large([1; 8192]); } // EMIT_MIR enum_opt.cand.EnumSizeOpt.diff @@ -60,9 +62,9 @@ pub fn invalid() { // EMIT_MIR enum_opt.trunc.EnumSizeOpt.diff pub fn trunc() { - let mut a = Truncatable::A; - a = Truncatable::B([0; 1024]); - a = Truncatable::C([0; 4096]); + let mut a = NotTrunctable::A; + a = NotTrunctable::B([0; 1024]); + a = NotTrunctable::C([0; 4096]); } pub fn rand_order() { diff --git a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff index 654e385bfe785..b9d6765d8c1ca 100644 --- a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff @@ -2,45 +2,41 @@ + // MIR for `trunc` after EnumSizeOpt fn trunc() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:62:16: 62:16 - let mut _1: Truncatable; // in scope 0 at $DIR/enum_opt.rs:63:7: 63:12 - let mut _2: Truncatable; // in scope 0 at $DIR/enum_opt.rs:64:7: 64:32 - let mut _3: [u8; 1024]; // in scope 0 at $DIR/enum_opt.rs:64:22: 64:31 - let mut _4: Truncatable; // in scope 0 at $DIR/enum_opt.rs:65:7: 65:32 - let mut _5: [u8; 4096]; // in scope 0 at $DIR/enum_opt.rs:65:22: 65:31 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:16: +0:16 + let mut _1: NotTrunctable; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + let mut _2: NotTrunctable; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:34 + let mut _3: [u8; 1024]; // in scope 0 at $DIR/enum_opt.rs:+2:24: +2:33 + let mut _4: NotTrunctable; // in scope 0 at $DIR/enum_opt.rs:+3:7: +3:34 + let mut _5: [u8; 4096]; // in scope 0 at $DIR/enum_opt.rs:+3:24: +3:33 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:63:7: 63:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:+1:7: +1:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:63:7: 63:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:63:15: 63:29 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:63:15: 63:29 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 - _3 = [const 0_u8; 1024]; // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - ((_2 as B).0: [u8; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 - _1 = move _2; // scope 1 at $DIR/enum_opt.rs:64:3: 64:32 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 - StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 - StorageLive(_5); // scope 1 at $DIR/enum_opt.rs:65:22: 65:31 - _5 = [const 0_u8; 4096]; // scope 1 at $DIR/enum_opt.rs:65:22: 65:31 - Deinit(_4); // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 - ((_4 as C).0: [u8; 4096]) = move _5; // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 - discriminant(_4) = 2; // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 - StorageDead(_5); // scope 1 at $DIR/enum_opt.rs:65:31: 65:32 - _1 = move _4; // scope 1 at $DIR/enum_opt.rs:65:3: 65:32 - StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:65:31: 65:32 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:62:16: 66:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:66:1: 66:2 - return; // scope 0 at $DIR/enum_opt.rs:66:2: 66:2 - } - - bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:62:1: 66:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:31 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:31 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 + _3 = [const 0_u8; 1024]; // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + ((_2 as B).0: [u8; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 + _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 + StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 + StorageLive(_5); // scope 1 at $DIR/enum_opt.rs:+3:24: +3:33 + _5 = [const 0_u8; 4096]; // scope 1 at $DIR/enum_opt.rs:+3:24: +3:33 + Deinit(_4); // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 + ((_4 as C).0: [u8; 4096]) = move _5; // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 + discriminant(_4) = 2; // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 + StorageDead(_5); // scope 1 at $DIR/enum_opt.rs:+3:33: +3:34 + _1 = move _4; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:34 + StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:+3:33: +3:34 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:16: +4:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+4:1: +4:2 + return; // scope 0 at $DIR/enum_opt.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff index 654e385bfe785..b9d6765d8c1ca 100644 --- a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff @@ -2,45 +2,41 @@ + // MIR for `trunc` after EnumSizeOpt fn trunc() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:62:16: 62:16 - let mut _1: Truncatable; // in scope 0 at $DIR/enum_opt.rs:63:7: 63:12 - let mut _2: Truncatable; // in scope 0 at $DIR/enum_opt.rs:64:7: 64:32 - let mut _3: [u8; 1024]; // in scope 0 at $DIR/enum_opt.rs:64:22: 64:31 - let mut _4: Truncatable; // in scope 0 at $DIR/enum_opt.rs:65:7: 65:32 - let mut _5: [u8; 4096]; // in scope 0 at $DIR/enum_opt.rs:65:22: 65:31 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:16: +0:16 + let mut _1: NotTrunctable; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + let mut _2: NotTrunctable; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:34 + let mut _3: [u8; 1024]; // in scope 0 at $DIR/enum_opt.rs:+2:24: +2:33 + let mut _4: NotTrunctable; // in scope 0 at $DIR/enum_opt.rs:+3:7: +3:34 + let mut _5: [u8; 4096]; // in scope 0 at $DIR/enum_opt.rs:+3:24: +3:33 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:63:7: 63:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:+1:7: +1:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:63:7: 63:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:63:15: 63:29 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:63:15: 63:29 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 - _3 = [const 0_u8; 1024]; // scope 1 at $DIR/enum_opt.rs:64:22: 64:31 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - ((_2 as B).0: [u8; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:64:7: 64:32 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 - _1 = move _2; // scope 1 at $DIR/enum_opt.rs:64:3: 64:32 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:64:31: 64:32 - StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 - StorageLive(_5); // scope 1 at $DIR/enum_opt.rs:65:22: 65:31 - _5 = [const 0_u8; 4096]; // scope 1 at $DIR/enum_opt.rs:65:22: 65:31 - Deinit(_4); // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 - ((_4 as C).0: [u8; 4096]) = move _5; // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 - discriminant(_4) = 2; // scope 1 at $DIR/enum_opt.rs:65:7: 65:32 - StorageDead(_5); // scope 1 at $DIR/enum_opt.rs:65:31: 65:32 - _1 = move _4; // scope 1 at $DIR/enum_opt.rs:65:3: 65:32 - StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:65:31: 65:32 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:62:16: 66:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:66:1: 66:2 - return; // scope 0 at $DIR/enum_opt.rs:66:2: 66:2 - } - - bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:62:1: 66:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:31 + discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:31 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 + _3 = [const 0_u8; 1024]; // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + ((_2 as B).0: [u8; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 + _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 + StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 + StorageLive(_5); // scope 1 at $DIR/enum_opt.rs:+3:24: +3:33 + _5 = [const 0_u8; 4096]; // scope 1 at $DIR/enum_opt.rs:+3:24: +3:33 + Deinit(_4); // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 + ((_4 as C).0: [u8; 4096]) = move _5; // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 + discriminant(_4) = 2; // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 + StorageDead(_5); // scope 1 at $DIR/enum_opt.rs:+3:33: +3:34 + _1 = move _4; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:34 + StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:+3:33: +3:34 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:16: +4:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+4:1: +4:2 + return; // scope 0 at $DIR/enum_opt.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff index bc72e507d5ab7..168677b173d53 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff @@ -2,53 +2,49 @@ + // MIR for `unin` after EnumSizeOpt fn unin() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:44:15: 44:15 - let mut _1: NoData; // in scope 0 at $DIR/enum_opt.rs:45:7: 45:12 - let mut _2: NoData; // in scope 0 at $DIR/enum_opt.rs:46:7: 46:31 - let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:46:21: 46:30 -+ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 -+ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 -+ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 -+ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 -+ let mut _8: *mut NoData; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 -+ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 -+ let mut _10: *const NoData; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 -+ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:15: +0:15 + let mut _1: NoData; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + let mut _2: NoData; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:31 + let mut _3: [u8; 8192]; // in scope 0 at $DIR/enum_opt.rs:+2:21: +2:30 ++ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _8: *mut NoData; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _10: *const NoData; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:45:7: 45:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:+1:7: +1:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:45:7: 45:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:45:15: 45:27 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:45:15: 45:27 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:46:21: 46:30 - _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:46:21: 46:30 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:46:30: 46:31 -- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _4 = const [4_usize, 8196_usize]; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:46:30: 46:31 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:44:15: 47:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:47:1: 47:2 - return; // scope 0 at $DIR/enum_opt.rs:47:2: 47:2 - } - - bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:44:1: 47:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:27 + discriminant(_1) = 1; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:27 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:21: +2:30 + _3 = [const 1_u8; 8192]; // scope 1 at $DIR/enum_opt.rs:+2:21: +2:30 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 + ((_2 as Large).0: [u8; 8192]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 + discriminant(_2) = 0; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:30: +2:31 +- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _4 = const [8196_usize, 4_usize]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _6 = _5 as usize (IntToInt); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _9 = _8 as *mut u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _11 = _10 as *const u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ copy_nonoverlapping(dst = _9, src = _11, count = _7); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:30: +2:31 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:15: +3:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+3:1: +3:2 + return; // scope 0 at $DIR/enum_opt.rs:+3:2: +3:2 } } diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff index 9001268dc2087..168677b173d53 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff @@ -2,53 +2,49 @@ + // MIR for `unin` after EnumSizeOpt fn unin() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:44:15: 44:15 - let mut _1: NoData; // in scope 0 at $DIR/enum_opt.rs:45:7: 45:12 - let mut _2: NoData; // in scope 0 at $DIR/enum_opt.rs:46:7: 46:31 - let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:46:21: 46:30 -+ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 -+ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 -+ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 -+ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 -+ let mut _8: *mut NoData; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 -+ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 -+ let mut _10: *const NoData; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 -+ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:46:3: 46:31 + let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:15: +0:15 + let mut _1: NoData; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + let mut _2: NoData; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:31 + let mut _3: [u8; 8192]; // in scope 0 at $DIR/enum_opt.rs:+2:21: +2:30 ++ let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _7: usize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _8: *mut NoData; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _10: *const NoData; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 scope 1 { - debug a => _1; // in scope 1 at $DIR/enum_opt.rs:45:7: 45:12 + debug a => _1; // in scope 1 at $DIR/enum_opt.rs:+1:7: +1:12 } bb0: { - StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:45:7: 45:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:45:15: 45:27 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:45:15: 45:27 - StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 - StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:46:21: 46:30 - _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:46:21: 46:30 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:46:7: 46:31 - StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:46:30: 46:31 -- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _4 = const [8_usize, 8200_usize]; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _6 = _5 as usize (Misc); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _9 = _8 as *mut u8 (Misc); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ _11 = _10 as *const u8 (Misc); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ copy_nonoverlapping(src=_11, dst=_9, count=_7); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 -+ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:46:3: 46:31 - StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:46:30: 46:31 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:44:15: 47:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:47:1: 47:2 - return; // scope 0 at $DIR/enum_opt.rs:47:2: 47:2 - } - - bb1 (cleanup): { - resume; // scope 0 at $DIR/enum_opt.rs:44:1: 47:2 + StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 + Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:27 + discriminant(_1) = 1; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:27 + StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 + StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:21: +2:30 + _3 = [const 1_u8; 8192]; // scope 1 at $DIR/enum_opt.rs:+2:21: +2:30 + Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 + ((_2 as Large).0: [u8; 8192]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 + discriminant(_2) = 0; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 + StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:30: +2:31 +- _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _4 = const [8196_usize, 4_usize]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _6 = _5 as usize (IntToInt); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _8 = &raw mut _1; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _9 = _8 as *mut u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _11 = _10 as *const u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ copy_nonoverlapping(dst = _9, src = _11, count = _7); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:30: +2:31 + _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:15: +3:2 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+3:1: +3:2 + return; // scope 0 at $DIR/enum_opt.rs:+3:2: +3:2 } } From 15d4728cda673e90b4db1ea2c60d18a6fae306d0 Mon Sep 17 00:00:00 2001 From: kadmin Date: Sun, 5 Feb 2023 22:14:40 +0000 Subject: [PATCH 9/9] Add de-init to destination place --- .../rustc_mir_transform/src/large_enums.rs | 17 ++++--- compiler/rustc_mir_transform/src/lib.rs | 2 +- .../enum_opt.cand.EnumSizeOpt.32bit.diff | 45 +++++++++++++------ .../enum_opt.cand.EnumSizeOpt.64bit.diff | 45 +++++++++++++------ .../enum_opt.invalid.EnumSizeOpt.32bit.diff | 17 +++---- .../enum_opt.invalid.EnumSizeOpt.64bit.diff | 17 +++---- tests/mir-opt/enum_opt.rs | 28 +++++++----- .../enum_opt.trunc.EnumSizeOpt.32bit.diff | 21 ++++----- .../enum_opt.trunc.EnumSizeOpt.64bit.diff | 21 ++++----- .../enum_opt.unin.EnumSizeOpt.32bit.diff | 44 ++++++++++++------ .../enum_opt.unin.EnumSizeOpt.64bit.diff | 44 ++++++++++++------ 11 files changed, 181 insertions(+), 120 deletions(-) diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 3f8662ad6971f..89f8de235835a 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -4,6 +4,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_middle::mir::interpret::AllocId; use rustc_middle::mir::*; use rustc_middle::ty::{self, AdtDef, Const, ParamEnv, Ty, TyCtxt}; +use rustc_session::Session; use rustc_target::abi::{HasDataLayout, Size, TagEncoding, Variants}; /// A pass that seeks to optimize unnecessary moves of large enum types, if there is a large @@ -28,14 +29,12 @@ pub struct EnumSizeOpt { } impl<'tcx> MirPass<'tcx> for EnumSizeOpt { + fn is_enabled(&self, sess: &Session) -> bool { + sess.opts.unstable_opts.unsound_mir_opts || sess.mir_opt_level() >= 3 + } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let sess = tcx.sess; - // FIXME(julianknodt): one thing noticed while testing this mir-opt is that there is a - // different layout of large enums on wasm. It's not clear what is causing this layout - // difference, as it should be identical to i686 (32 bit). - if (!sess.opts.unstable_opts.unsound_mir_opts) || sess.mir_opt_level() < 3 { - return; - } + // NOTE: This pass may produce different MIR based on the alignment of the target + // platform, but it will still be valid. self.optim(tcx, body); } } @@ -254,6 +253,9 @@ impl EnumSizeOpt { )), }; + let deinit_old = + Statement { source_info, kind: StatementKind::Deinit(box dst) }; + let copy_bytes = Statement { source_info, kind: StatementKind::Intrinsic( @@ -279,6 +281,7 @@ impl EnumSizeOpt { dst_cast, src_ptr, src_cast, + deinit_old, copy_bytes, store_dead, ] diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index be3652dd3e7bd..45cd4024c9f57 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -547,7 +547,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { tcx, body, &[ - &large_enums::EnumSizeOpt { discrepancy: 128 }, &reveal_all::RevealAll, // has to be done before inlining, since inlined code is in RevealAll mode. &lower_slice_len::LowerSliceLenCalls, // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first &unreachable_prop::UnreachablePropagation, @@ -586,6 +585,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &simplify::SimplifyLocals::new("final"), &multiple_return_terminators::MultipleReturnTerminators, &deduplicate_blocks::DeduplicateBlocks, + &large_enums::EnumSizeOpt { discrepancy: 128 }, // Some cleanup necessary at least for LLVM and potentially other codegen backends. &add_call_guards::CriticalCallEdges, // Dump the end result for testing and debugging purposes. diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff index e0ba46c15f4a9..b139deeee1fc9 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff @@ -1,11 +1,11 @@ - // MIR for `cand` before EnumSizeOpt + // MIR for `cand` after EnumSizeOpt - fn cand() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:15: +0:15 + fn cand() -> Candidate { + let mut _0: Candidate; // return place in scope 0 at $DIR/enum_opt.rs:+0:18: +0:27 let mut _1: Candidate; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 let mut _2: Candidate; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:34 - let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:+2:24: +2:33 + let mut _3: [u8; 8196]; // in scope 0 at $DIR/enum_opt.rs:+2:24: +2:33 + let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 + let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 + let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 @@ -14,25 +14,29 @@ + let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 + let mut _10: *const Candidate; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 + let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _12: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _13: isize; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _14: usize; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _15: usize; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _16: *mut Candidate; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _17: *mut u8; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _18: *const Candidate; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _19: *const u8; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 scope 1 { debug a => _1; // in scope 1 at $DIR/enum_opt.rs:+1:7: +1:12 } bb0: { StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:34 - ((_1 as Small).0: u8) = const 1_u8; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:34 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:34 + _1 = Candidate::Small(const 1_u8); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:34 StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 - _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + _3 = [const 1_u8; 8196]; // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 + _2 = Candidate::Large(move _3); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 - _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 -+ _4 = const [2_usize, 8196_usize]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _4 = const [2_usize, 8197_usize]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + _6 = _5 as usize (IntToInt); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 @@ -40,12 +44,25 @@ + _9 = _8 as *mut u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + _11 = _10 as *const u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ Deinit(_8); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + copy_nonoverlapping(dst = _9, src = _11, count = _7); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:15: +3:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+3:1: +3:2 - return; // scope 0 at $DIR/enum_opt.rs:+3:2: +3:2 +- _0 = move _1; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ StorageLive(_12); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _12 = const [2_usize, 8197_usize]; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _13 = discriminant(_1); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _14 = _13 as usize (IntToInt); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _15 = _12[_14]; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _16 = &raw mut _0; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _17 = _16 as *mut u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _18 = &raw const _1; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _19 = _18 as *const u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ Deinit(_16); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ copy_nonoverlapping(dst = _17, src = _19, count = _15); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ StorageDead(_12); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+4:1: +4:2 + return; // scope 0 at $DIR/enum_opt.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff index 67439dba9c947..b139deeee1fc9 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff @@ -1,11 +1,11 @@ - // MIR for `cand` before EnumSizeOpt + // MIR for `cand` after EnumSizeOpt - fn cand() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:15: +0:15 + fn cand() -> Candidate { + let mut _0: Candidate; // return place in scope 0 at $DIR/enum_opt.rs:+0:18: +0:27 let mut _1: Candidate; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 let mut _2: Candidate; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:34 - let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:+2:24: +2:33 + let mut _3: [u8; 8196]; // in scope 0 at $DIR/enum_opt.rs:+2:24: +2:33 + let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 + let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 + let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 @@ -14,25 +14,29 @@ + let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 + let mut _10: *const Candidate; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 + let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:34 ++ let mut _12: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _13: isize; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _14: usize; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _15: usize; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _16: *mut Candidate; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _17: *mut u8; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _18: *const Candidate; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _19: *const u8; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 scope 1 { debug a => _1; // in scope 1 at $DIR/enum_opt.rs:+1:7: +1:12 } bb0: { StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:34 - ((_1 as Small).0: u8) = const 1_u8; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:34 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:34 + _1 = Candidate::Small(const 1_u8); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:34 StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 - _3 = [const 1_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + _3 = [const 1_u8; 8196]; // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 + _2 = Candidate::Large(move _3); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 - _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 -+ _4 = const [2_usize, 8200_usize]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ _4 = const [2_usize, 8197_usize]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + _6 = _5 as usize (IntToInt); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 @@ -40,12 +44,25 @@ + _9 = _8 as *mut u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + _11 = _10 as *const u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 ++ Deinit(_8); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + copy_nonoverlapping(dst = _9, src = _11, count = _7); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 + StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:15: +3:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+3:1: +3:2 - return; // scope 0 at $DIR/enum_opt.rs:+3:2: +3:2 +- _0 = move _1; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ StorageLive(_12); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _12 = const [2_usize, 8197_usize]; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _13 = discriminant(_1); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _14 = _13 as usize (IntToInt); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _15 = _12[_14]; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _16 = &raw mut _0; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _17 = _16 as *mut u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _18 = &raw const _1; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _19 = _18 as *const u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ Deinit(_16); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ copy_nonoverlapping(dst = _17, src = _19, count = _15); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ StorageDead(_12); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+4:1: +4:2 + return; // scope 0 at $DIR/enum_opt.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff index db2efa195a369..a80001149ebb7 100644 --- a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.32bit.diff @@ -1,8 +1,8 @@ - // MIR for `invalid` before EnumSizeOpt + // MIR for `invalid` after EnumSizeOpt - fn invalid() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:18: +0:18 + fn invalid() -> InvalidIdxs { + let mut _0: InvalidIdxs; // return place in scope 0 at $DIR/enum_opt.rs:+0:21: +0:32 let mut _1: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 let mut _2: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:36 let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:+2:26: +2:35 @@ -12,20 +12,17 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:29 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:29 + _1 = InvalidIdxs::A; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:29 StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:26: +2:35 _3 = [const 0_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:+2:26: +2:35 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 + _2 = InvalidIdxs::Large(move _3); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:35: +2:36 _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:36 StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:35: +2:36 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:18: +3:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+3:1: +3:2 - return; // scope 0 at $DIR/enum_opt.rs:+3:2: +3:2 + _0 = move _1; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+4:1: +4:2 + return; // scope 0 at $DIR/enum_opt.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff index db2efa195a369..a80001149ebb7 100644 --- a/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.invalid.EnumSizeOpt.64bit.diff @@ -1,8 +1,8 @@ - // MIR for `invalid` before EnumSizeOpt + // MIR for `invalid` after EnumSizeOpt - fn invalid() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:18: +0:18 + fn invalid() -> InvalidIdxs { + let mut _0: InvalidIdxs; // return place in scope 0 at $DIR/enum_opt.rs:+0:21: +0:32 let mut _1: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 let mut _2: InvalidIdxs; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:36 let mut _3: [u64; 1024]; // in scope 0 at $DIR/enum_opt.rs:+2:26: +2:35 @@ -12,20 +12,17 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:29 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:29 + _1 = InvalidIdxs::A; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:29 StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:26: +2:35 _3 = [const 0_u64; 1024]; // scope 1 at $DIR/enum_opt.rs:+2:26: +2:35 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 - ((_2 as Large).0: [u64; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 + _2 = InvalidIdxs::Large(move _3); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:36 StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:35: +2:36 _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:36 StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:35: +2:36 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:18: +3:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+3:1: +3:2 - return; // scope 0 at $DIR/enum_opt.rs:+3:2: +3:2 + _0 = move _1; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+4:1: +4:2 + return; // scope 0 at $DIR/enum_opt.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/enum_opt.rs b/tests/mir-opt/enum_opt.rs index 6876c56cfa4ed..2768d70804926 100644 --- a/tests/mir-opt/enum_opt.rs +++ b/tests/mir-opt/enum_opt.rs @@ -1,20 +1,19 @@ +// unit-test: EnumSizeOpt // EMIT_MIR_FOR_EACH_BIT_WIDTH -// compile-flags: -Zunsound-mir-opts -Zmir-opt-level=3 -// ignore-wasm32 +// compile-flags: -Zunsound-mir-opts #![feature(arbitrary_enum_discriminant, repr128)] // Tests that an enum with a variant with no data gets correctly transformed. -#[repr(C)] pub enum NoData { - Large([u8; 8192]), + Large([u8; 8196]), None, } // Tests that an enum with a variant with data that is a valid candidate gets transformed. pub enum Candidate { Small(u8), - Large([u64; 1024]), + Large([u8; 8196]), } // Tests that an enum which has a discriminant much higher than the variant does not get @@ -43,34 +42,39 @@ pub enum RandOrderDiscr { } // EMIT_MIR enum_opt.unin.EnumSizeOpt.diff -pub fn unin() { +pub fn unin() -> NoData { let mut a = NoData::None; - a = NoData::Large([1; 8192]); + a = NoData::Large([1; 8196]); + a } // EMIT_MIR enum_opt.cand.EnumSizeOpt.diff -pub fn cand() { +pub fn cand() -> Candidate { let mut a = Candidate::Small(1); - a = Candidate::Large([1; 1024]); + a = Candidate::Large([1; 8196]); + a } // EMIT_MIR enum_opt.invalid.EnumSizeOpt.diff -pub fn invalid() { +pub fn invalid() -> InvalidIdxs { let mut a = InvalidIdxs::A; a = InvalidIdxs::Large([0; 1024]); + a } // EMIT_MIR enum_opt.trunc.EnumSizeOpt.diff -pub fn trunc() { +pub fn trunc() -> NotTrunctable { let mut a = NotTrunctable::A; a = NotTrunctable::B([0; 1024]); a = NotTrunctable::C([0; 4096]); + a } -pub fn rand_order() { +pub fn rand_order() -> RandOrderDiscr { let mut a = RandOrderDiscr::A; a = RandOrderDiscr::B([0; 1024]); a = RandOrderDiscr::C; + a } pub fn main() { diff --git a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff index b9d6765d8c1ca..1ef79044d4fc6 100644 --- a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.32bit.diff @@ -1,8 +1,8 @@ - // MIR for `trunc` before EnumSizeOpt + // MIR for `trunc` after EnumSizeOpt - fn trunc() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:16: +0:16 + fn trunc() -> NotTrunctable { + let mut _0: NotTrunctable; // return place in scope 0 at $DIR/enum_opt.rs:+0:19: +0:32 let mut _1: NotTrunctable; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 let mut _2: NotTrunctable; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:34 let mut _3: [u8; 1024]; // in scope 0 at $DIR/enum_opt.rs:+2:24: +2:33 @@ -14,29 +14,24 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:31 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:31 + _1 = NotTrunctable::A; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:31 StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 _3 = [const 0_u8; 1024]; // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 - ((_2 as B).0: [u8; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + _2 = NotTrunctable::B(move _3); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 StorageLive(_5); // scope 1 at $DIR/enum_opt.rs:+3:24: +3:33 _5 = [const 0_u8; 4096]; // scope 1 at $DIR/enum_opt.rs:+3:24: +3:33 - Deinit(_4); // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 - ((_4 as C).0: [u8; 4096]) = move _5; // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 - discriminant(_4) = 2; // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 + _4 = NotTrunctable::C(move _5); // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 StorageDead(_5); // scope 1 at $DIR/enum_opt.rs:+3:33: +3:34 _1 = move _4; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:34 StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:+3:33: +3:34 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:16: +4:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+4:1: +4:2 - return; // scope 0 at $DIR/enum_opt.rs:+4:2: +4:2 + _0 = move _1; // scope 1 at $DIR/enum_opt.rs:+4:3: +4:4 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+5:1: +5:2 + return; // scope 0 at $DIR/enum_opt.rs:+5:2: +5:2 } } diff --git a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff index b9d6765d8c1ca..1ef79044d4fc6 100644 --- a/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.trunc.EnumSizeOpt.64bit.diff @@ -1,8 +1,8 @@ - // MIR for `trunc` before EnumSizeOpt + // MIR for `trunc` after EnumSizeOpt - fn trunc() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:16: +0:16 + fn trunc() -> NotTrunctable { + let mut _0: NotTrunctable; // return place in scope 0 at $DIR/enum_opt.rs:+0:19: +0:32 let mut _1: NotTrunctable; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 let mut _2: NotTrunctable; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:34 let mut _3: [u8; 1024]; // in scope 0 at $DIR/enum_opt.rs:+2:24: +2:33 @@ -14,29 +14,24 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:31 - discriminant(_1) = 0; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:31 + _1 = NotTrunctable::A; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:31 StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 _3 = [const 0_u8; 1024]; // scope 1 at $DIR/enum_opt.rs:+2:24: +2:33 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 - ((_2 as B).0: [u8; 1024]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 - discriminant(_2) = 1; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 + _2 = NotTrunctable::B(move _3); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:34 StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:34 StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:33: +2:34 StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 StorageLive(_5); // scope 1 at $DIR/enum_opt.rs:+3:24: +3:33 _5 = [const 0_u8; 4096]; // scope 1 at $DIR/enum_opt.rs:+3:24: +3:33 - Deinit(_4); // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 - ((_4 as C).0: [u8; 4096]) = move _5; // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 - discriminant(_4) = 2; // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 + _4 = NotTrunctable::C(move _5); // scope 1 at $DIR/enum_opt.rs:+3:7: +3:34 StorageDead(_5); // scope 1 at $DIR/enum_opt.rs:+3:33: +3:34 _1 = move _4; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:34 StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:+3:33: +3:34 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:16: +4:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+4:1: +4:2 - return; // scope 0 at $DIR/enum_opt.rs:+4:2: +4:2 + _0 = move _1; // scope 1 at $DIR/enum_opt.rs:+4:3: +4:4 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+5:1: +5:2 + return; // scope 0 at $DIR/enum_opt.rs:+5:2: +5:2 } } diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff index 168677b173d53..ad9f12cf95953 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff @@ -1,11 +1,11 @@ - // MIR for `unin` before EnumSizeOpt + // MIR for `unin` after EnumSizeOpt - fn unin() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:15: +0:15 + fn unin() -> NoData { + let mut _0: NoData; // return place in scope 0 at $DIR/enum_opt.rs:+0:18: +0:24 let mut _1: NoData; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 let mut _2: NoData; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:31 - let mut _3: [u8; 8192]; // in scope 0 at $DIR/enum_opt.rs:+2:21: +2:30 + let mut _3: [u8; 8196]; // in scope 0 at $DIR/enum_opt.rs:+2:21: +2:30 + let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 + let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 + let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 @@ -14,24 +14,29 @@ + let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 + let mut _10: *const NoData; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 + let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _12: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _13: isize; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _14: usize; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _15: usize; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _16: *mut NoData; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _17: *mut u8; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _18: *const NoData; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _19: *const u8; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 scope 1 { debug a => _1; // in scope 1 at $DIR/enum_opt.rs:+1:7: +1:12 } bb0: { StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:27 - discriminant(_1) = 1; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:27 + _1 = NoData::None; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:27 StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:21: +2:30 - _3 = [const 1_u8; 8192]; // scope 1 at $DIR/enum_opt.rs:+2:21: +2:30 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 - ((_2 as Large).0: [u8; 8192]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 - discriminant(_2) = 0; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 + _3 = [const 1_u8; 8196]; // scope 1 at $DIR/enum_opt.rs:+2:21: +2:30 + _2 = NoData::Large(move _3); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:30: +2:31 - _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 -+ _4 = const [8196_usize, 4_usize]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _4 = const [8197_usize, 1_usize]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + _6 = _5 as usize (IntToInt); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 @@ -39,12 +44,25 @@ + _9 = _8 as *mut u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + _11 = _10 as *const u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ Deinit(_8); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + copy_nonoverlapping(dst = _9, src = _11, count = _7); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:30: +2:31 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:15: +3:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+3:1: +3:2 - return; // scope 0 at $DIR/enum_opt.rs:+3:2: +3:2 +- _0 = move _1; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ StorageLive(_12); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _12 = const [8197_usize, 1_usize]; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _13 = discriminant(_1); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _14 = _13 as usize (IntToInt); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _15 = _12[_14]; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _16 = &raw mut _0; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _17 = _16 as *mut u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _18 = &raw const _1; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _19 = _18 as *const u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ Deinit(_16); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ copy_nonoverlapping(dst = _17, src = _19, count = _15); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ StorageDead(_12); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+4:1: +4:2 + return; // scope 0 at $DIR/enum_opt.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff index 168677b173d53..ad9f12cf95953 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff @@ -1,11 +1,11 @@ - // MIR for `unin` before EnumSizeOpt + // MIR for `unin` after EnumSizeOpt - fn unin() -> () { - let mut _0: (); // return place in scope 0 at $DIR/enum_opt.rs:+0:15: +0:15 + fn unin() -> NoData { + let mut _0: NoData; // return place in scope 0 at $DIR/enum_opt.rs:+0:18: +0:24 let mut _1: NoData; // in scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 let mut _2: NoData; // in scope 0 at $DIR/enum_opt.rs:+2:7: +2:31 - let mut _3: [u8; 8192]; // in scope 0 at $DIR/enum_opt.rs:+2:21: +2:30 + let mut _3: [u8; 8196]; // in scope 0 at $DIR/enum_opt.rs:+2:21: +2:30 + let mut _4: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 + let mut _5: isize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 + let mut _6: usize; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 @@ -14,24 +14,29 @@ + let mut _9: *mut u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 + let mut _10: *const NoData; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 + let mut _11: *const u8; // in scope 0 at $DIR/enum_opt.rs:+2:3: +2:31 ++ let mut _12: [usize; 2]; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _13: isize; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _14: usize; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _15: usize; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _16: *mut NoData; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _17: *mut u8; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _18: *const NoData; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 ++ let mut _19: *const u8; // in scope 0 at $DIR/enum_opt.rs:+3:3: +3:4 scope 1 { debug a => _1; // in scope 1 at $DIR/enum_opt.rs:+1:7: +1:12 } bb0: { StorageLive(_1); // scope 0 at $DIR/enum_opt.rs:+1:7: +1:12 - Deinit(_1); // scope 0 at $DIR/enum_opt.rs:+1:15: +1:27 - discriminant(_1) = 1; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:27 + _1 = NoData::None; // scope 0 at $DIR/enum_opt.rs:+1:15: +1:27 StorageLive(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 StorageLive(_3); // scope 1 at $DIR/enum_opt.rs:+2:21: +2:30 - _3 = [const 1_u8; 8192]; // scope 1 at $DIR/enum_opt.rs:+2:21: +2:30 - Deinit(_2); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 - ((_2 as Large).0: [u8; 8192]) = move _3; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 - discriminant(_2) = 0; // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 + _3 = [const 1_u8; 8196]; // scope 1 at $DIR/enum_opt.rs:+2:21: +2:30 + _2 = NoData::Large(move _3); // scope 1 at $DIR/enum_opt.rs:+2:7: +2:31 StorageDead(_3); // scope 1 at $DIR/enum_opt.rs:+2:30: +2:31 - _1 = move _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + StorageLive(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 -+ _4 = const [8196_usize, 4_usize]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ _4 = const [8197_usize, 1_usize]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + _5 = discriminant(_2); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + _6 = _5 as usize (IntToInt); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + _7 = _4[_6]; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 @@ -39,12 +44,25 @@ + _9 = _8 as *mut u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + _10 = &raw const _2; // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + _11 = _10 as *const u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 ++ Deinit(_8); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + copy_nonoverlapping(dst = _9, src = _11, count = _7); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 + StorageDead(_4); // scope 1 at $DIR/enum_opt.rs:+2:3: +2:31 StorageDead(_2); // scope 1 at $DIR/enum_opt.rs:+2:30: +2:31 - _0 = const (); // scope 0 at $DIR/enum_opt.rs:+0:15: +3:2 - StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+3:1: +3:2 - return; // scope 0 at $DIR/enum_opt.rs:+3:2: +3:2 +- _0 = move _1; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ StorageLive(_12); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _12 = const [8197_usize, 1_usize]; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _13 = discriminant(_1); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _14 = _13 as usize (IntToInt); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _15 = _12[_14]; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _16 = &raw mut _0; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _17 = _16 as *mut u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _18 = &raw const _1; // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ _19 = _18 as *const u8 (PtrToPtr); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ Deinit(_16); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ copy_nonoverlapping(dst = _17, src = _19, count = _15); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 ++ StorageDead(_12); // scope 1 at $DIR/enum_opt.rs:+3:3: +3:4 + StorageDead(_1); // scope 0 at $DIR/enum_opt.rs:+4:1: +4:2 + return; // scope 0 at $DIR/enum_opt.rs:+4:2: +4:2 } }