From 3c02cfc3e7e52ce023b565180c63c72bd7ab675d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 31 May 2023 13:57:55 +0000 Subject: Explain the reason for why a test exists --- tests/codegen/const_scalar_pair.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests/codegen') diff --git a/tests/codegen/const_scalar_pair.rs b/tests/codegen/const_scalar_pair.rs index 8f32c50b798..aa4cf7a64d5 100644 --- a/tests/codegen/const_scalar_pair.rs +++ b/tests/codegen/const_scalar_pair.rs @@ -2,6 +2,8 @@ #![feature(inline_const)] +// Test that we don't generate a memory allocation for the constant +// and read the fields from that, but instead just create the value pair directly. pub fn foo() -> (i32, i32) { // CHECK: ret { i32, i32 } { i32 1, i32 2 } const { (1, 2) } -- cgit 1.4.1-3-g733a5 From 79ba7b307d0d0120a95043d229f5420858981045 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 26 May 2023 14:53:34 -0400 Subject: Enable ScalarReplacementOfAggregates --- compiler/rustc_mir_transform/src/sroa.rs | 50 ++++++++- .../codegen/issues/issue-105386-ub-in-debuginfo.rs | 7 +- tests/incremental/hashes/match_expressions.rs | 3 +- ...ifts.unchecked_shl_unsigned_smaller.Inline.diff | 96 ++++++++--------- ...ecked_shl_unsigned_smaller.PreCodegen.after.mir | 104 +++++++++--------- ...shifts.unchecked_shr_signed_smaller.Inline.diff | 96 ++++++++--------- ...checked_shr_signed_smaller.PreCodegen.after.mir | 104 +++++++++--------- .../mem_replace.mem_replace.PreCodegen.after.mir | 10 +- .../simple_option_map.ezmap.PreCodegen.after.mir | 20 +--- ..._index.slice_get_mut_usize.PreCodegen.after.mir | 16 +-- ...ce_get_unchecked_mut_range.PreCodegen.after.mir | 119 ++++++++++----------- .../slice_iter.forward_loop.PreCodegen.after.mir | 15 ++- .../slice_iter.reverse_loop.PreCodegen.after.mir | 15 ++- 13 files changed, 313 insertions(+), 342 deletions(-) (limited to 'tests/codegen') diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index 2d77291293d..e4b3b8b9262 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -6,23 +6,29 @@ use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_mir_dataflow::value_analysis::{excluded_locals, iter_fields}; -use rustc_target::abi::FieldIdx; +use rustc_target::abi::{FieldIdx, ReprFlags, FIRST_VARIANT}; pub struct ScalarReplacementOfAggregates; impl<'tcx> MirPass<'tcx> for ScalarReplacementOfAggregates { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.mir_opt_level() >= 3 + sess.mir_opt_level() >= 2 } #[instrument(level = "debug", skip(self, tcx, body))] fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { debug!(def_id = ?body.source.def_id()); + + // Avoid query cycles (generators require optimized MIR for layout). + if tcx.type_of(body.source.def_id()).subst_identity().is_generator() { + return; + } + let mut excluded = excluded_locals(body); let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); loop { debug!(?excluded); - let escaping = escaping_locals(&excluded, body); + let escaping = escaping_locals(tcx, param_env, &excluded, body); debug!(?escaping); let replacements = compute_flattening(tcx, param_env, body, escaping); debug!(?replacements); @@ -48,11 +54,45 @@ impl<'tcx> MirPass<'tcx> for ScalarReplacementOfAggregates { /// - the locals is a union or an enum; /// - the local's address is taken, and thus the relative addresses of the fields are observable to /// client code. -fn escaping_locals(excluded: &BitSet, body: &Body<'_>) -> BitSet { +fn escaping_locals<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + excluded: &BitSet, + body: &Body<'tcx>, +) -> BitSet { + let is_excluded_ty = |ty: Ty<'tcx>| { + if ty.is_union() || ty.is_enum() { + return true; + } + if let ty::Adt(def, _substs) = ty.kind() { + if def.repr().flags.contains(ReprFlags::IS_SIMD) { + // Exclude #[repr(simd)] types so that they are not de-optimized into an array + return true; + } + // We already excluded unions and enums, so this ADT must have one variant + let variant = def.variant(FIRST_VARIANT); + if variant.fields.len() > 1 { + // If this has more than one field, it cannot be a wrapper that only provides a + // niche, so we do not want to automatically exclude it. + return false; + } + let Ok(layout) = tcx.layout_of(param_env.and(ty)) else { + // We can't get the layout + return true; + }; + if layout.layout.largest_niche().is_some() { + // This type has a niche + return true; + } + } + // Default for non-ADTs + false + }; + let mut set = BitSet::new_empty(body.local_decls.len()); set.insert_range(RETURN_PLACE..=Local::from_usize(body.arg_count)); for (local, decl) in body.local_decls().iter_enumerated() { - if decl.ty.is_union() || decl.ty.is_enum() || excluded.contains(local) { + if excluded.contains(local) || is_excluded_ty(decl.ty) { set.insert(local); } } diff --git a/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs b/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs index 2ee4d7cca0e..6e0eacfe400 100644 --- a/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs +++ b/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs @@ -1,4 +1,5 @@ -// compile-flags: --crate-type=lib -O -Cdebuginfo=2 -Cno-prepopulate-passes +// compile-flags: --crate-type=lib -O -Cdebuginfo=2 -Cno-prepopulate-passes -Zmir-enable-passes=-ScalarReplacementOfAggregates +// MIR SROA will decompose the closure // min-llvm-version: 15.0 # this test uses opaque pointer notation #![feature(stmt_expr_attributes)] @@ -15,8 +16,8 @@ pub fn outer_function(x: S, y: S) -> usize { // Check that we do not attempt to load from the spilled arg before it is assigned to // when generating debuginfo. // CHECK-LABEL: @outer_function -// CHECK: [[spill:%.*]] = alloca %"[closure@{{.*.rs}}:9:23: 9:25]" -// CHECK-NOT: [[ptr_tmp:%.*]] = getelementptr inbounds %"[closure@{{.*.rs}}:9:23: 9:25]", ptr [[spill]] +// CHECK: [[spill:%.*]] = alloca %"[closure@{{.*.rs}}:10:23: 10:25]" +// CHECK-NOT: [[ptr_tmp:%.*]] = getelementptr inbounds %"[closure@{{.*.rs}}:10:23: 10:25]", ptr [[spill]] // CHECK-NOT: [[load:%.*]] = load ptr, ptr // CHECK: call void @llvm.lifetime.start{{.*}}({{.*}}, ptr [[spill]]) // CHECK: [[inner:%.*]] = getelementptr inbounds %"{{.*}}", ptr [[spill]] diff --git a/tests/incremental/hashes/match_expressions.rs b/tests/incremental/hashes/match_expressions.rs index 4429df6833e..ecb19480d65 100644 --- a/tests/incremental/hashes/match_expressions.rs +++ b/tests/incremental/hashes/match_expressions.rs @@ -225,8 +225,9 @@ pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 { } } +// Ignore optimized_mir in cfail2, the only change to optimized MIR is a span. #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")] #[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")] #[rustc_clean(cfg="cfail6")] diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff index d76cd0e2bb8..e82e3f18811 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff @@ -11,35 +11,33 @@ + debug self => _3; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + debug rhs => _4; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + let mut _5: u16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ let mut _6: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ let mut _7: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 2 { + scope 3 (inlined core::num::::unchecked_shl::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ debug x => _7; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ let mut _8: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ let mut _9: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug x => _4; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _6: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _7: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 4 { + scope 5 (inlined >::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ debug self => _7; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ debug self => _4; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + scope 6 (inlined convert::num:: for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL -+ debug u => _7; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _10: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _11: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _12: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ debug u => _4; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _8: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _9: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _10: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + } + scope 7 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ debug self => _9; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL -+ let mut _13: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL -+ let _14: u16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ debug self => _7; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let mut _11: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let _12: u16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + scope 8 { -+ debug x => _14; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ debug x => _12; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + } + } + scope 9 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ debug self => _8; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ let mut _15: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ let mut _16: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _13: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + scope 10 { + debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL + } @@ -52,7 +50,7 @@ + } + } + scope 12 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL -+ debug self => _15; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL + } + } + } @@ -70,18 +68,14 @@ - // + span: $DIR/unchecked_shifts.rs:11:7: 11:20 - // + literal: Const { ty: unsafe fn(u16, u32) -> u16 {core::num::::unchecked_shl}, val: Value() } + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageLive(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ _6 = (_4,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ _7 = move (_6.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageLive(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageLive(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _11 = const 65535_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _10 = Gt(_7, move _11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageDead(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ switchInt(move _10) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _9 = const 65535_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _8 = Gt(_4, move _9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ switchInt(move _8) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { @@ -92,7 +86,7 @@ + } + + bb2: { -+ _9 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _7 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: TryFromIntError, val: Value() } @@ -100,22 +94,22 @@ + } + + bb3: { -+ StorageLive(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _12 = _7 as u16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _9 = Result::::Ok(move _12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageDead(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _10 = _4 as u16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _7 = Result::::Ok(move _10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb4: { -+ StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageLive(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ _13 = discriminant(_9); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL -+ switchInt(move _13) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ StorageDead(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _11 = discriminant(_7); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb5: { -+ _8 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ _6 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + @@ -124,25 +118,23 @@ + } + + bb7: { -+ _14 = move ((_9 as Ok).0: u16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL -+ _8 = Option::::Some(move _14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ _12 = move ((_7 as Ok).0: u16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ _6 = Option::::Some(move _12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb8: { -+ StorageDead(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageDead(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageLive(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ _16 = discriminant(_8); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ switchInt(move _16) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _14) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb9: { -+ _5 = move ((_8 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ StorageDead(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageDead(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _5 = move ((_6 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _0 = unchecked_shl::(_3, move _5) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir index f4b2416eaab..8fa4fdaa49a 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir @@ -7,38 +7,36 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { scope 1 (inlined core::num::::unchecked_shl) { // at $DIR/unchecked_shifts.rs:11:7: 11:23 debug self => _1; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL debug rhs => _2; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - let mut _3: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL - let mut _4: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL - let mut _13: u16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _11: u16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL scope 2 { scope 3 (inlined core::num::::unchecked_shl::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL - debug x => _4; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL - let mut _8: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL - let mut _11: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug x => _2; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _6: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _9: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL scope 4 { scope 5 (inlined >::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL - debug self => _4; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + debug self => _2; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL scope 6 (inlined convert::num:: for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL - debug u => _4; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _5: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _6: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _7: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + debug u => _2; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _3: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _4: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _5: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } } scope 7 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL - debug self => _8; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _9: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - let _10: u16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + debug self => _6; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _7: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let _8: u16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL scope 8 { - debug x => _10; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + debug x => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL } } scope 9 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL - debug self => _11; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _12: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _14: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _9; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _10: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _12: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL scope 10 { - debug val => _13; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL + debug val => _11; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL } scope 11 { scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL @@ -49,7 +47,7 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { } } scope 12 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL - debug self => _14; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _12; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL } } } @@ -58,31 +56,27 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { } bb0: { - StorageLive(_13); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageLive(_3); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _3 = (_2,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageLive(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _4 = move (_3.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageLive(_11); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageLive(_6); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageLive(_5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _5 = const 65535_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _6 = Gt(_4, move _5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageDead(_5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - switchInt(move _6) -> [0: bb1, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_11); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_4); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_3); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _3 = const 65535_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _4 = Gt(_2, move _3); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_3); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + switchInt(move _4) -> [0: bb1, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { - StorageLive(_7); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _7 = _4 as u16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _8 = Result::::Ok(move _7); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageDead(_7); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _5 = _2 as u16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _6 = Result::::Ok(move _5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL goto -> bb3; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb2: { - _8 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _6 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL // mir::Constant // + span: no-location // + literal: Const { ty: TryFromIntError, val: Value() } @@ -90,45 +84,43 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { } bb3: { - StorageDead(_6); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageLive(_10); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _9 = discriminant(_8); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - switchInt(move _9) -> [0: bb4, 1: bb5, otherwise: bb9]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_4); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _7 = discriminant(_6); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb9]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb4: { - _10 = move ((_8 as Ok).0: u16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - _11 = Option::::Some(move _10); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + _8 = move ((_6 as Ok).0: u16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _9 = Option::::Some(move _8); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL goto -> bb6; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb5: { - _11 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _9 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL goto -> bb6; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb6: { - StorageDead(_10); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL StorageDead(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageLive(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _12 = discriminant(_11); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - switchInt(move _12) -> [1: bb7, otherwise: bb9]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _10 = discriminant(_9); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _10) -> [1: bb7, otherwise: bb9]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL } bb7: { - _13 = move ((_11 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - StorageDead(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageDead(_11); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageDead(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageDead(_3); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _0 = unchecked_shl::(_1, move _13) -> [return: bb8, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + _11 = move ((_9 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _0 = unchecked_shl::(_1, move _11) -> [return: bb8, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::}, val: Value() } } bb8: { - StorageDead(_13); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + StorageDead(_11); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff index f3d3e6090bb..f20c7da4747 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff @@ -11,35 +11,33 @@ + debug self => _3; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + debug rhs => _4; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + let mut _5: i16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ let mut _6: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ let mut _7: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 2 { + scope 3 (inlined core::num::::unchecked_shr::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ debug x => _7; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ let mut _8: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ let mut _9: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug x => _4; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _6: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _7: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 4 { + scope 5 (inlined >::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ debug self => _7; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ debug self => _4; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + scope 6 (inlined convert::num:: for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL -+ debug u => _7; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _10: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _11: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _12: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ debug u => _4; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _8: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _9: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _10: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + } + scope 7 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ debug self => _9; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL -+ let mut _13: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL -+ let _14: i16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ debug self => _7; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let mut _11: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let _12: i16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + scope 8 { -+ debug x => _14; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ debug x => _12; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + } + } + scope 9 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ debug self => _8; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ let mut _15: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ let mut _16: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _13: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + scope 10 { + debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL + } @@ -52,7 +50,7 @@ + } + } + scope 12 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL -+ debug self => _15; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL + } + } + } @@ -70,18 +68,14 @@ - // + span: $DIR/unchecked_shifts.rs:17:7: 17:20 - // + literal: Const { ty: unsafe fn(i16, u32) -> i16 {core::num::::unchecked_shr}, val: Value() } + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageLive(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ _6 = (_4,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ _7 = move (_6.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageLive(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageLive(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _11 = const 32767_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _10 = Gt(_7, move _11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageDead(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ switchInt(move _10) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _9 = const 32767_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _8 = Gt(_4, move _9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ switchInt(move _8) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { @@ -92,7 +86,7 @@ + } + + bb2: { -+ _9 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _7 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: TryFromIntError, val: Value() } @@ -100,22 +94,22 @@ + } + + bb3: { -+ StorageLive(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _12 = _7 as i16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _9 = Result::::Ok(move _12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageDead(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _10 = _4 as i16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _7 = Result::::Ok(move _10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb4: { -+ StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageLive(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ _13 = discriminant(_9); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL -+ switchInt(move _13) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ StorageDead(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _11 = discriminant(_7); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb5: { -+ _8 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ _6 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + @@ -124,25 +118,23 @@ + } + + bb7: { -+ _14 = move ((_9 as Ok).0: i16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL -+ _8 = Option::::Some(move _14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ _12 = move ((_7 as Ok).0: i16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ _6 = Option::::Some(move _12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb8: { -+ StorageDead(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageDead(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageLive(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ _16 = discriminant(_8); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ switchInt(move _16) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _14) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb9: { -+ _5 = move ((_8 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ StorageDead(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageDead(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _5 = move ((_6 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _0 = unchecked_shr::(_3, move _5) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir index 67f0fe8932f..7f737abb936 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir @@ -7,38 +7,36 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 { scope 1 (inlined core::num::::unchecked_shr) { // at $DIR/unchecked_shifts.rs:17:7: 17:23 debug self => _1; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL debug rhs => _2; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - let mut _3: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL - let mut _4: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL - let mut _13: i16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _11: i16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL scope 2 { scope 3 (inlined core::num::::unchecked_shr::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL - debug x => _4; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL - let mut _8: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL - let mut _11: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug x => _2; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _6: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _9: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL scope 4 { scope 5 (inlined >::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL - debug self => _4; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + debug self => _2; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL scope 6 (inlined convert::num:: for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL - debug u => _4; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _5: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _6: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _7: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + debug u => _2; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _3: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _4: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _5: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } } scope 7 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL - debug self => _8; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _9: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - let _10: i16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + debug self => _6; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _7: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let _8: i16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL scope 8 { - debug x => _10; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + debug x => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL } } scope 9 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL - debug self => _11; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _12: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _14: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _9; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _10: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _12: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL scope 10 { - debug val => _13; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL + debug val => _11; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL } scope 11 { scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL @@ -49,7 +47,7 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 { } } scope 12 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL - debug self => _14; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _12; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL } } } @@ -58,31 +56,27 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 { } bb0: { - StorageLive(_13); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageLive(_3); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _3 = (_2,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageLive(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _4 = move (_3.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageLive(_11); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageLive(_6); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageLive(_5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _5 = const 32767_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _6 = Gt(_4, move _5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageDead(_5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - switchInt(move _6) -> [0: bb1, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_11); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_4); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_3); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _3 = const 32767_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _4 = Gt(_2, move _3); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_3); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + switchInt(move _4) -> [0: bb1, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { - StorageLive(_7); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _7 = _4 as i16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _8 = Result::::Ok(move _7); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageDead(_7); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _5 = _2 as i16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _6 = Result::::Ok(move _5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL goto -> bb3; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb2: { - _8 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _6 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL // mir::Constant // + span: no-location // + literal: Const { ty: TryFromIntError, val: Value() } @@ -90,45 +84,43 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 { } bb3: { - StorageDead(_6); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageLive(_10); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _9 = discriminant(_8); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - switchInt(move _9) -> [0: bb4, 1: bb5, otherwise: bb9]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_4); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _7 = discriminant(_6); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb9]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb4: { - _10 = move ((_8 as Ok).0: i16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - _11 = Option::::Some(move _10); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + _8 = move ((_6 as Ok).0: i16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _9 = Option::::Some(move _8); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL goto -> bb6; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb5: { - _11 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _9 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL goto -> bb6; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb6: { - StorageDead(_10); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL StorageDead(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageLive(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _12 = discriminant(_11); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - switchInt(move _12) -> [1: bb7, otherwise: bb9]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _10 = discriminant(_9); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _10) -> [1: bb7, otherwise: bb9]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL } bb7: { - _13 = move ((_11 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - StorageDead(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageDead(_11); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageDead(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - StorageDead(_3); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _0 = unchecked_shr::(_1, move _13) -> [return: bb8, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + _11 = move ((_9 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _0 = unchecked_shr::(_1, move _11) -> [return: bb8, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::}, val: Value() } } bb8: { - StorageDead(_13); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + StorageDead(_11); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 } diff --git a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir index 50e0538c133..0cf9643dfc2 100644 --- a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir @@ -15,20 +15,18 @@ fn mem_replace(_1: &mut u32, _2: u32) -> u32 { scope 7 (inlined std::ptr::write::) { // at $SRC_DIR/core/src/mem/mod.rs:LL:COL debug dst => _4; // in scope 7 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL debug src => _2; // in scope 7 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - let mut _6: *mut u32; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL scope 8 { scope 9 (inlined std::ptr::write::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL - debug dst => _6; // in scope 9 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug dst => _4; // in scope 9 at $SRC_DIR/core/src/intrinsics.rs:LL:COL } } } } scope 4 (inlined std::ptr::read::) { // at $SRC_DIR/core/src/mem/mod.rs:LL:COL debug src => _3; // in scope 4 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - let mut _5: *const u32; // in scope 4 at $SRC_DIR/core/src/intrinsics.rs:LL:COL scope 5 { scope 6 (inlined std::ptr::read::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL - debug src => _5; // in scope 6 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug src => _3; // in scope 6 at $SRC_DIR/core/src/intrinsics.rs:LL:COL } } } @@ -38,15 +36,11 @@ fn mem_replace(_1: &mut u32, _2: u32) -> u32 { bb0: { StorageLive(_3); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL _3 = &raw const (*_1); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL - StorageLive(_5); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL _0 = (*_3); // scope 5 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - StorageDead(_5); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL StorageDead(_3); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL StorageLive(_4); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL _4 = &raw mut (*_1); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL - StorageLive(_6); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL (*_4) = _2; // scope 8 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - StorageDead(_6); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL StorageDead(_4); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL return; // scope 0 at $DIR/mem_replace.rs:+2:2: +2:2 } diff --git a/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir index 089b0c23e2c..73b5678ce04 100644 --- a/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir @@ -3,24 +3,21 @@ fn ezmap(_1: Option) -> Option { debug x => _1; // in scope 0 at $DIR/simple_option_map.rs:+0:14: +0:15 let mut _0: std::option::Option; // return place in scope 0 at $DIR/simple_option_map.rs:+0:33: +0:44 - let mut _5: i32; // in scope 0 at $DIR/simple_option_map.rs:11:25: 11:29 scope 1 (inlined map::) { // at $DIR/simple_option_map.rs:18:5: 18:22 debug slf => _1; // in scope 1 at $DIR/simple_option_map.rs:6:17: 6:20 debug f => const ZeroSized: [closure@$DIR/simple_option_map.rs:18:12: 18:15]; // in scope 1 at $DIR/simple_option_map.rs:6:33: 6:34 let mut _2: isize; // in scope 1 at $DIR/simple_option_map.rs:11:9: 11:16 let _3: i32; // in scope 1 at $DIR/simple_option_map.rs:11:14: 11:15 - let mut _4: (i32,); // in scope 1 at $DIR/simple_option_map.rs:11:25: 11:29 - let mut _6: i32; // in scope 1 at $DIR/simple_option_map.rs:11:25: 11:29 + let mut _4: i32; // in scope 1 at $DIR/simple_option_map.rs:11:25: 11:29 scope 2 { debug x => _3; // in scope 2 at $DIR/simple_option_map.rs:11:14: 11:15 scope 3 (inlined ezmap::{closure#0}) { // at $DIR/simple_option_map.rs:11:25: 11:29 - debug n => _5; // in scope 3 at $DIR/simple_option_map.rs:+1:13: +1:14 + debug n => _3; // in scope 3 at $DIR/simple_option_map.rs:+1:13: +1:14 } } } bb0: { - StorageLive(_3); // scope 0 at $DIR/simple_option_map.rs:+1:5: +1:22 _2 = discriminant(_1); // scope 1 at $DIR/simple_option_map.rs:10:11: 10:14 switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; // scope 1 at $DIR/simple_option_map.rs:10:5: 10:14 } @@ -32,21 +29,14 @@ fn ezmap(_1: Option) -> Option { bb2: { _3 = ((_1 as Some).0: i32); // scope 1 at $DIR/simple_option_map.rs:11:14: 11:15 - StorageLive(_6); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29 StorageLive(_4); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29 - _4 = (move _3,); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29 - StorageLive(_5); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29 - _5 = move (_4.0: i32); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29 - _6 = Add(_5, const 1_i32); // scope 3 at $DIR/simple_option_map.rs:+1:16: +1:21 - StorageDead(_5); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29 - StorageDead(_4); // scope 2 at $DIR/simple_option_map.rs:11:28: 11:29 - _0 = Option::::Some(move _6); // scope 2 at $DIR/simple_option_map.rs:11:20: 11:30 - StorageDead(_6); // scope 2 at $DIR/simple_option_map.rs:11:29: 11:30 + _4 = Add(_3, const 1_i32); // scope 3 at $DIR/simple_option_map.rs:+1:16: +1:21 + _0 = Option::::Some(move _4); // scope 2 at $DIR/simple_option_map.rs:11:20: 11:30 + StorageDead(_4); // scope 2 at $DIR/simple_option_map.rs:11:29: 11:30 goto -> bb3; // scope 1 at $DIR/simple_option_map.rs:14:1: 14:2 } bb3: { - StorageDead(_3); // scope 0 at $DIR/simple_option_map.rs:+1:5: +1:22 return; // scope 0 at $DIR/simple_option_map.rs:+2:2: +2:2 } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.mir index b05d44f4d60..6c306280536 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.mir @@ -21,19 +21,17 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { debug self => _2; // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL debug slice => _6; // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL let mut _7: *mut u32; // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let mut _10: usize; // in scope 4 at $SRC_DIR/core/src/intrinsics.rs:LL:COL - let mut _11: *mut [u32]; // in scope 4 at $SRC_DIR/core/src/intrinsics.rs:LL:COL scope 5 { debug this => _2; // in scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL scope 6 { scope 7 (inlined >::get_unchecked_mut::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL - debug this => _10; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL - debug slice => _11; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug this => _2; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug slice => _6; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL scope 8 (inlined ptr::mut_ptr::::len) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL - debug self => _11; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - let mut _12: *const [u32]; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _6; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + let mut _10: *const [u32]; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL scope 9 (inlined std::ptr::metadata::<[u32]>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - debug ptr => _12; // in scope 9 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + debug ptr => _10; // in scope 9 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL scope 10 { } } @@ -81,14 +79,10 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { StorageLive(_6); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL _6 = &raw mut (*_1); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL StorageLive(_10); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageLive(_11); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageLive(_12); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL StorageLive(_7); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL _7 = _6 as *mut u32 (PtrToPtr); // scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL _8 = Offset(_7, _2); // scope 13 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL StorageDead(_7); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageDead(_12); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageDead(_11); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL StorageDead(_10); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL StorageDead(_6); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL _9 = &mut (*_8); // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir index 6d9ec5d9a27..727ccc1de53 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir @@ -4,65 +4,63 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) -> debug slice => _1; // in scope 0 at $DIR/slice_index.rs:+0:45: +0:50 debug index => _2; // in scope 0 at $DIR/slice_index.rs:+0:64: +0:69 let mut _0: &mut [u32]; // return place in scope 0 at $DIR/slice_index.rs:+0:88: +0:98 + let mut _3: usize; // in scope 0 at $DIR/slice_index.rs:+1:29: +1:34 + let mut _4: usize; // in scope 0 at $DIR/slice_index.rs:+1:29: +1:34 scope 1 (inlined core::slice::::get_unchecked_mut::>) { // at $DIR/slice_index.rs:26:11: 26:35 debug self => _1; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - debug index => _2; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - let mut _3: *mut [u32]; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - let mut _15: *mut [u32]; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + debug index => std::ops::Range{ .0 => _3, .1 => _4, }; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + let mut _5: *mut [u32]; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + let mut _14: *mut [u32]; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL scope 2 { scope 3 (inlined as SliceIndex<[u32]>>::get_unchecked_mut) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL - debug self => _2; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - debug slice => _3; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let mut _4: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let mut _5: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug self => std::ops::Range{ .0 => _3, .1 => _4, }; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug slice => _5; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL let mut _7: *mut u32; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let mut _8: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let mut _9: *mut u32; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let mut _10: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let _16: std::ops::Range; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let mut _17: std::ops::Range; // in scope 3 at $SRC_DIR/core/src/intrinsics.rs:LL:COL - let mut _18: *mut [u32]; // in scope 3 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + let mut _8: *mut u32; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let mut _9: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let _16: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let _17: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL scope 4 { - debug this => _16; // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug this => std::ops::Range{ .0 => _16, .1 => _17, }; // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL scope 5 { let _6: usize; // in scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL scope 6 { debug new_len => _6; // in scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL scope 11 (inlined ptr::mut_ptr::::as_mut_ptr) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL - debug self => _3; // in scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _5; // in scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL } scope 12 (inlined ptr::mut_ptr::::add) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL debug self => _7; // in scope 12 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - debug count => _8; // in scope 12 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug count => _3; // in scope 12 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL scope 13 { } } scope 14 (inlined slice_from_raw_parts_mut::) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL - debug data => _9; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - debug len => _10; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - let mut _11: *mut (); // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + debug data => _8; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + debug len => _9; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + let mut _10: *mut (); // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL scope 15 (inlined ptr::mut_ptr::::cast::<()>) { // at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - debug self => _9; // in scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _8; // in scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL } scope 16 (inlined std::ptr::from_raw_parts_mut::<[u32]>) { // at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - debug data_address => _11; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - debug metadata => _10; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - let mut _12: *const (); // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - let mut _13: std::ptr::metadata::PtrComponents<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - let mut _14: std::ptr::metadata::PtrRepr<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + debug data_address => _10; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + debug metadata => _9; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + let mut _11: *const (); // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + let mut _12: std::ptr::metadata::PtrComponents<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + let mut _13: std::ptr::metadata::PtrRepr<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL scope 17 { } } } } scope 7 (inlined as SliceIndex<[T]>>::get_unchecked_mut::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL - debug this => _17; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL - debug slice => _18; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug this => std::ops::Range{ .0 => _16, .1 => _17, }; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug slice => _5; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL scope 8 (inlined ptr::mut_ptr::::len) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL - debug self => _18; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - let mut _19: *const [u32]; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _5; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + let mut _15: *const [u32]; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL scope 9 (inlined std::ptr::metadata::<[u32]>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - debug ptr => _19; // in scope 9 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + debug ptr => _15; // in scope 9 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL scope 10 { } } @@ -75,60 +73,51 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) -> } bb0: { + _3 = move (_2.0: usize); // scope 0 at $DIR/slice_index.rs:+1:29: +1:34 + _4 = move (_2.1: usize); // scope 0 at $DIR/slice_index.rs:+1:29: +1:34 + StorageLive(_14); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _5 = &raw mut (*_1); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageLive(_15); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - StorageLive(_3); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - _3 = &raw mut (*_1); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageLive(_16); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageLive(_17); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - StorageLive(_18); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - StorageLive(_19); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageLive(_6); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageLive(_4); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _4 = (_2.1: usize); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageLive(_5); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _5 = (_2.0: usize); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _6 = unchecked_sub::(move _4, move _5) -> [return: bb1, unwind unreachable]; // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _6 = unchecked_sub::(_4, _3) -> [return: bb1, unwind unreachable]; // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/slice/index.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(usize, usize) -> usize {unchecked_sub::}, val: Value() } } bb1: { - StorageDead(_5); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageDead(_4); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageLive(_9); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageLive(_7); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _7 = _3 as *mut u32 (PtrToPtr); // scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL StorageLive(_8); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _8 = (_2.0: usize); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _9 = Offset(_7, _8); // scope 13 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - StorageDead(_8); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageLive(_7); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _7 = _5 as *mut u32 (PtrToPtr); // scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + _8 = Offset(_7, _3); // scope 13 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL StorageDead(_7); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageLive(_10); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _10 = _6; // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageLive(_11); // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - _11 = _9 as *mut () (PtrToPtr); // scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - StorageLive(_14); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageLive(_9); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _9 = _6; // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageLive(_10); // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + _10 = _8 as *mut () (PtrToPtr); // scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL StorageLive(_13); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL StorageLive(_12); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - _12 = _11 as *const () (Pointer(MutToConstPointer)); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - _13 = ptr::metadata::PtrComponents::<[u32]> { data_address: move _12, metadata: _10 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageLive(_11); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + _11 = _10 as *const () (Pointer(MutToConstPointer)); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + _12 = ptr::metadata::PtrComponents::<[u32]> { data_address: move _11, metadata: _9 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageDead(_11); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + _13 = ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _12 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL StorageDead(_12); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - _14 = ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _13 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - StorageDead(_13); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - _15 = (_14.1: *mut [u32]); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - StorageDead(_14); // scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - StorageDead(_11); // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - StorageDead(_10); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _14 = (_13.1: *mut [u32]); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageDead(_13); // scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageDead(_10); // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL StorageDead(_9); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_8); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL StorageDead(_6); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageDead(_19); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - StorageDead(_18); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageDead(_17); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageDead(_16); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - StorageDead(_3); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - _0 = &mut (*_15); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - StorageDead(_15); // scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_15); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _0 = &mut (*_14); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_14); // scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL return; // scope 0 at $DIR/slice_index.rs:+2:2: +2:2 } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir index 0cf1d68d18a..0c18fb84bcd 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir @@ -39,21 +39,20 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { scope 13 (inlined NonNull::::new_unchecked) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL debug ptr => _9; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL let mut _10: *const T; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL - let mut _22: *mut T; // in scope 13 at $SRC_DIR/core/src/intrinsics.rs:LL:COL scope 14 { scope 15 (inlined NonNull::::new_unchecked::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL - debug ptr => _22; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug ptr => _9; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL scope 16 (inlined ptr::mut_ptr::::is_null) { // at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL - debug self => _22; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - let mut _23: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _9; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + let mut _22: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL scope 17 { scope 18 (inlined ptr::mut_ptr::::is_null::runtime_impl) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - debug ptr => _23; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug ptr => _22; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL scope 19 (inlined ptr::mut_ptr::::addr) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - debug self => _23; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _22; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL scope 20 { scope 21 (inlined ptr::mut_ptr::::cast::<()>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - debug self => _23; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _22; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL } } } @@ -122,10 +121,8 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { _9 = _4 as *mut T (PtrToPtr); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL StorageLive(_10); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL StorageLive(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL - StorageLive(_23); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL _10 = _9 as *const T (Pointer(MutToConstPointer)); // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL _11 = NonNull:: { pointer: _10 }; // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL - StorageDead(_23); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL StorageDead(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL StorageDead(_10); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL StorageDead(_9); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir index 4fde50c6fe4..1aa05cbeb97 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir @@ -44,21 +44,20 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { scope 13 (inlined NonNull::::new_unchecked) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL debug ptr => _9; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL let mut _10: *const T; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL - let mut _24: *mut T; // in scope 13 at $SRC_DIR/core/src/intrinsics.rs:LL:COL scope 14 { scope 15 (inlined NonNull::::new_unchecked::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL - debug ptr => _24; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug ptr => _9; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL scope 16 (inlined ptr::mut_ptr::::is_null) { // at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL - debug self => _24; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - let mut _25: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _9; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + let mut _24: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL scope 17 { scope 18 (inlined ptr::mut_ptr::::is_null::runtime_impl) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - debug ptr => _25; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug ptr => _24; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL scope 19 (inlined ptr::mut_ptr::::addr) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - debug self => _25; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _24; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL scope 20 { scope 21 (inlined ptr::mut_ptr::::cast::<()>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - debug self => _25; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _24; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL } } } @@ -134,10 +133,8 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { _9 = _4 as *mut T (PtrToPtr); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL StorageLive(_10); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL StorageLive(_24); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL - StorageLive(_25); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL _10 = _9 as *const T (Pointer(MutToConstPointer)); // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL _11 = NonNull:: { pointer: _10 }; // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL - StorageDead(_25); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL StorageDead(_24); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL StorageDead(_10); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL StorageDead(_9); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL -- cgit 1.4.1-3-g733a5 From bf36193ef6f8bc31cc2ae3ffe8ec9bfe0d3d29a8 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 7 May 2023 03:00:41 -0700 Subject: Add a distinct `OperandValue::ZeroSized` variant for ZSTs These tend to have special handling in a bunch of places anyway, so the variant helps remember that. And I think it's easier to grok than non-Scalar Aggregates sometimes being `Immediates` (like I got wrong and caused 109992). As a minor bonus, it means we don't need to generate poison LLVM values for them to pass around in `OperandValue::Immediate`s. --- compiler/rustc_codegen_gcc/src/builder.rs | 2 +- compiler/rustc_codegen_gcc/src/type_of.rs | 3 +- compiler/rustc_codegen_llvm/src/builder.rs | 2 +- compiler/rustc_codegen_llvm/src/type_of.rs | 3 +- compiler/rustc_codegen_ssa/src/base.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 13 ++++- compiler/rustc_codegen_ssa/src/mir/debuginfo.rs | 3 + compiler/rustc_codegen_ssa/src/mir/mod.rs | 13 ++--- compiler/rustc_codegen_ssa/src/mir/operand.rs | 49 ++++++++-------- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 68 +++++++++++----------- tests/codegen/intrinsics/transmute.rs | 75 +++++++++++++++++++++++-- 11 files changed, 157 insertions(+), 76 deletions(-) (limited to 'tests/codegen') diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 869344ce92d..f9ea0f00456 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -758,7 +758,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { assert_eq!(place.llextra.is_some(), place.layout.is_unsized()); if place.layout.is_zst() { - return OperandRef::new_zst(self, place.layout); + return OperandRef::zero_sized(place.layout); } fn scalar_load_metadata<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, load: RValue<'gcc>, scalar: &abi::Scalar) { diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 5df8c1a209d..30a3fe67b85 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -159,8 +159,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { fn is_gcc_immediate(&self) -> bool { match self.abi { Abi::Scalar(_) | Abi::Vector { .. } => true, - Abi::ScalarPair(..) => false, - Abi::Uninhabited | Abi::Aggregate { .. } => self.is_zst(), + Abi::ScalarPair(..) | Abi::Uninhabited | Abi::Aggregate { .. } => false, } } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 4d0bcd53d15..5968e70b1cc 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -486,7 +486,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { assert_eq!(place.llextra.is_some(), place.layout.is_unsized()); if place.layout.is_zst() { - return OperandRef::new_zst(self, place.layout); + return OperandRef::zero_sized(place.layout); } #[instrument(level = "trace", skip(bx))] diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index e264ce78f0d..a493c9c0548 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -198,8 +198,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { fn is_llvm_immediate(&self) -> bool { match self.abi { Abi::Scalar(_) | Abi::Vector { .. } => true, - Abi::ScalarPair(..) => false, - Abi::Uninhabited | Abi::Aggregate { .. } => self.is_zst(), + Abi::ScalarPair(..) | Abi::Uninhabited | Abi::Aggregate { .. } => false, } } diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 15c7847155d..242d209b684 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -295,7 +295,7 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let (base, info) = match bx.load_operand(src).val { OperandValue::Pair(base, info) => unsize_ptr(bx, base, src_ty, dst_ty, Some(info)), OperandValue::Immediate(base) => unsize_ptr(bx, base, src_ty, dst_ty, None), - OperandValue::Ref(..) => bug!(), + OperandValue::Ref(..) | OperandValue::ZeroSized => bug!(), }; OperandValue::Pair(base, info).store(bx, dst); } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 3f0b64b1103..e0cb26d3ba8 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1,5 +1,5 @@ use super::operand::OperandRef; -use super::operand::OperandValue::{Immediate, Pair, Ref}; +use super::operand::OperandValue::{Immediate, Pair, Ref, ZeroSized}; use super::place::PlaceRef; use super::{CachedLlbb, FunctionCx, LocalRef}; @@ -427,6 +427,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { assert_eq!(align, op.layout.align.abi, "return place is unaligned!"); llval } + ZeroSized => bug!("ZST return value shouldn't be in PassMode::Cast"), }; let ty = bx.cast_backend_type(cast_ty); let addr = bx.pointercast(llslot, bx.type_ptr_to(ty)); @@ -1386,6 +1387,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (llval, align, true) } } + ZeroSized => match arg.mode { + PassMode::Indirect { .. } => { + // Though `extern "Rust"` doesn't pass ZSTs, some ABIs pass + // a pointer for `repr(C)` structs even when empty, so get + // one from an `alloca` (which can be left uninitialized). + let scratch = PlaceRef::alloca(bx, arg.layout); + (scratch.llval, scratch.align, true) + } + _ => bug!("ZST {op:?} wasn't ignored, but was passed with abi {arg:?}"), + }, }; if by_ref && !arg.is_indirect() { diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index bba2800fb05..4f79c6a3d82 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -352,6 +352,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.set_var_name(a, &(name.clone() + ".0")); bx.set_var_name(b, &(name.clone() + ".1")); } + OperandValue::ZeroSized => { + // These never have a value to talk about + } }, LocalRef::PendingOperand => {} } diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 00414003202..2809ec2deb5 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -129,16 +129,13 @@ enum LocalRef<'tcx, V> { PendingOperand, } -impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> { - fn new_operand>( - bx: &mut Bx, - layout: TyAndLayout<'tcx>, - ) -> LocalRef<'tcx, V> { +impl<'tcx, V: CodegenObject> LocalRef<'tcx, V> { + fn new_operand(layout: TyAndLayout<'tcx>) -> LocalRef<'tcx, V> { if layout.is_zst() { // Zero-size temporaries aren't always initialized, which // doesn't matter because they don't contain data, but // we need something in the operand. - LocalRef::Operand(OperandRef::new_zst(bx, layout)) + LocalRef::Operand(OperandRef::zero_sized(layout)) } else { LocalRef::PendingOperand } @@ -249,7 +246,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } } else { debug!("alloc: {:?} -> operand", local); - LocalRef::new_operand(&mut start_bx, layout) + LocalRef::new_operand(layout) } }; @@ -355,7 +352,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let local = |op| LocalRef::Operand(op); match arg.mode { PassMode::Ignore => { - return local(OperandRef::new_zst(bx, arg.layout)); + return local(OperandRef::zero_sized(arg.layout)); } PassMode::Direct(_) => { let llarg = bx.get_param(llarg_idx); diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 4000c9540ce..31c293d7c29 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -45,6 +45,14 @@ pub enum OperandValue { /// as returned by [`LayoutTypeMethods::scalar_pair_element_backend_type`] /// with `immediate: true`. Pair(V, V), + /// A value taking no bytes, and which therefore needs no LLVM value at all. + /// + /// If you ever need a `V` to pass to something, get a fresh poison value + /// from [`ConstMethods::const_poison`]. + /// + /// An `OperandValue` *must* be this variant for any type for which + /// `is_zst` on its `Layout` returns `true`. + ZeroSized, } /// An `OperandRef` is an "SSA" reference to a Rust value, along with @@ -71,15 +79,9 @@ impl fmt::Debug for OperandRef<'_, V> { } impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { - pub fn new_zst>( - bx: &mut Bx, - layout: TyAndLayout<'tcx>, - ) -> OperandRef<'tcx, V> { + pub fn zero_sized(layout: TyAndLayout<'tcx>) -> OperandRef<'tcx, V> { assert!(layout.is_zst()); - OperandRef { - val: OperandValue::Immediate(bx.const_poison(bx.immediate_backend_type(layout))), - layout, - } + OperandRef { val: OperandValue::ZeroSized, layout } } pub fn from_const>( @@ -97,7 +99,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let llval = bx.scalar_to_backend(x, scalar, bx.immediate_backend_type(layout)); OperandValue::Immediate(llval) } - ConstValue::ZeroSized => return OperandRef::new_zst(bx, layout), + ConstValue::ZeroSized => return OperandRef::zero_sized(layout), ConstValue::Slice { data, start, end } => { let Abi::ScalarPair(a_scalar, _) = layout.abi else { bug!("from_const: invalid ScalarPair layout: {:#?}", layout); @@ -178,7 +180,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { ); OperandRef { val: OperandValue::Pair(a_val, b_val), layout } } - _ if layout.is_zst() => OperandRef::new_zst(bx, layout), + _ if layout.is_zst() => OperandRef::zero_sized(layout), _ => { // Neither a scalar nor scalar pair. Load from a place let init = bx.const_data_from_alloc(alloc); @@ -216,6 +218,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { OperandValue::Immediate(llptr) => (llptr, None), OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)), OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self), + OperandValue::ZeroSized => bug!("Deref of ZST operand {:?}", self), }; let layout = cx.layout_of(projected_ty); PlaceRef { llval: llptr, llextra, layout, align: layout.align.abi } @@ -273,9 +276,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let mut val = match (self.val, self.layout.abi) { // If the field is ZST, it has no data. - _ if field.is_zst() => { - return OperandRef::new_zst(bx, field); - } + _ if field.is_zst() => OperandValue::ZeroSized, // Newtype of a scalar, scalar pair or vector. (OperandValue::Immediate(_) | OperandValue::Pair(..), _) @@ -306,6 +307,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { }; match (&mut val, field.abi) { + (OperandValue::ZeroSized, _) => {} ( OperandValue::Immediate(llval), Abi::Scalar(_) | Abi::ScalarPair(..) | Abi::Vector { .. }, @@ -359,8 +361,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { impl<'a, 'tcx, V: CodegenObject> OperandValue { /// Returns an `OperandValue` that's generally UB to use in any way. /// - /// Depending on the `layout`, returns an `Immediate` or `Pair` containing - /// poison value(s), or a `Ref` containing a poison pointer. + /// Depending on the `layout`, returns `ZeroSized` for ZSTs, an `Immediate` or + /// `Pair` containing poison value(s), or a `Ref` containing a poison pointer. /// /// Supports sized types only. pub fn poison>( @@ -368,7 +370,9 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue { layout: TyAndLayout<'tcx>, ) -> OperandValue { assert!(layout.is_sized()); - if bx.cx().is_backend_immediate(layout) { + if layout.is_zst() { + OperandValue::ZeroSized + } else if bx.cx().is_backend_immediate(layout) { let ibty = bx.cx().immediate_backend_type(layout); OperandValue::Immediate(bx.const_poison(ibty)) } else if bx.cx().is_backend_scalar_pair(layout) { @@ -421,12 +425,11 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue { flags: MemFlags, ) { debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest); - // Avoid generating stores of zero-sized values, because the only way to have a zero-sized - // value is through `undef`, and store itself is useless. - if dest.layout.is_zst() { - return; - } match self { + OperandValue::ZeroSized => { + // Avoid generating stores of zero-sized values, because the only way to have a zero-sized + // value is through `undef`/`poison`, and the store itself is useless. + } OperandValue::Ref(r, None, source_align) => { if flags.contains(MemFlags::NONTEMPORAL) { // HACK(nox): This is inefficient but there is no nontemporal memcpy. @@ -527,7 +530,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // checks in `codegen_consume` and `extract_field`. let elem = o.layout.field(bx.cx(), 0); if elem.is_zst() { - o = OperandRef::new_zst(bx, elem); + o = OperandRef::zero_sized(elem); } else { return None; } @@ -561,7 +564,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // ZSTs don't require any actual memory access. if layout.is_zst() { - return OperandRef::new_zst(bx, layout); + return OperandRef::zero_sized(layout); } if let Some(o) = self.maybe_codegen_consume_direct(bx, place_ref) { diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 0255b660380..5241a5aee00 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -70,6 +70,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandValue::Ref(_, Some(_), _) => { bug!("unsized coercion on an unsized rvalue"); } + OperandValue::ZeroSized => { + bug!("unsized coercion on a ZST rvalue"); + } } } @@ -165,11 +168,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } match src.val { - OperandValue::Ref(..) => { + OperandValue::Ref(..) | OperandValue::ZeroSized => { span_bug!( self.mir.span, "Operand path should have handled transmute \ - from `Ref` {src:?} to place {dst:?}" + from {src:?} to place {dst:?}" ); } OperandValue::Immediate(..) | OperandValue::Pair(..) => { @@ -220,17 +223,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let fake_place = PlaceRef::new_sized_aligned(cast_ptr, cast, align); Some(bx.load_operand(fake_place).val) } + OperandValue::ZeroSized => { + let OperandValueKind::ZeroSized = operand_kind else { + bug!("Found {operand_kind:?} for operand {operand:?}"); + }; + if let OperandValueKind::ZeroSized = cast_kind { + Some(OperandValue::ZeroSized) + } else { + None + } + } OperandValue::Immediate(imm) => { let OperandValueKind::Immediate(in_scalar) = operand_kind else { bug!("Found {operand_kind:?} for operand {operand:?}"); }; - if let OperandValueKind::Immediate(out_scalar) = cast_kind { - match (in_scalar, out_scalar) { - (ScalarOrZst::Zst, ScalarOrZst::Zst) => { - Some(OperandRef::new_zst(bx, cast).val) - } - (ScalarOrZst::Scalar(in_scalar), ScalarOrZst::Scalar(out_scalar)) - if in_scalar.size(self.cx) == out_scalar.size(self.cx) => + if let OperandValueKind::Immediate(out_scalar) = cast_kind + && in_scalar.size(self.cx) == out_scalar.size(self.cx) { let operand_bty = bx.backend_type(operand.layout); let cast_bty = bx.backend_type(cast); @@ -242,9 +250,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { out_scalar, cast_bty, ))) - } - _ => None, - } } else { None } @@ -457,6 +462,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandValue::Ref(..) => { bug!("by-ref operand {:?} in `codegen_rvalue_operand`", operand); } + OperandValue::ZeroSized => { + bug!("zero-sized operand {:?} in `codegen_rvalue_operand`", operand); + } }; let (lldata, llextra) = base::unsize_ptr(bx, lldata, operand.layout.ty, cast.ty, llextra); @@ -490,6 +498,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandValue::Ref(_, _, _) => todo!(), OperandValue::Immediate(v) => (v, None), OperandValue::Pair(v, l) => (v, Some(l)), + OperandValue::ZeroSized => bug!("ZST -- which is not PointerLike -- in DynStar"), }; let (lldata, llextra) = base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra); @@ -718,7 +727,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // According to `rvalue_creates_operand`, only ZST // aggregate rvalues are allowed to be operands. let ty = rvalue.ty(self.mir, self.cx.tcx()); - OperandRef::new_zst(bx, self.cx.layout_of(self.monomorphize(ty))) + OperandRef::zero_sized(self.cx.layout_of(self.monomorphize(ty))) } mir::Rvalue::ShallowInitBox(ref operand, content_ty) => { let operand = self.codegen_operand(bx, operand); @@ -936,6 +945,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Can always load from a pointer as needed (OperandValueKind::Ref, _) => true, + // ZST-to-ZST is the easiest thing ever + (OperandValueKind::ZeroSized, OperandValueKind::ZeroSized) => true, + + // But if only one of them is a ZST the sizes can't match + (OperandValueKind::ZeroSized, _) | (_, OperandValueKind::ZeroSized) => false, + // Need to generate an `alloc` to get a pointer from an immediate (OperandValueKind::Immediate(..) | OperandValueKind::Pair(..), OperandValueKind::Ref) => false, @@ -979,12 +994,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { /// Gets which variant of [`OperandValue`] is expected for a particular type. fn value_kind(&self, layout: TyAndLayout<'tcx>) -> OperandValueKind { - if self.cx.is_backend_immediate(layout) { + if layout.is_zst() { + OperandValueKind::ZeroSized + } else if self.cx.is_backend_immediate(layout) { debug_assert!(!self.cx.is_backend_scalar_pair(layout)); OperandValueKind::Immediate(match layout.abi { - abi::Abi::Scalar(s) => ScalarOrZst::Scalar(s), - abi::Abi::Vector { element, .. } => ScalarOrZst::Scalar(element), - _ if layout.is_zst() => ScalarOrZst::Zst, + abi::Abi::Scalar(s) => s, + abi::Abi::Vector { element, .. } => element, x => span_bug!(self.mir.span, "Couldn't translate {x:?} as backend immediate"), }) } else if self.cx.is_backend_scalar_pair(layout) { @@ -1007,21 +1023,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { #[derive(Debug, Copy, Clone)] enum OperandValueKind { Ref, - Immediate(ScalarOrZst), + Immediate(abi::Scalar), Pair(abi::Scalar, abi::Scalar), -} - -#[derive(Debug, Copy, Clone)] -enum ScalarOrZst { - Zst, - Scalar(abi::Scalar), -} - -impl ScalarOrZst { - pub fn size(self, cx: &impl abi::HasDataLayout) -> abi::Size { - match self { - ScalarOrZst::Zst => abi::Size::ZERO, - ScalarOrZst::Scalar(s) => s.size(cx), - } - } + ZeroSized, } diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index 664e697c2a5..fe42494000e 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -14,10 +14,10 @@ use std::intrinsics::{transmute, transmute_unchecked}; // Some of these need custom MIR to not get removed by MIR optimizations. use std::intrinsics::mir::*; -enum Never {} +pub enum ZstNever {} #[repr(align(2))] -pub struct BigNever(Never, u16, Never); +pub struct BigNever(ZstNever, u16, ZstNever); #[repr(align(8))] pub struct Scalar64(i64); @@ -56,11 +56,13 @@ pub unsafe fn check_bigger_array(x: [u32; 3]) -> [u32; 7] { transmute_unchecked(x) } -// CHECK-LABEL: @check_to_uninhabited( +// CHECK-LABEL: @check_to_empty_array( #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] -pub unsafe fn check_to_uninhabited(x: u16) -> BigNever { +pub unsafe fn check_to_empty_array(x: [u32; 5]) -> [u32; 0] { + // CHECK-NOT: trap // CHECK: call void @llvm.trap + // CHECK-NOT: trap mir!{ { RET = CastTransmute(x); @@ -69,6 +71,37 @@ pub unsafe fn check_to_uninhabited(x: u16) -> BigNever { } } +// CHECK-LABEL: @check_from_empty_array( +#[no_mangle] +#[custom_mir(dialect = "runtime", phase = "optimized")] +pub unsafe fn check_from_empty_array(x: [u32; 0]) -> [u32; 5] { + // CHECK-NOT: trap + // CHECK: call void @llvm.trap + // CHECK-NOT: trap + mir!{ + { + RET = CastTransmute(x); + Return() + } + } +} + +// CHECK-LABEL: @check_to_uninhabited( +#[no_mangle] +#[custom_mir(dialect = "runtime", phase = "optimized")] +pub unsafe fn check_to_uninhabited(x: u16) { + // CHECK-NOT: trap + // CHECK: call void @llvm.trap + // CHECK-NOT: trap + mir!{ + let temp: BigNever; + { + temp = CastTransmute(x); + Return() + } + } +} + // CHECK-LABEL: @check_from_uninhabited( #[no_mangle] #[custom_mir(dialect = "runtime", phase = "optimized")] @@ -366,6 +399,40 @@ pub unsafe fn check_issue_109992(x: ()) -> [(); 1] { } } +// CHECK-LABEL: @check_unit_to_never( +#[no_mangle] +#[custom_mir(dialect = "runtime", phase = "optimized")] +pub unsafe fn check_unit_to_never(x: ()) { + // This uses custom MIR to avoid MIR optimizations having removed ZST ops. + + // CHECK-NOT: trap + // CHECK: call void @llvm.trap + // CHECK-NOT: trap + mir!{ + let temp: ZstNever; + { + temp = CastTransmute(x); + Return() + } + } +} + +// CHECK-LABEL: @check_unit_from_never( +#[no_mangle] +#[custom_mir(dialect = "runtime", phase = "optimized")] +pub unsafe fn check_unit_from_never(x: ZstNever) -> () { + // This uses custom MIR to avoid MIR optimizations having removed ZST ops. + + // CHECK: start + // CHECK-NEXT: ret void + mir!{ + { + RET = CastTransmute(x); + Return() + } + } +} + // CHECK-LABEL: @check_maybe_uninit_pair(i16 %x.0, i64 %x.1) #[no_mangle] pub unsafe fn check_maybe_uninit_pair( -- cgit 1.4.1-3-g733a5