diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 283ed94b61513..71bec38c405d8 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1366,57 +1366,108 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { return self.new_opaque(); } - let mut was_updated = false; - - // If that cast just casts away the metadata again, - if let PtrToPtr = kind - && let Value::Aggregate(AggregateTy::RawPtr { data_pointer_ty, .. }, _, fields) = - self.get(value) - && let ty::RawPtr(to_pointee, _) = to.kind() - && to_pointee.is_sized(self.tcx, self.typing_env()) - { - from = *data_pointer_ty; - value = fields[0]; - was_updated = true; - if *data_pointer_ty == to { - return Some(fields[0]); + let mut was_ever_updated = false; + loop { + let mut was_updated_this_iteration = false; + + // Transmuting between raw pointers is just a pointer cast so long as + // they have the same metadata type (like `*const i32` <=> `*mut u64` + // or `*mut [i32]` <=> `*const [u64]`), including the common special + // case of `*const T` <=> `*mut T`. + if let Transmute = kind + && from.is_unsafe_ptr() + && to.is_unsafe_ptr() + && self.pointers_have_same_metadata(from, to) + { + *kind = PtrToPtr; + was_updated_this_iteration = true; } - } - // PtrToPtr-then-PtrToPtr can skip the intermediate step - if let PtrToPtr = kind - && let Value::Cast { kind: inner_kind, value: inner_value, from: inner_from, to: _ } = - *self.get(value) - && let PtrToPtr = inner_kind - { - from = inner_from; - value = inner_value; - was_updated = true; - if inner_from == to { - return Some(inner_value); + // If a cast just casts away the metadata again, then we can get it by + // casting the original thin pointer passed to `from_raw_parts` + if let PtrToPtr = kind + && let Value::Aggregate(AggregateTy::RawPtr { data_pointer_ty, .. }, _, fields) = + self.get(value) + && let ty::RawPtr(to_pointee, _) = to.kind() + && to_pointee.is_sized(self.tcx, self.typing_env()) + { + from = *data_pointer_ty; + value = fields[0]; + was_updated_this_iteration = true; + if *data_pointer_ty == to { + return Some(fields[0]); + } } - } - // PtrToPtr-then-Transmute can just transmute the original, so long as the - // PtrToPtr didn't change metadata (and thus the size of the pointer) - if let Transmute = kind - && let Value::Cast { - kind: PtrToPtr, + // Aggregate-then-Transmute can just transmute the original field value, + // so long as the bytes of a value from only from a single field. + if let Transmute = kind + && let Value::Aggregate(_aggregate_ty, variant_idx, field_values) = self.get(value) + && let Some((field_idx, field_ty)) = + self.value_is_all_in_one_field(from, *variant_idx) + { + from = field_ty; + value = field_values[field_idx.as_usize()]; + was_updated_this_iteration = true; + if field_ty == to { + return Some(value); + } + } + + // Various cast-then-cast cases can be simplified. + if let Value::Cast { + kind: inner_kind, value: inner_value, from: inner_from, to: inner_to, } = *self.get(value) - && self.pointers_have_same_metadata(inner_from, inner_to) - { - from = inner_from; - value = inner_value; - was_updated = true; - if inner_from == to { - return Some(inner_value); + { + let new_kind = match (inner_kind, *kind) { + // Even if there's a narrowing cast in here that's fine, because + // things like `*mut [i32] -> *mut i32 -> *const i32` and + // `*mut [i32] -> *const [i32] -> *const i32` can skip the middle in MIR. + (PtrToPtr, PtrToPtr) => Some(PtrToPtr), + // PtrToPtr-then-Transmute is fine so long as the pointer cast is identity: + // `*const T -> *mut T -> NonNull` is fine, but we need to check for narrowing + // to skip things like `*const [i32] -> *const i32 -> NonNull`. + (PtrToPtr, Transmute) + if self.pointers_have_same_metadata(inner_from, inner_to) => + { + Some(Transmute) + } + // Similarly, for Transmute-then-PtrToPtr. Note that we need to check different + // variables for their metadata, and thus this can't merge with the previous arm. + (Transmute, PtrToPtr) if self.pointers_have_same_metadata(from, to) => { + Some(Transmute) + } + // If would be legal to always do this, but we don't want to hide information + // from the backend that it'd otherwise be able to use for optimizations. + (Transmute, Transmute) + if !self.type_may_have_niche_of_interest_to_backend(inner_to) => + { + Some(Transmute) + } + _ => None, + }; + if let Some(new_kind) = new_kind { + *kind = new_kind; + from = inner_from; + value = inner_value; + was_updated_this_iteration = true; + if inner_from == to { + return Some(inner_value); + } + } + } + + if was_updated_this_iteration { + was_ever_updated = true; + } else { + break; } } - if was_updated && let Some(op) = self.try_as_operand(value, location) { + if was_ever_updated && let Some(op) = self.try_as_operand(value, location) { *operand = op; } @@ -1438,6 +1489,54 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { false } } + + /// Returns `false` if we know for sure that this type has no interesting niche, + /// and thus we can skip transmuting through it without worrying. + /// + /// The backend will emit `assume`s when transmuting between types with niches, + /// so we want to preserve `i32 -> char -> u32` so that that data is around, + /// but it's fine to skip whole-range-is-value steps like `A -> u32 -> B`. + fn type_may_have_niche_of_interest_to_backend(&self, ty: Ty<'tcx>) -> bool { + let Ok(layout) = self.ecx.layout_of(ty) else { + // If it's too generic or something, then assume it might be interesting later. + return true; + }; + + match layout.backend_repr { + BackendRepr::Uninhabited => true, + BackendRepr::Scalar(a) => !a.is_always_valid(&self.ecx), + BackendRepr::ScalarPair(a, b) => { + !a.is_always_valid(&self.ecx) || !b.is_always_valid(&self.ecx) + } + BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => false, + } + } + + fn value_is_all_in_one_field( + &self, + ty: Ty<'tcx>, + variant: VariantIdx, + ) -> Option<(FieldIdx, Ty<'tcx>)> { + if let Ok(layout) = self.ecx.layout_of(ty) + && let abi::Variants::Single { index } = layout.variants + && index == variant + && let Some((field_idx, field_layout)) = layout.non_1zst_field(&self.ecx) + && layout.size == field_layout.size + { + // We needed to check the variant to avoid trying to read the tag + // field from an enum where no fields have variants, since that tag + // field isn't in the `Aggregate` from which we're getting values. + Some((FieldIdx::from_usize(field_idx), field_layout.ty)) + } else if let ty::Adt(adt, args) = ty.kind() + && adt.is_struct() + && adt.repr().transparent() + && let [single_field] = adt.non_enum_variant().fields.raw.as_slice() + { + Some((FieldIdx::ZERO, single_field.ty(self.tcx, args))) + } else { + None + } + } } fn op_to_prop_const<'tcx>( diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 1a65affe8121a..9e024508c5828 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -173,29 +173,6 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { *kind = CastKind::IntToInt; return; } - - // Transmuting a transparent struct/union to a field's type is a projection - if let ty::Adt(adt_def, args) = operand_ty.kind() - && adt_def.repr().transparent() - && (adt_def.is_struct() || adt_def.is_union()) - && let Some(place) = operand.place() - { - let variant = adt_def.non_enum_variant(); - for (i, field) in variant.fields.iter_enumerated() { - let field_ty = field.ty(self.tcx, args); - if field_ty == *cast_ty { - let place = place - .project_deeper(&[ProjectionElem::Field(i, *cast_ty)], self.tcx); - let operand = if operand.is_move() { - Operand::Move(place) - } else { - Operand::Copy(place) - }; - *rvalue = Rvalue::Use(operand); - return; - } - } - } } } } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff index 4097e060f4d47..5ea9902b26251 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff @@ -51,7 +51,6 @@ StorageLive(_7); _7 = const 1_usize; _6 = const {0x1 as *mut [bool; 0]}; - StorageDead(_7); StorageLive(_11); StorageLive(_8); _8 = UbChecks(); @@ -79,6 +78,7 @@ _11 = const {0x1 as *const [bool; 0]}; _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_11); + StorageDead(_7); StorageDead(_6); _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff index ff44d0df5e3e9..cc5a41a7f63b1 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff @@ -51,7 +51,6 @@ StorageLive(_7); _7 = const 1_usize; _6 = const {0x1 as *mut [bool; 0]}; - StorageDead(_7); StorageLive(_11); StorageLive(_8); _8 = UbChecks(); @@ -83,6 +82,7 @@ _11 = const {0x1 as *const [bool; 0]}; _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_11); + StorageDead(_7); StorageDead(_6); _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff index 3662c3b59d271..3d398fbea7935 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff @@ -51,7 +51,6 @@ StorageLive(_7); _7 = const 1_usize; _6 = const {0x1 as *mut [bool; 0]}; - StorageDead(_7); StorageLive(_11); StorageLive(_8); _8 = UbChecks(); @@ -79,6 +78,7 @@ _11 = const {0x1 as *const [bool; 0]}; _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_11); + StorageDead(_7); StorageDead(_6); _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff index 68dee57dee9e0..dc99c3f7a8c9b 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff @@ -51,7 +51,6 @@ StorageLive(_7); _7 = const 1_usize; _6 = const {0x1 as *mut [bool; 0]}; - StorageDead(_7); StorageLive(_11); StorageLive(_8); _8 = UbChecks(); @@ -83,6 +82,7 @@ _11 = const {0x1 as *const [bool; 0]}; _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_11); + StorageDead(_7); StorageDead(_6); _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff index e62fcb66e3a6d..6a3ec54306994 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff @@ -53,7 +53,6 @@ - _6 = copy _7 as *mut [bool; 0] (Transmute); + _7 = const 1_usize; + _6 = const {0x1 as *mut [bool; 0]}; - StorageDead(_7); StorageLive(_11); StorageLive(_8); _8 = UbChecks(); @@ -67,7 +66,7 @@ bb2: { StorageLive(_10); -- _10 = copy _6 as *mut () (PtrToPtr); +- _10 = copy _7 as *mut () (Transmute); - _9 = NonNull::::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable]; + _10 = const {0x1 as *mut ()}; + _9 = NonNull::::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb3, unwind unreachable]; @@ -80,11 +79,12 @@ bb4: { StorageDead(_8); -- _11 = copy _6 as *const [bool; 0] (PtrToPtr); +- _11 = copy _7 as *const [bool; 0] (Transmute); - _5 = NonNull::<[bool; 0]> { pointer: copy _11 }; + _11 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_11); + StorageDead(_7); StorageDead(_6); - _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; + _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff index 8183abd315ae5..9471ad47cd9df 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff @@ -53,7 +53,6 @@ - _6 = copy _7 as *mut [bool; 0] (Transmute); + _7 = const 1_usize; + _6 = const {0x1 as *mut [bool; 0]}; - StorageDead(_7); StorageLive(_11); StorageLive(_8); _8 = UbChecks(); @@ -71,7 +70,7 @@ bb3: { StorageLive(_10); -- _10 = copy _6 as *mut () (PtrToPtr); +- _10 = copy _7 as *mut () (Transmute); - _9 = NonNull::::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable]; + _10 = const {0x1 as *mut ()}; + _9 = NonNull::::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb4, unwind unreachable]; @@ -84,11 +83,12 @@ bb5: { StorageDead(_8); -- _11 = copy _6 as *const [bool; 0] (PtrToPtr); +- _11 = copy _7 as *const [bool; 0] (Transmute); - _5 = NonNull::<[bool; 0]> { pointer: copy _11 }; + _11 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_11); + StorageDead(_7); StorageDead(_6); - _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; + _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff index 4fa6ef29e0697..187927b8ecab7 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff @@ -53,7 +53,6 @@ - _6 = copy _7 as *mut [bool; 0] (Transmute); + _7 = const 1_usize; + _6 = const {0x1 as *mut [bool; 0]}; - StorageDead(_7); StorageLive(_11); StorageLive(_8); _8 = UbChecks(); @@ -67,7 +66,7 @@ bb2: { StorageLive(_10); -- _10 = copy _6 as *mut () (PtrToPtr); +- _10 = copy _7 as *mut () (Transmute); - _9 = NonNull::::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable]; + _10 = const {0x1 as *mut ()}; + _9 = NonNull::::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb3, unwind unreachable]; @@ -80,11 +79,12 @@ bb4: { StorageDead(_8); -- _11 = copy _6 as *const [bool; 0] (PtrToPtr); +- _11 = copy _7 as *const [bool; 0] (Transmute); - _5 = NonNull::<[bool; 0]> { pointer: copy _11 }; + _11 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_11); + StorageDead(_7); StorageDead(_6); - _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; + _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff index 753292045632f..031c021ba5abf 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff @@ -53,7 +53,6 @@ - _6 = copy _7 as *mut [bool; 0] (Transmute); + _7 = const 1_usize; + _6 = const {0x1 as *mut [bool; 0]}; - StorageDead(_7); StorageLive(_11); StorageLive(_8); _8 = UbChecks(); @@ -71,7 +70,7 @@ bb3: { StorageLive(_10); -- _10 = copy _6 as *mut () (PtrToPtr); +- _10 = copy _7 as *mut () (Transmute); - _9 = NonNull::::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable]; + _10 = const {0x1 as *mut ()}; + _9 = NonNull::::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb4, unwind unreachable]; @@ -84,11 +83,12 @@ bb5: { StorageDead(_8); -- _11 = copy _6 as *const [bool; 0] (PtrToPtr); +- _11 = copy _7 as *const [bool; 0] (Transmute); - _5 = NonNull::<[bool; 0]> { pointer: copy _11 }; + _11 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_11); + StorageDead(_7); StorageDead(_6); - _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; + _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; diff --git a/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-abort.diff b/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-abort.diff new file mode 100644 index 0000000000000..5ae575f300afb --- /dev/null +++ b/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-abort.diff @@ -0,0 +1,340 @@ +- // MIR for `aggregate_struct_then_transmute` before GVN ++ // MIR for `aggregate_struct_then_transmute` after GVN + + fn aggregate_struct_then_transmute(_1: u16, _2: *const u8) -> () { + debug id => _1; + debug thin => _2; + let mut _0: (); + let _3: MyId; + let mut _4: u16; + let _5: (); + let mut _6: u16; + let mut _7: MyId; + let mut _9: u16; + let mut _10: std::marker::PhantomData; + let _11: (); + let mut _12: u16; + let mut _13: TypedId; + let mut _15: u16; + let _16: (); + let mut _17: u16; + let mut _18: std::result::Result; + let mut _20: u16; + let _21: (); + let mut _22: u32; + let mut _23: std::option::Option; + let mut _25: u16; + let _26: (); + let mut _27: i16; + let mut _28: MyId; + let mut _30: u16; + let mut _31: u16; + let _32: (); + let mut _33: u32; + let mut _34: aggregate_struct_then_transmute::Pair; + let mut _36: u16; + let mut _37: u16; + let _38: (); + let mut _39: u16; + let mut _40: aggregate_struct_then_transmute::Pair; + let mut _42: u16; + let _43: (); + let mut _44: u16; + let mut _45: (u16,); + let mut _47: u16; + let _48: (); + let mut _49: u16; + let mut _50: [u16; 1]; + let mut _52: *const u8; + let mut _53: (); + let _54: (); + let mut _55: *const u8; + let mut _56: *const i32; + scope 1 { + debug a => _3; + let _8: TypedId; + scope 2 { + debug b => _8; + let _14: std::result::Result; + scope 3 { + debug c => _14; + let _19: std::option::Option; + scope 4 { + debug d => _19; + let _24: MyId; + scope 5 { + debug e => _24; + let _29: aggregate_struct_then_transmute::Pair; + scope 6 { + debug f => _29; + let _35: aggregate_struct_then_transmute::Pair; + scope 7 { + debug g => _35; + let _41: (u16,); + scope 8 { + debug h => _41; + let _46: [u16; 1]; + scope 9 { + debug i => _46; + let _51: *const i32; + scope 10 { + debug j => _51; + } + } + } + } + } + } + } + } + } + } + + bb0: { +- StorageLive(_3); ++ nop; + StorageLive(_4); + _4 = copy _1; +- _3 = MyId(move _4); ++ _3 = MyId(copy _1); + StorageDead(_4); + StorageLive(_5); + StorageLive(_6); + StorageLive(_7); +- _7 = move _3; +- _6 = move _7 as u16 (Transmute); ++ _7 = copy _3; ++ _6 = copy _1; + StorageDead(_7); +- _5 = opaque::(move _6) -> [return: bb1, unwind unreachable]; ++ _5 = opaque::(copy _1) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_6); + StorageDead(_5); +- StorageLive(_8); ++ nop; + StorageLive(_9); + _9 = copy _1; + StorageLive(_10); +- _10 = PhantomData::; +- _8 = TypedId::(move _9, move _10); ++ _10 = const PhantomData::; ++ _8 = TypedId::(copy _1, const PhantomData::); + StorageDead(_10); + StorageDead(_9); + StorageLive(_11); + StorageLive(_12); + StorageLive(_13); +- _13 = move _8; +- _12 = move _13 as u16 (Transmute); ++ _13 = copy _8; ++ _12 = copy _1; + StorageDead(_13); +- _11 = opaque::(move _12) -> [return: bb2, unwind unreachable]; ++ _11 = opaque::(copy _1) -> [return: bb2, unwind unreachable]; + } + + bb2: { + StorageDead(_12); + StorageDead(_11); +- StorageLive(_14); ++ nop; + StorageLive(_15); + _15 = copy _1; +- _14 = Result::::Err(move _15); ++ _14 = Result::::Err(copy _1); + StorageDead(_15); + StorageLive(_16); + StorageLive(_17); + StorageLive(_18); +- _18 = move _14; +- _17 = move _18 as u16 (Transmute); ++ _18 = copy _14; ++ _17 = copy _1; + StorageDead(_18); +- _16 = opaque::(move _17) -> [return: bb3, unwind unreachable]; ++ _16 = opaque::(copy _1) -> [return: bb3, unwind unreachable]; + } + + bb3: { + StorageDead(_17); + StorageDead(_16); +- StorageLive(_19); ++ nop; + StorageLive(_20); + _20 = copy _1; +- _19 = Option::::Some(move _20); ++ _19 = Option::::Some(copy _1); + StorageDead(_20); + StorageLive(_21); + StorageLive(_22); + StorageLive(_23); + _23 = copy _19; +- _22 = move _23 as u32 (Transmute); ++ _22 = copy _19 as u32 (Transmute); + StorageDead(_23); + _21 = opaque::(move _22) -> [return: bb4, unwind unreachable]; + } + + bb4: { + StorageDead(_22); + StorageDead(_21); + StorageLive(_24); + StorageLive(_25); + _25 = copy _1; +- _24 = MyId(move _25); ++ _24 = copy _3; + StorageDead(_25); + StorageLive(_26); + StorageLive(_27); + StorageLive(_28); +- _28 = move _24; +- _27 = move _28 as i16 (Transmute); ++ _28 = copy _3; ++ _27 = copy _1 as i16 (Transmute); + StorageDead(_28); + _26 = opaque::(move _27) -> [return: bb5, unwind unreachable]; + } + + bb5: { + StorageDead(_27); + StorageDead(_26); +- StorageLive(_29); ++ nop; + StorageLive(_30); + _30 = copy _1; + StorageLive(_31); + _31 = copy _1; +- _29 = Pair(move _30, move _31); ++ _29 = Pair(copy _1, copy _1); + StorageDead(_31); + StorageDead(_30); + StorageLive(_32); + StorageLive(_33); + StorageLive(_34); +- _34 = move _29; +- _33 = move _34 as u32 (Transmute); ++ _34 = copy _29; ++ _33 = copy _29 as u32 (Transmute); + StorageDead(_34); + _32 = opaque::(move _33) -> [return: bb6, unwind unreachable]; + } + + bb6: { + StorageDead(_33); + StorageDead(_32); + StorageLive(_35); + StorageLive(_36); + _36 = copy _1; + StorageLive(_37); + _37 = copy _1; +- _35 = Pair(move _36, move _37); ++ _35 = copy _29; + StorageDead(_37); + StorageDead(_36); + StorageLive(_38); + StorageLive(_39); + StorageLive(_40); +- _40 = move _35; +- _39 = move _40 as u16 (Transmute); ++ _40 = copy _29; ++ _39 = copy _29 as u16 (Transmute); + StorageDead(_40); + _38 = opaque::(move _39) -> [return: bb7, unwind unreachable]; + } + + bb7: { + StorageDead(_39); + StorageDead(_38); +- StorageLive(_41); ++ nop; + StorageLive(_42); + _42 = copy _1; +- _41 = (move _42,); ++ _41 = (copy _1,); + StorageDead(_42); + StorageLive(_43); + StorageLive(_44); + StorageLive(_45); + _45 = copy _41; +- _44 = move _45 as u16 (Transmute); ++ _44 = copy _1; + StorageDead(_45); +- _43 = opaque::(move _44) -> [return: bb8, unwind unreachable]; ++ _43 = opaque::(copy _1) -> [return: bb8, unwind unreachable]; + } + + bb8: { + StorageDead(_44); + StorageDead(_43); +- StorageLive(_46); ++ nop; + StorageLive(_47); + _47 = copy _1; +- _46 = [move _47]; ++ _46 = [copy _1]; + StorageDead(_47); + StorageLive(_48); + StorageLive(_49); + StorageLive(_50); + _50 = copy _46; +- _49 = move _50 as u16 (Transmute); ++ _49 = copy _1; + StorageDead(_50); +- _48 = opaque::(move _49) -> [return: bb9, unwind unreachable]; ++ _48 = opaque::(copy _1) -> [return: bb9, unwind unreachable]; + } + + bb9: { + StorageDead(_49); + StorageDead(_48); +- StorageLive(_51); ++ nop; + StorageLive(_52); + _52 = copy _2; + StorageLive(_53); +- _53 = (); +- _51 = *const i32 from (move _52, move _53); ++ _53 = const (); ++ _51 = *const i32 from (copy _2, const ()); + StorageDead(_53); + StorageDead(_52); + StorageLive(_54); + StorageLive(_55); + StorageLive(_56); + _56 = copy _51; +- _55 = move _56 as *const u8 (Transmute); ++ _55 = copy _2; + StorageDead(_56); +- _54 = opaque::<*const u8>(move _55) -> [return: bb10, unwind unreachable]; ++ _54 = opaque::<*const u8>(copy _2) -> [return: bb10, unwind unreachable]; + } + + bb10: { + StorageDead(_55); + StorageDead(_54); + _0 = const (); +- StorageDead(_51); +- StorageDead(_46); +- StorageDead(_41); ++ nop; ++ nop; ++ nop; + StorageDead(_35); +- StorageDead(_29); ++ nop; + StorageDead(_24); +- StorageDead(_19); +- StorageDead(_14); +- StorageDead(_8); +- StorageDead(_3); ++ nop; ++ nop; ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-unwind.diff b/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-unwind.diff new file mode 100644 index 0000000000000..3119a93fb8912 --- /dev/null +++ b/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-unwind.diff @@ -0,0 +1,340 @@ +- // MIR for `aggregate_struct_then_transmute` before GVN ++ // MIR for `aggregate_struct_then_transmute` after GVN + + fn aggregate_struct_then_transmute(_1: u16, _2: *const u8) -> () { + debug id => _1; + debug thin => _2; + let mut _0: (); + let _3: MyId; + let mut _4: u16; + let _5: (); + let mut _6: u16; + let mut _7: MyId; + let mut _9: u16; + let mut _10: std::marker::PhantomData; + let _11: (); + let mut _12: u16; + let mut _13: TypedId; + let mut _15: u16; + let _16: (); + let mut _17: u16; + let mut _18: std::result::Result; + let mut _20: u16; + let _21: (); + let mut _22: u32; + let mut _23: std::option::Option; + let mut _25: u16; + let _26: (); + let mut _27: i16; + let mut _28: MyId; + let mut _30: u16; + let mut _31: u16; + let _32: (); + let mut _33: u32; + let mut _34: aggregate_struct_then_transmute::Pair; + let mut _36: u16; + let mut _37: u16; + let _38: (); + let mut _39: u16; + let mut _40: aggregate_struct_then_transmute::Pair; + let mut _42: u16; + let _43: (); + let mut _44: u16; + let mut _45: (u16,); + let mut _47: u16; + let _48: (); + let mut _49: u16; + let mut _50: [u16; 1]; + let mut _52: *const u8; + let mut _53: (); + let _54: (); + let mut _55: *const u8; + let mut _56: *const i32; + scope 1 { + debug a => _3; + let _8: TypedId; + scope 2 { + debug b => _8; + let _14: std::result::Result; + scope 3 { + debug c => _14; + let _19: std::option::Option; + scope 4 { + debug d => _19; + let _24: MyId; + scope 5 { + debug e => _24; + let _29: aggregate_struct_then_transmute::Pair; + scope 6 { + debug f => _29; + let _35: aggregate_struct_then_transmute::Pair; + scope 7 { + debug g => _35; + let _41: (u16,); + scope 8 { + debug h => _41; + let _46: [u16; 1]; + scope 9 { + debug i => _46; + let _51: *const i32; + scope 10 { + debug j => _51; + } + } + } + } + } + } + } + } + } + } + + bb0: { +- StorageLive(_3); ++ nop; + StorageLive(_4); + _4 = copy _1; +- _3 = MyId(move _4); ++ _3 = MyId(copy _1); + StorageDead(_4); + StorageLive(_5); + StorageLive(_6); + StorageLive(_7); +- _7 = move _3; +- _6 = move _7 as u16 (Transmute); ++ _7 = copy _3; ++ _6 = copy _1; + StorageDead(_7); +- _5 = opaque::(move _6) -> [return: bb1, unwind continue]; ++ _5 = opaque::(copy _1) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_6); + StorageDead(_5); +- StorageLive(_8); ++ nop; + StorageLive(_9); + _9 = copy _1; + StorageLive(_10); +- _10 = PhantomData::; +- _8 = TypedId::(move _9, move _10); ++ _10 = const PhantomData::; ++ _8 = TypedId::(copy _1, const PhantomData::); + StorageDead(_10); + StorageDead(_9); + StorageLive(_11); + StorageLive(_12); + StorageLive(_13); +- _13 = move _8; +- _12 = move _13 as u16 (Transmute); ++ _13 = copy _8; ++ _12 = copy _1; + StorageDead(_13); +- _11 = opaque::(move _12) -> [return: bb2, unwind continue]; ++ _11 = opaque::(copy _1) -> [return: bb2, unwind continue]; + } + + bb2: { + StorageDead(_12); + StorageDead(_11); +- StorageLive(_14); ++ nop; + StorageLive(_15); + _15 = copy _1; +- _14 = Result::::Err(move _15); ++ _14 = Result::::Err(copy _1); + StorageDead(_15); + StorageLive(_16); + StorageLive(_17); + StorageLive(_18); +- _18 = move _14; +- _17 = move _18 as u16 (Transmute); ++ _18 = copy _14; ++ _17 = copy _1; + StorageDead(_18); +- _16 = opaque::(move _17) -> [return: bb3, unwind continue]; ++ _16 = opaque::(copy _1) -> [return: bb3, unwind continue]; + } + + bb3: { + StorageDead(_17); + StorageDead(_16); +- StorageLive(_19); ++ nop; + StorageLive(_20); + _20 = copy _1; +- _19 = Option::::Some(move _20); ++ _19 = Option::::Some(copy _1); + StorageDead(_20); + StorageLive(_21); + StorageLive(_22); + StorageLive(_23); + _23 = copy _19; +- _22 = move _23 as u32 (Transmute); ++ _22 = copy _19 as u32 (Transmute); + StorageDead(_23); + _21 = opaque::(move _22) -> [return: bb4, unwind continue]; + } + + bb4: { + StorageDead(_22); + StorageDead(_21); + StorageLive(_24); + StorageLive(_25); + _25 = copy _1; +- _24 = MyId(move _25); ++ _24 = copy _3; + StorageDead(_25); + StorageLive(_26); + StorageLive(_27); + StorageLive(_28); +- _28 = move _24; +- _27 = move _28 as i16 (Transmute); ++ _28 = copy _3; ++ _27 = copy _1 as i16 (Transmute); + StorageDead(_28); + _26 = opaque::(move _27) -> [return: bb5, unwind continue]; + } + + bb5: { + StorageDead(_27); + StorageDead(_26); +- StorageLive(_29); ++ nop; + StorageLive(_30); + _30 = copy _1; + StorageLive(_31); + _31 = copy _1; +- _29 = Pair(move _30, move _31); ++ _29 = Pair(copy _1, copy _1); + StorageDead(_31); + StorageDead(_30); + StorageLive(_32); + StorageLive(_33); + StorageLive(_34); +- _34 = move _29; +- _33 = move _34 as u32 (Transmute); ++ _34 = copy _29; ++ _33 = copy _29 as u32 (Transmute); + StorageDead(_34); + _32 = opaque::(move _33) -> [return: bb6, unwind continue]; + } + + bb6: { + StorageDead(_33); + StorageDead(_32); + StorageLive(_35); + StorageLive(_36); + _36 = copy _1; + StorageLive(_37); + _37 = copy _1; +- _35 = Pair(move _36, move _37); ++ _35 = copy _29; + StorageDead(_37); + StorageDead(_36); + StorageLive(_38); + StorageLive(_39); + StorageLive(_40); +- _40 = move _35; +- _39 = move _40 as u16 (Transmute); ++ _40 = copy _29; ++ _39 = copy _29 as u16 (Transmute); + StorageDead(_40); + _38 = opaque::(move _39) -> [return: bb7, unwind continue]; + } + + bb7: { + StorageDead(_39); + StorageDead(_38); +- StorageLive(_41); ++ nop; + StorageLive(_42); + _42 = copy _1; +- _41 = (move _42,); ++ _41 = (copy _1,); + StorageDead(_42); + StorageLive(_43); + StorageLive(_44); + StorageLive(_45); + _45 = copy _41; +- _44 = move _45 as u16 (Transmute); ++ _44 = copy _1; + StorageDead(_45); +- _43 = opaque::(move _44) -> [return: bb8, unwind continue]; ++ _43 = opaque::(copy _1) -> [return: bb8, unwind continue]; + } + + bb8: { + StorageDead(_44); + StorageDead(_43); +- StorageLive(_46); ++ nop; + StorageLive(_47); + _47 = copy _1; +- _46 = [move _47]; ++ _46 = [copy _1]; + StorageDead(_47); + StorageLive(_48); + StorageLive(_49); + StorageLive(_50); + _50 = copy _46; +- _49 = move _50 as u16 (Transmute); ++ _49 = copy _1; + StorageDead(_50); +- _48 = opaque::(move _49) -> [return: bb9, unwind continue]; ++ _48 = opaque::(copy _1) -> [return: bb9, unwind continue]; + } + + bb9: { + StorageDead(_49); + StorageDead(_48); +- StorageLive(_51); ++ nop; + StorageLive(_52); + _52 = copy _2; + StorageLive(_53); +- _53 = (); +- _51 = *const i32 from (move _52, move _53); ++ _53 = const (); ++ _51 = *const i32 from (copy _2, const ()); + StorageDead(_53); + StorageDead(_52); + StorageLive(_54); + StorageLive(_55); + StorageLive(_56); + _56 = copy _51; +- _55 = move _56 as *const u8 (Transmute); ++ _55 = copy _2; + StorageDead(_56); +- _54 = opaque::<*const u8>(move _55) -> [return: bb10, unwind continue]; ++ _54 = opaque::<*const u8>(copy _2) -> [return: bb10, unwind continue]; + } + + bb10: { + StorageDead(_55); + StorageDead(_54); + _0 = const (); +- StorageDead(_51); +- StorageDead(_46); +- StorageDead(_41); ++ nop; ++ nop; ++ nop; + StorageDead(_35); +- StorageDead(_29); ++ nop; + StorageDead(_24); +- StorageDead(_19); +- StorageDead(_14); +- StorageDead(_8); +- StorageDead(_3); ++ nop; ++ nop; ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 19b58a917f87c..c895a5792595e 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -12,7 +12,7 @@ #![allow(unused)] use std::intrinsics::mir::*; -use std::marker::Freeze; +use std::marker::{Freeze, PhantomData}; use std::mem::transmute; struct S(T); @@ -933,6 +933,69 @@ fn cast_pointer_eq(p1: *mut u8, p2: *mut u32, p3: *mut u32, p4: *mut [u32]) { // CHECK: _0 = const (); } +unsafe fn aggregate_struct_then_transmute(id: u16, thin: *const u8) { + // CHECK: opaque::(copy _1) + let a = MyId(id); + opaque(std::intrinsics::transmute::<_, u16>(a)); + + // CHECK: opaque::(copy _1) + let b = TypedId::(id, PhantomData); + opaque(std::intrinsics::transmute::<_, u16>(b)); + + // CHECK: opaque::(copy _1) + let c = Err::(id); + opaque(std::intrinsics::transmute::<_, u16>(c)); + + // CHECK: [[TEMP1:_[0-9]+]] = Option::::Some(copy _1); + // CHECK: [[TEMP2:_[0-9]+]] = copy [[TEMP1]] as u32 (Transmute); + // CHECK: opaque::(move [[TEMP2]]) + let d = Some(id); + opaque(std::intrinsics::transmute::<_, u32>(d)); + + // Still need the transmute, but the aggregate can be skipped + // CHECK: [[TEMP:_[0-9]+]] = copy _1 as i16 (Transmute); + // CHECK: opaque::(move [[TEMP]]) + let e = MyId(id); + opaque(std::intrinsics::transmute::<_, i16>(e)); + + // CHECK: [[PAIR:_[0-9]+]] = Pair(copy _1, copy _1); + // CHECK: [[TEMP:_[0-9]+]] = copy [[PAIR]] as u32 (Transmute); + // CHECK: opaque::(move [[TEMP]]) + struct Pair(u16, u16); + let f = Pair(id, id); + opaque(std::intrinsics::transmute::<_, u32>(f)); + + // CHECK: [[TEMP:_[0-9]+]] = copy [[PAIR]] as u16 (Transmute); + // CHECK: opaque::(move [[TEMP]]) + let g = Pair(id, id); + opaque(std::intrinsics::transmute_unchecked::<_, u16>(g)); + + // CHECK: opaque::(copy _1) + let h = (id,); + opaque(std::intrinsics::transmute::<_, u16>(h)); + + // CHECK: opaque::(copy _1) + let i = [id]; + opaque(std::intrinsics::transmute::<_, u16>(i)); + + // CHECK: opaque::<*const u8>(copy _2) + let j: *const i32 = std::intrinsics::aggregate_raw_ptr(thin, ()); + opaque(std::intrinsics::transmute::<_, *const u8>(j)); +} + +unsafe fn transmute_then_transmute_again(a: u32, c: char) { + // CHECK: [[TEMP1:_[0-9]+]] = copy _1 as char (Transmute); + // CHECK: [[TEMP2:_[0-9]+]] = copy [[TEMP1]] as i32 (Transmute); + // CHECK: opaque::(move [[TEMP2]]) + let x = std::intrinsics::transmute::(a); + opaque(std::intrinsics::transmute::(x)); + + // CHECK: [[TEMP:_[0-9]+]] = copy _2 as i32 (Transmute); + // CHECK: opaque::(move [[TEMP]]) + let x = std::intrinsics::transmute::(c); + opaque(std::intrinsics::transmute::(x)); +} + // Transmuting can skip a pointer cast so long as it wasn't a fat-to-thin cast. unsafe fn cast_pointer_then_transmute(thin: *mut u32, fat: *mut [u8]) { // CHECK-LABEL: fn cast_pointer_then_transmute @@ -946,6 +1009,28 @@ unsafe fn cast_pointer_then_transmute(thin: *mut u32, fat: *mut [u8]) { let fat_addr: usize = std::intrinsics::transmute(fat as *const ()); } +unsafe fn transmute_then_cast_pointer(addr: usize, fat: *mut [u8]) { + // CHECK-LABEL: fn transmute_then_cast_pointer + + // This is roughly what `NonNull::dangling` does + // CHECK: [[CPTR:_.+]] = copy _1 as *const u8 (Transmute); + // CHECK: takes_const_ptr::(move [[CPTR]]) + let p: *mut u8 = std::intrinsics::transmute(addr); + takes_const_ptr(p); + + // This cast is fat-to-thin, so can't be merged with the transmute + // CHECK: [[FAT:_.+]] = move {{.+}} as *const [i32] (Transmute); + // CHECK: [[THIN:_.+]] = copy [[FAT]] as *const i32 (PtrToPtr); + // CHECK: takes_const_ptr::(move [[THIN]]) + let q = std::intrinsics::transmute::<&mut [i32], *const [i32]>(&mut [1, 2, 3]); + takes_const_ptr(q as *const i32); + + // CHECK: [[TPTR:_.+]] = copy _2 as *const u8 (PtrToPtr); + // CHECK: takes_const_ptr::(move [[TPTR]]) + let w = std::intrinsics::transmute::<*mut [u8], *const [u8]>(fat); + takes_const_ptr(w as *const u8); +} + #[custom_mir(dialect = "analysis")] fn remove_casts_must_change_both_sides(mut_a: &*mut u8, mut_b: *mut u8) -> bool { // CHECK-LABEL: fn remove_casts_must_change_both_sides( @@ -1002,6 +1087,18 @@ fn identity(x: T) -> T { x } +#[inline(never)] +fn takes_const_ptr(_: *const T) {} + +#[repr(transparent)] +#[rustc_layout_scalar_valid_range_end(55555)] +struct MyId(u16); + +#[repr(transparent)] +struct TypedId(u16, PhantomData); + +enum Never {} + // EMIT_MIR gvn.subexpression_elimination.GVN.diff // EMIT_MIR gvn.wrap_unwrap.GVN.diff // EMIT_MIR gvn.repeated_index.GVN.diff @@ -1034,5 +1131,8 @@ fn identity(x: T) -> T { // EMIT_MIR gvn.dedup_multiple_bounds_checks_lengths.GVN.diff // EMIT_MIR gvn.generic_cast_metadata.GVN.diff // EMIT_MIR gvn.cast_pointer_eq.GVN.diff +// EMIT_MIR gvn.aggregate_struct_then_transmute.GVN.diff +// EMIT_MIR gvn.transmute_then_transmute_again.GVN.diff // EMIT_MIR gvn.cast_pointer_then_transmute.GVN.diff +// EMIT_MIR gvn.transmute_then_cast_pointer.GVN.diff // EMIT_MIR gvn.remove_casts_must_change_both_sides.GVN.diff diff --git a/tests/mir-opt/gvn.transmute_then_cast_pointer.GVN.panic-abort.diff b/tests/mir-opt/gvn.transmute_then_cast_pointer.GVN.panic-abort.diff new file mode 100644 index 0000000000000..0bec425dd9957 --- /dev/null +++ b/tests/mir-opt/gvn.transmute_then_cast_pointer.GVN.panic-abort.diff @@ -0,0 +1,115 @@ +- // MIR for `transmute_then_cast_pointer` before GVN ++ // MIR for `transmute_then_cast_pointer` after GVN + + fn transmute_then_cast_pointer(_1: usize, _2: *mut [u8]) -> () { + debug addr => _1; + debug fat => _2; + let mut _0: (); + let _3: *mut u8; + let mut _4: usize; + let _5: (); + let mut _6: *const u8; + let mut _7: *mut u8; + let mut _9: &mut [i32]; + let mut _10: &mut [i32; 3]; + let mut _11: &mut [i32; 3]; + let mut _12: [i32; 3]; + let _13: (); + let mut _14: *const i32; + let mut _15: *const [i32]; + let mut _17: *mut [u8]; + let _18: (); + let mut _19: *const u8; + let mut _20: *const [u8]; + scope 1 { + debug p => _3; + let _8: *const [i32]; + scope 2 { + debug q => _8; + let _16: *const [u8]; + scope 3 { + debug w => _16; + } + } + } + + bb0: { +- StorageLive(_3); ++ nop; + StorageLive(_4); + _4 = copy _1; +- _3 = move _4 as *mut u8 (Transmute); ++ _3 = copy _1 as *mut u8 (Transmute); + StorageDead(_4); + StorageLive(_5); + StorageLive(_6); + StorageLive(_7); + _7 = copy _3; +- _6 = move _7 as *const u8 (PtrToPtr); ++ _6 = copy _1 as *const u8 (Transmute); + StorageDead(_7); + _5 = takes_const_ptr::(move _6) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_6); + StorageDead(_5); +- StorageLive(_8); ++ nop; + StorageLive(_9); + StorageLive(_10); + StorageLive(_11); + StorageLive(_12); + _12 = [const 1_i32, const 2_i32, const 3_i32]; + _11 = &mut _12; + _10 = &mut (*_11); + _9 = move _10 as &mut [i32] (PointerCoercion(Unsize, Implicit)); + StorageDead(_10); + _8 = move _9 as *const [i32] (Transmute); + StorageDead(_9); + StorageDead(_12); + StorageDead(_11); + StorageLive(_13); + StorageLive(_14); + StorageLive(_15); + _15 = copy _8; +- _14 = move _15 as *const i32 (PtrToPtr); ++ _14 = copy _8 as *const i32 (PtrToPtr); + StorageDead(_15); + _13 = takes_const_ptr::(move _14) -> [return: bb2, unwind unreachable]; + } + + bb2: { + StorageDead(_14); + StorageDead(_13); +- StorageLive(_16); ++ nop; + StorageLive(_17); + _17 = copy _2; +- _16 = move _17 as *const [u8] (Transmute); ++ _16 = copy _2 as *const [u8] (PtrToPtr); + StorageDead(_17); + StorageLive(_18); + StorageLive(_19); + StorageLive(_20); + _20 = copy _16; +- _19 = move _20 as *const u8 (PtrToPtr); ++ _19 = copy _2 as *const u8 (PtrToPtr); + StorageDead(_20); + _18 = takes_const_ptr::(move _19) -> [return: bb3, unwind unreachable]; + } + + bb3: { + StorageDead(_19); + StorageDead(_18); + _0 = const (); +- StorageDead(_16); +- StorageDead(_8); +- StorageDead(_3); ++ nop; ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.transmute_then_cast_pointer.GVN.panic-unwind.diff b/tests/mir-opt/gvn.transmute_then_cast_pointer.GVN.panic-unwind.diff new file mode 100644 index 0000000000000..14f2fe08a86a2 --- /dev/null +++ b/tests/mir-opt/gvn.transmute_then_cast_pointer.GVN.panic-unwind.diff @@ -0,0 +1,115 @@ +- // MIR for `transmute_then_cast_pointer` before GVN ++ // MIR for `transmute_then_cast_pointer` after GVN + + fn transmute_then_cast_pointer(_1: usize, _2: *mut [u8]) -> () { + debug addr => _1; + debug fat => _2; + let mut _0: (); + let _3: *mut u8; + let mut _4: usize; + let _5: (); + let mut _6: *const u8; + let mut _7: *mut u8; + let mut _9: &mut [i32]; + let mut _10: &mut [i32; 3]; + let mut _11: &mut [i32; 3]; + let mut _12: [i32; 3]; + let _13: (); + let mut _14: *const i32; + let mut _15: *const [i32]; + let mut _17: *mut [u8]; + let _18: (); + let mut _19: *const u8; + let mut _20: *const [u8]; + scope 1 { + debug p => _3; + let _8: *const [i32]; + scope 2 { + debug q => _8; + let _16: *const [u8]; + scope 3 { + debug w => _16; + } + } + } + + bb0: { +- StorageLive(_3); ++ nop; + StorageLive(_4); + _4 = copy _1; +- _3 = move _4 as *mut u8 (Transmute); ++ _3 = copy _1 as *mut u8 (Transmute); + StorageDead(_4); + StorageLive(_5); + StorageLive(_6); + StorageLive(_7); + _7 = copy _3; +- _6 = move _7 as *const u8 (PtrToPtr); ++ _6 = copy _1 as *const u8 (Transmute); + StorageDead(_7); + _5 = takes_const_ptr::(move _6) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_6); + StorageDead(_5); +- StorageLive(_8); ++ nop; + StorageLive(_9); + StorageLive(_10); + StorageLive(_11); + StorageLive(_12); + _12 = [const 1_i32, const 2_i32, const 3_i32]; + _11 = &mut _12; + _10 = &mut (*_11); + _9 = move _10 as &mut [i32] (PointerCoercion(Unsize, Implicit)); + StorageDead(_10); + _8 = move _9 as *const [i32] (Transmute); + StorageDead(_9); + StorageDead(_12); + StorageDead(_11); + StorageLive(_13); + StorageLive(_14); + StorageLive(_15); + _15 = copy _8; +- _14 = move _15 as *const i32 (PtrToPtr); ++ _14 = copy _8 as *const i32 (PtrToPtr); + StorageDead(_15); + _13 = takes_const_ptr::(move _14) -> [return: bb2, unwind continue]; + } + + bb2: { + StorageDead(_14); + StorageDead(_13); +- StorageLive(_16); ++ nop; + StorageLive(_17); + _17 = copy _2; +- _16 = move _17 as *const [u8] (Transmute); ++ _16 = copy _2 as *const [u8] (PtrToPtr); + StorageDead(_17); + StorageLive(_18); + StorageLive(_19); + StorageLive(_20); + _20 = copy _16; +- _19 = move _20 as *const u8 (PtrToPtr); ++ _19 = copy _2 as *const u8 (PtrToPtr); + StorageDead(_20); + _18 = takes_const_ptr::(move _19) -> [return: bb3, unwind continue]; + } + + bb3: { + StorageDead(_19); + StorageDead(_18); + _0 = const (); +- StorageDead(_16); +- StorageDead(_8); +- StorageDead(_3); ++ nop; ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.transmute_then_transmute_again.GVN.panic-abort.diff b/tests/mir-opt/gvn.transmute_then_transmute_again.GVN.panic-abort.diff new file mode 100644 index 0000000000000..962fecd2586eb --- /dev/null +++ b/tests/mir-opt/gvn.transmute_then_transmute_again.GVN.panic-abort.diff @@ -0,0 +1,74 @@ +- // MIR for `transmute_then_transmute_again` before GVN ++ // MIR for `transmute_then_transmute_again` after GVN + + fn transmute_then_transmute_again(_1: u32, _2: char) -> () { + debug a => _1; + debug c => _2; + let mut _0: (); + let _3: char; + let mut _4: u32; + let _5: (); + let mut _6: i32; + let mut _7: char; + let mut _9: char; + let _10: (); + let mut _11: i32; + let mut _12: u32; + scope 1 { + debug x => _3; + let _8: u32; + scope 2 { + debug x => _8; + } + } + + bb0: { +- StorageLive(_3); ++ nop; + StorageLive(_4); + _4 = copy _1; +- _3 = move _4 as char (Transmute); ++ _3 = copy _1 as char (Transmute); + StorageDead(_4); + StorageLive(_5); + StorageLive(_6); + StorageLive(_7); + _7 = copy _3; +- _6 = move _7 as i32 (Transmute); ++ _6 = copy _3 as i32 (Transmute); + StorageDead(_7); + _5 = opaque::(move _6) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_6); + StorageDead(_5); +- StorageLive(_8); ++ nop; + StorageLive(_9); + _9 = copy _2; +- _8 = move _9 as u32 (Transmute); ++ _8 = copy _2 as u32 (Transmute); + StorageDead(_9); + StorageLive(_10); + StorageLive(_11); + StorageLive(_12); + _12 = copy _8; +- _11 = move _12 as i32 (Transmute); ++ _11 = copy _2 as i32 (Transmute); + StorageDead(_12); + _10 = opaque::(move _11) -> [return: bb2, unwind unreachable]; + } + + bb2: { + StorageDead(_11); + StorageDead(_10); + _0 = const (); +- StorageDead(_8); +- StorageDead(_3); ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.transmute_then_transmute_again.GVN.panic-unwind.diff b/tests/mir-opt/gvn.transmute_then_transmute_again.GVN.panic-unwind.diff new file mode 100644 index 0000000000000..e32397c1aed07 --- /dev/null +++ b/tests/mir-opt/gvn.transmute_then_transmute_again.GVN.panic-unwind.diff @@ -0,0 +1,74 @@ +- // MIR for `transmute_then_transmute_again` before GVN ++ // MIR for `transmute_then_transmute_again` after GVN + + fn transmute_then_transmute_again(_1: u32, _2: char) -> () { + debug a => _1; + debug c => _2; + let mut _0: (); + let _3: char; + let mut _4: u32; + let _5: (); + let mut _6: i32; + let mut _7: char; + let mut _9: char; + let _10: (); + let mut _11: i32; + let mut _12: u32; + scope 1 { + debug x => _3; + let _8: u32; + scope 2 { + debug x => _8; + } + } + + bb0: { +- StorageLive(_3); ++ nop; + StorageLive(_4); + _4 = copy _1; +- _3 = move _4 as char (Transmute); ++ _3 = copy _1 as char (Transmute); + StorageDead(_4); + StorageLive(_5); + StorageLive(_6); + StorageLive(_7); + _7 = copy _3; +- _6 = move _7 as i32 (Transmute); ++ _6 = copy _3 as i32 (Transmute); + StorageDead(_7); + _5 = opaque::(move _6) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_6); + StorageDead(_5); +- StorageLive(_8); ++ nop; + StorageLive(_9); + _9 = copy _2; +- _8 = move _9 as u32 (Transmute); ++ _8 = copy _2 as u32 (Transmute); + StorageDead(_9); + StorageLive(_10); + StorageLive(_11); + StorageLive(_12); + _12 = copy _8; +- _11 = move _12 as i32 (Transmute); ++ _11 = copy _2 as i32 (Transmute); + StorageDead(_12); + _10 = opaque::(move _11) -> [return: bb2, unwind continue]; + } + + bb2: { + StorageDead(_11); + StorageDead(_10); + _0 = const (); +- StorageDead(_8); +- StorageDead(_3); ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff index 581244074b36c..4337e0da18336 100644 --- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff @@ -11,10 +11,43 @@ + scope 1 (inlined std::ptr::drop_in_place::> - shim(Some(Vec))) { + let mut _6: &mut std::vec::Vec; + let mut _7: (); ++ scope 2 (inlined as Drop>::drop) { ++ let mut _8: *mut [A]; ++ let mut _9: *mut A; ++ let mut _10: usize; ++ scope 3 (inlined Vec::::as_mut_ptr) { ++ scope 4 (inlined alloc::raw_vec::RawVec::::ptr) { ++ scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::) { ++ scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::) { ++ let mut _11: std::ptr::NonNull; ++ scope 7 (inlined Unique::::cast::) { ++ scope 8 (inlined NonNull::::cast::) { ++ scope 9 (inlined NonNull::::as_ptr) { ++ } ++ } ++ } ++ scope 10 (inlined Unique::::as_non_null_ptr) { ++ } ++ } ++ scope 11 (inlined NonNull::::as_ptr) { ++ } ++ } ++ } ++ } ++ scope 12 (inlined slice_from_raw_parts_mut::) { ++ scope 13 (inlined std::ptr::from_raw_parts_mut::<[A], A>) { ++ } ++ } ++ scope 14 (inlined std::ptr::drop_in_place::<[A]> - shim(Some([A]))) { ++ let mut _12: usize; ++ let mut _13: *mut A; ++ let mut _14: bool; ++ } ++ } + } -+ scope 2 (inlined std::ptr::drop_in_place::> - shim(Some(Option))) { -+ let mut _8: isize; -+ let mut _9: isize; ++ scope 15 (inlined std::ptr::drop_in_place::> - shim(Some(Option))) { ++ let mut _15: isize; ++ let mut _16: isize; + } bb0: { @@ -25,7 +58,21 @@ + StorageLive(_6); + StorageLive(_7); + _6 = &mut (*_4); -+ _7 = as Drop>::drop(move _6) -> [return: bb2, unwind unreachable]; ++ StorageLive(_10); ++ StorageLive(_8); ++ StorageLive(_9); ++ StorageLive(_11); ++ _11 = copy (((((*_6).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); ++ _9 = copy _11 as *mut A (Transmute); ++ StorageDead(_11); ++ _10 = copy ((*_6).1: usize); ++ _8 = *mut [A] from (copy _9, copy _10); ++ StorageDead(_9); ++ StorageLive(_12); ++ StorageLive(_13); ++ StorageLive(_14); ++ _12 = const 0_usize; ++ goto -> bb4; } bb1: { @@ -36,25 +83,41 @@ StorageLive(_5); _5 = copy _2; - _0 = std::ptr::drop_in_place::>(move _5) -> [return: bb2, unwind unreachable]; -+ StorageLive(_8); -+ StorageLive(_9); -+ _8 = discriminant((*_5)); -+ switchInt(move _8) -> [0: bb3, otherwise: bb4]; ++ StorageLive(_15); ++ StorageLive(_16); ++ _15 = discriminant((*_5)); ++ switchInt(move _15) -> [0: bb5, otherwise: bb6]; } bb2: { ++ StorageDead(_14); ++ StorageDead(_13); ++ StorageDead(_12); ++ StorageDead(_8); ++ StorageDead(_10); + drop(((*_4).0: alloc::raw_vec::RawVec)) -> [return: bb1, unwind unreachable]; + } + + bb3: { -+ StorageDead(_9); -+ StorageDead(_8); ++ _13 = &raw mut (*_8)[_12]; ++ _12 = Add(move _12, const 1_usize); ++ drop((*_13)) -> [return: bb4, unwind unreachable]; ++ } ++ ++ bb4: { ++ _14 = Eq(copy _12, copy _10); ++ switchInt(move _14) -> [0: bb3, otherwise: bb2]; ++ } ++ ++ bb5: { ++ StorageDead(_16); ++ StorageDead(_15); StorageDead(_5); return; + } + -+ bb4: { -+ drop((((*_5) as Some).0: B)) -> [return: bb3, unwind unreachable]; ++ bb6: { ++ drop((((*_5) as Some).0: B)) -> [return: bb5, unwind unreachable]; } } diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir index 02aadfc1de064..103475b608cee 100644 --- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir @@ -20,7 +20,7 @@ fn b(_1: &mut Box) -> &mut T { StorageLive(_5); StorageLive(_6); _5 = copy (*_4); - _6 = copy (((_5.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const T); + _6 = copy ((_5.0: std::ptr::Unique).0: std::ptr::NonNull) as *const T (Transmute); _3 = &mut (*_6); StorageDead(_6); StorageDead(_5); diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir index 1ea347510fdb4..babb26808cece 100644 --- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir @@ -18,7 +18,7 @@ fn d(_1: &Box) -> &T { StorageLive(_4); StorageLive(_5); _4 = copy (*_3); - _5 = copy (((_4.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const T); + _5 = copy ((_4.0: std::ptr::Unique).0: std::ptr::NonNull) as *const T (Transmute); _2 = &(*_5); StorageDead(_5); StorageDead(_4); diff --git a/tests/mir-opt/inline/unsized_argument.caller.Inline.diff b/tests/mir-opt/inline/unsized_argument.caller.Inline.diff index 70671e2089a01..644d6d320de04 100644 --- a/tests/mir-opt/inline/unsized_argument.caller.Inline.diff +++ b/tests/mir-opt/inline/unsized_argument.caller.Inline.diff @@ -12,7 +12,7 @@ StorageLive(_2); StorageLive(_3); _3 = move _1; - _4 = copy (((_3.0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>).0: *const [i32]); + _4 = copy ((_3.0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>) as *const [i32] (Transmute); _2 = callee(move (*_4)) -> [return: bb1, unwind: bb3]; } diff --git a/tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify-after-simplifycfg.diff b/tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify-after-simplifycfg.diff deleted file mode 100644 index 9844aa2a64e26..0000000000000 --- a/tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify-after-simplifycfg.diff +++ /dev/null @@ -1,83 +0,0 @@ -- // MIR for `adt_transmutes` before InstSimplify-after-simplifycfg -+ // MIR for `adt_transmutes` after InstSimplify-after-simplifycfg - - fn adt_transmutes() -> () { - let mut _0: (); - let _1: u8; - let mut _2: std::option::Option>; - let mut _4: std::num::Wrapping; - let mut _6: std::num::Wrapping; - let mut _8: Union32; - let mut _10: Union32; - let mut _12: std::mem::MaybeUninit; - scope 1 { - debug _a => _1; - let _3: i16; - scope 2 { - debug _a => _3; - let _5: u16; - scope 3 { - debug _a => _5; - let _7: u32; - scope 4 { - debug _a => _7; - let _9: i32; - scope 5 { - debug _a => _9; - let _11: std::mem::ManuallyDrop; - scope 6 { - debug _a => _11; - } - } - } - } - } - } - - bb0: { - StorageLive(_1); - StorageLive(_2); - _2 = Option::>::Some(const std::num::NonZero::::MAX); - _1 = move _2 as u8 (Transmute); - StorageDead(_2); - StorageLive(_3); - StorageLive(_4); - _4 = Wrapping::(const 0_i16); -- _3 = move _4 as i16 (Transmute); -+ _3 = move (_4.0: i16); - StorageDead(_4); - StorageLive(_5); - StorageLive(_6); - _6 = Wrapping::(const 0_i16); - _5 = move _6 as u16 (Transmute); - StorageDead(_6); - StorageLive(_7); - StorageLive(_8); - _8 = Union32 { u32: const 0_i32 }; - _7 = move _8 as u32 (Transmute); - StorageDead(_8); - StorageLive(_9); - StorageLive(_10); - _10 = Union32 { u32: const 0_u32 }; - _9 = move _10 as i32 (Transmute); - StorageDead(_10); - StorageLive(_11); - StorageLive(_12); - _12 = MaybeUninit::::uninit() -> [return: bb1, unwind unreachable]; - } - - bb1: { -- _11 = move _12 as std::mem::ManuallyDrop (Transmute); -+ _11 = move (_12.1: std::mem::ManuallyDrop); - StorageDead(_12); - _0 = const (); - StorageDead(_11); - StorageDead(_9); - StorageDead(_7); - StorageDead(_5); - StorageDead(_3); - StorageDead(_1); - return; - } - } - diff --git a/tests/mir-opt/instsimplify/combine_transmutes.keep_transparent_transmute.InstSimplify-after-simplifycfg.diff b/tests/mir-opt/instsimplify/combine_transmutes.keep_transparent_transmute.InstSimplify-after-simplifycfg.diff new file mode 100644 index 0000000000000..66a29629591ad --- /dev/null +++ b/tests/mir-opt/instsimplify/combine_transmutes.keep_transparent_transmute.InstSimplify-after-simplifycfg.diff @@ -0,0 +1,30 @@ +- // MIR for `keep_transparent_transmute` before InstSimplify-after-simplifycfg ++ // MIR for `keep_transparent_transmute` after InstSimplify-after-simplifycfg + + fn keep_transparent_transmute() -> () { + let mut _0: (); + let _1: i16; + let mut _3: std::num::Wrapping; + scope 1 { + debug _a => _1; + let _2: i16; + scope 2 { + debug _a => _2; + } + } + + bb0: { + StorageLive(_1); + _1 = const keep_transparent_transmute::{constant#0} as i16 (Transmute); + StorageLive(_2); + StorageLive(_3); + _3 = Wrapping::(const 0_i16); + _2 = move _3 as i16 (Transmute); + StorageDead(_3); + _0 = const (); + StorageDead(_2); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/instsimplify/combine_transmutes.rs b/tests/mir-opt/instsimplify/combine_transmutes.rs index 8a670301825be..c12f307ca0e5a 100644 --- a/tests/mir-opt/instsimplify/combine_transmutes.rs +++ b/tests/mir-opt/instsimplify/combine_transmutes.rs @@ -43,22 +43,19 @@ pub unsafe fn integer_transmutes() { } } -// EMIT_MIR combine_transmutes.adt_transmutes.InstSimplify-after-simplifycfg.diff -pub unsafe fn adt_transmutes() { - // CHECK-LABEL: fn adt_transmutes( - // CHECK: as u8 (Transmute); - // CHECK: ({{_.*}}.0: i16); - // CHECK: as u16 (Transmute); - // CHECK: as u32 (Transmute); - // CHECK: as i32 (Transmute); - // CHECK: ({{_.*}}.1: std::mem::ManuallyDrop); +// EMIT_MIR combine_transmutes.keep_transparent_transmute.InstSimplify-after-simplifycfg.diff +pub unsafe fn keep_transparent_transmute() { + // CHECK-LABEL: fn keep_transparent_transmute( + // CHECK-NOT: .{{[0-9]+}}: i16 + // CHECK: as i16 (Transmute); + // CHECK-NOT: .{{[0-9]+}}: i16 + // CHECK: as i16 (Transmute); + // CHECK-NOT: .{{[0-9]+}}: i16 - let _a: u8 = transmute(Some(std::num::NonZero::::MAX)); + // Transmutes should not be converted to field accesses, because MCP#807 + // bans projections into `[rustc_layout_scalar_valid_range_*]` types. + let _a: i16 = transmute(const { std::num::NonZero::new(12345_i16).unwrap() }); let _a: i16 = transmute(std::num::Wrapping(0_i16)); - let _a: u16 = transmute(std::num::Wrapping(0_i16)); - let _a: u32 = transmute(Union32 { i32: 0 }); - let _a: i32 = transmute(Union32 { u32: 0 }); - let _a: ManuallyDrop = transmute(MaybeUninit::::uninit()); } pub union Union32 { diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir index a3308cc5df196..a2ef53e0e1308 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir @@ -4,28 +4,28 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _13: std::slice::Iter<'_, T>; - let mut _14: std::iter::Enumerate>; - let mut _15: std::iter::Enumerate>; - let mut _23: std::option::Option<(usize, &T)>; - let mut _26: &impl Fn(usize, &T); - let mut _27: (usize, &T); - let _28: (); + let mut _11: std::slice::Iter<'_, T>; + let mut _12: std::iter::Enumerate>; + let mut _13: std::iter::Enumerate>; + let mut _21: std::option::Option<(usize, &T)>; + let mut _24: &impl Fn(usize, &T); + let mut _25: (usize, &T); + let _26: (); scope 1 { - debug iter => _15; - let _24: usize; - let _25: &T; + debug iter => _13; + let _22: usize; + let _23: &T; scope 2 { - debug i => _24; - debug x => _25; + debug i => _22; + debug x => _23; } scope 18 (inlined > as Iterator>::next) { - let mut _16: &mut std::slice::Iter<'_, T>; - let mut _17: std::option::Option<&T>; - let mut _21: (usize, bool); - let mut _22: (usize, &T); + let mut _14: &mut std::slice::Iter<'_, T>; + let mut _15: std::option::Option<&T>; + let mut _19: (usize, bool); + let mut _20: (usize, &T); scope 19 { - let _20: usize; + let _18: usize; scope 24 { } } @@ -40,8 +40,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } scope 25 (inlined as Try>::branch) { - let mut _18: isize; - let _19: &T; + let mut _16: isize; + let _17: &T; scope 26 { } } @@ -50,14 +50,13 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _5: std::ptr::NonNull<[T]>; - let mut _9: *mut T; - let mut _10: *mut T; - let mut _12: *const T; + let mut _7: *mut T; + let mut _8: *mut T; + let mut _10: *const T; scope 5 { - let _8: std::ptr::NonNull; + let _6: std::ptr::NonNull; scope 6 { - let _11: *const T; + let _9: *const T; scope 7 { } scope 12 (inlined without_provenance::) { @@ -73,8 +72,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } scope 10 (inlined NonNull::<[T]>::cast::) { - let mut _6: *mut [T]; - let mut _7: *const T; + let mut _5: *const T; scope 11 (inlined NonNull::<[T]>::as_ptr) { } } @@ -89,82 +87,76 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb0: { - StorageLive(_13); + StorageLive(_11); StorageLive(_3); - StorageLive(_8); - _3 = PtrMetadata(copy _1); - StorageLive(_5); + StorageLive(_6); StorageLive(_4); + _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); - _5 = NonNull::<[T]> { pointer: move _4 }; - StorageDead(_4); - StorageLive(_6); - StorageLive(_7); - _6 = copy _5 as *mut [T] (Transmute); - _7 = copy _6 as *const T (PtrToPtr); - _8 = NonNull:: { pointer: move _7 }; - StorageDead(_7); - StorageDead(_6); + StorageLive(_5); + _5 = copy _4 as *const T (PtrToPtr); + _6 = NonNull:: { pointer: move _5 }; StorageDead(_5); - StorageLive(_11); + StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_10); - StorageLive(_9); - _9 = copy _8 as *mut T (Transmute); - _10 = Offset(copy _9, copy _3); - StorageDead(_9); - _11 = move _10 as *const T (PtrToPtr); - StorageDead(_10); + StorageLive(_8); + StorageLive(_7); + _7 = copy _4 as *mut T (PtrToPtr); + _8 = Offset(copy _7, copy _3); + StorageDead(_7); + _9 = move _8 as *const T (PtrToPtr); + StorageDead(_8); goto -> bb3; } bb2: { - _11 = copy _3 as *const T (Transmute); + _9 = copy _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageLive(_12); - _12 = copy _11; - _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_12); - StorageDead(_11); - StorageDead(_8); + StorageLive(_10); + _10 = copy _9; + _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_10); + StorageDead(_9); + StorageDead(_4); + StorageDead(_6); StorageDead(_3); - _14 = Enumerate::> { iter: copy _13, count: const 0_usize }; - StorageDead(_13); - StorageLive(_15); - _15 = copy _14; + _12 = Enumerate::> { iter: copy _11, count: const 0_usize }; + StorageDead(_11); + StorageLive(_13); + _13 = copy _12; goto -> bb4; } bb4: { - StorageLive(_23); - StorageLive(_20); StorageLive(_21); - StorageLive(_17); - StorageLive(_16); - _16 = &mut (_15.0: std::slice::Iter<'_, T>); - _17 = as Iterator>::next(move _16) -> [return: bb5, unwind unreachable]; + StorageLive(_18); + StorageLive(_19); + StorageLive(_15); + StorageLive(_14); + _14 = &mut (_13.0: std::slice::Iter<'_, T>); + _15 = as Iterator>::next(move _14) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_16); - StorageLive(_18); - _18 = discriminant(_17); - switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb11]; + StorageDead(_14); + StorageLive(_16); + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb11]; } bb6: { + StorageDead(_16); + StorageDead(_15); + StorageDead(_19); StorageDead(_18); - StorageDead(_17); StorageDead(_21); - StorageDead(_20); - StorageDead(_23); - StorageDead(_15); + StorageDead(_13); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -173,35 +165,35 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb8: { - _19 = move ((_17 as Some).0: &T); - StorageDead(_18); - StorageDead(_17); - _20 = copy (_15.1: usize); - _21 = AddWithOverflow(copy (_15.1: usize), const 1_usize); - assert(!move (_21.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_15.1: usize), const 1_usize) -> [success: bb9, unwind unreachable]; + _17 = move ((_15 as Some).0: &T); + StorageDead(_16); + StorageDead(_15); + _18 = copy (_13.1: usize); + _19 = AddWithOverflow(copy (_13.1: usize), const 1_usize); + assert(!move (_19.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_13.1: usize), const 1_usize) -> [success: bb9, unwind unreachable]; } bb9: { - (_15.1: usize) = move (_21.0: usize); - StorageLive(_22); - _22 = (copy _20, copy _19); - _23 = Option::<(usize, &T)>::Some(move _22); - StorageDead(_22); - StorageDead(_21); + (_13.1: usize) = move (_19.0: usize); + StorageLive(_20); + _20 = (copy _18, copy _17); + _21 = Option::<(usize, &T)>::Some(move _20); StorageDead(_20); - _24 = copy (((_23 as Some).0: (usize, &T)).0: usize); - _25 = copy (((_23 as Some).0: (usize, &T)).1: &T); - StorageLive(_26); - _26 = &_2; - StorageLive(_27); - _27 = (copy _24, copy _25); - _28 = >::call(move _26, move _27) -> [return: bb10, unwind unreachable]; + StorageDead(_19); + StorageDead(_18); + _22 = copy (((_21 as Some).0: (usize, &T)).0: usize); + _23 = copy (((_21 as Some).0: (usize, &T)).1: &T); + StorageLive(_24); + _24 = &_2; + StorageLive(_25); + _25 = (copy _22, copy _23); + _26 = >::call(move _24, move _25) -> [return: bb10, unwind unreachable]; } bb10: { - StorageDead(_27); - StorageDead(_26); - StorageDead(_23); + StorageDead(_25); + StorageDead(_24); + StorageDead(_21); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir index 2a837fabd4c24..c1b846e662bc2 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir @@ -4,35 +4,34 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _13: std::slice::Iter<'_, T>; - let mut _14: std::iter::Enumerate>; - let mut _15: std::iter::Enumerate>; - let mut _16: &mut std::iter::Enumerate>; - let mut _17: std::option::Option<(usize, &T)>; - let mut _18: isize; - let mut _21: &impl Fn(usize, &T); - let mut _22: (usize, &T); - let _23: (); + let mut _11: std::slice::Iter<'_, T>; + let mut _12: std::iter::Enumerate>; + let mut _13: std::iter::Enumerate>; + let mut _14: &mut std::iter::Enumerate>; + let mut _15: std::option::Option<(usize, &T)>; + let mut _16: isize; + let mut _19: &impl Fn(usize, &T); + let mut _20: (usize, &T); + let _21: (); scope 1 { - debug iter => _15; - let _19: usize; - let _20: &T; + debug iter => _13; + let _17: usize; + let _18: &T; scope 2 { - debug i => _19; - debug x => _20; + debug i => _17; + debug x => _18; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _5: std::ptr::NonNull<[T]>; - let mut _9: *mut T; - let mut _10: *mut T; - let mut _12: *const T; + let mut _7: *mut T; + let mut _8: *mut T; + let mut _10: *const T; scope 5 { - let _8: std::ptr::NonNull; + let _6: std::ptr::NonNull; scope 6 { - let _11: *const T; + let _9: *const T; scope 7 { } scope 12 (inlined without_provenance::) { @@ -48,8 +47,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } scope 10 (inlined NonNull::<[T]>::cast::) { - let mut _6: *mut [T]; - let mut _7: *const T; + let mut _5: *const T; scope 11 (inlined NonNull::<[T]>::as_ptr) { } } @@ -64,72 +62,66 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb0: { - StorageLive(_13); + StorageLive(_11); StorageLive(_3); - StorageLive(_8); - _3 = PtrMetadata(copy _1); - StorageLive(_5); + StorageLive(_6); StorageLive(_4); + _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); - _5 = NonNull::<[T]> { pointer: move _4 }; - StorageDead(_4); - StorageLive(_6); - StorageLive(_7); - _6 = copy _5 as *mut [T] (Transmute); - _7 = copy _6 as *const T (PtrToPtr); - _8 = NonNull:: { pointer: move _7 }; - StorageDead(_7); - StorageDead(_6); + StorageLive(_5); + _5 = copy _4 as *const T (PtrToPtr); + _6 = NonNull:: { pointer: move _5 }; StorageDead(_5); - StorageLive(_11); + StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_10); - StorageLive(_9); - _9 = copy _8 as *mut T (Transmute); - _10 = Offset(copy _9, copy _3); - StorageDead(_9); - _11 = move _10 as *const T (PtrToPtr); - StorageDead(_10); + StorageLive(_8); + StorageLive(_7); + _7 = copy _4 as *mut T (PtrToPtr); + _8 = Offset(copy _7, copy _3); + StorageDead(_7); + _9 = move _8 as *const T (PtrToPtr); + StorageDead(_8); goto -> bb3; } bb2: { - _11 = copy _3 as *const T (Transmute); + _9 = copy _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageLive(_12); - _12 = copy _11; - _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_12); - StorageDead(_11); - StorageDead(_8); + StorageLive(_10); + _10 = copy _9; + _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_10); + StorageDead(_9); + StorageDead(_4); + StorageDead(_6); StorageDead(_3); - _14 = Enumerate::> { iter: copy _13, count: const 0_usize }; - StorageDead(_13); - StorageLive(_15); - _15 = copy _14; + _12 = Enumerate::> { iter: copy _11, count: const 0_usize }; + StorageDead(_11); + StorageLive(_13); + _13 = copy _12; goto -> bb4; } bb4: { - StorageLive(_17); - _16 = &mut _15; - _17 = > as Iterator>::next(move _16) -> [return: bb5, unwind: bb11]; + StorageLive(_15); + _14 = &mut _13; + _15 = > as Iterator>::next(move _14) -> [return: bb5, unwind: bb11]; } bb5: { - _18 = discriminant(_17); - switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10]; + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_17); StorageDead(_15); + StorageDead(_13); drop(_2) -> [return: bb7, unwind continue]; } @@ -138,19 +130,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb8: { - _19 = copy (((_17 as Some).0: (usize, &T)).0: usize); - _20 = copy (((_17 as Some).0: (usize, &T)).1: &T); - StorageLive(_21); - _21 = &_2; - StorageLive(_22); - _22 = (copy _19, copy _20); - _23 = >::call(move _21, move _22) -> [return: bb9, unwind: bb11]; + _17 = copy (((_15 as Some).0: (usize, &T)).0: usize); + _18 = copy (((_15 as Some).0: (usize, &T)).1: &T); + StorageLive(_19); + _19 = &_2; + StorageLive(_20); + _20 = (copy _17, copy _18); + _21 = >::call(move _19, move _20) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_22); - StorageDead(_21); - StorageDead(_17); + StorageDead(_20); + StorageDead(_19); + StorageDead(_15); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir index 063045caebb5c..8cebf2c6bace6 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -4,32 +4,31 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _13: std::slice::Iter<'_, T>; - let mut _14: std::slice::Iter<'_, T>; - let mut _15: &mut std::slice::Iter<'_, T>; - let mut _16: std::option::Option<&T>; - let mut _17: isize; - let mut _19: &impl Fn(&T); - let mut _20: (&T,); - let _21: (); + let mut _11: std::slice::Iter<'_, T>; + let mut _12: std::slice::Iter<'_, T>; + let mut _13: &mut std::slice::Iter<'_, T>; + let mut _14: std::option::Option<&T>; + let mut _15: isize; + let mut _17: &impl Fn(&T); + let mut _18: (&T,); + let _19: (); scope 1 { - debug iter => _14; - let _18: &T; + debug iter => _12; + let _16: &T; scope 2 { - debug x => _18; + debug x => _16; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _5: std::ptr::NonNull<[T]>; - let mut _9: *mut T; - let mut _10: *mut T; - let mut _12: *const T; + let mut _7: *mut T; + let mut _8: *mut T; + let mut _10: *const T; scope 5 { - let _8: std::ptr::NonNull; + let _6: std::ptr::NonNull; scope 6 { - let _11: *const T; + let _9: *const T; scope 7 { } scope 12 (inlined without_provenance::) { @@ -45,8 +44,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } scope 10 (inlined NonNull::<[T]>::cast::) { - let mut _6: *mut [T]; - let mut _7: *const T; + let mut _5: *const T; scope 11 (inlined NonNull::<[T]>::as_ptr) { } } @@ -58,68 +56,62 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { bb0: { StorageLive(_3); - StorageLive(_8); - _3 = PtrMetadata(copy _1); - StorageLive(_5); + StorageLive(_6); StorageLive(_4); + _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); - _5 = NonNull::<[T]> { pointer: move _4 }; - StorageDead(_4); - StorageLive(_6); - StorageLive(_7); - _6 = copy _5 as *mut [T] (Transmute); - _7 = copy _6 as *const T (PtrToPtr); - _8 = NonNull:: { pointer: move _7 }; - StorageDead(_7); - StorageDead(_6); + StorageLive(_5); + _5 = copy _4 as *const T (PtrToPtr); + _6 = NonNull:: { pointer: move _5 }; StorageDead(_5); - StorageLive(_11); + StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_10); - StorageLive(_9); - _9 = copy _8 as *mut T (Transmute); - _10 = Offset(copy _9, copy _3); - StorageDead(_9); - _11 = move _10 as *const T (PtrToPtr); - StorageDead(_10); + StorageLive(_8); + StorageLive(_7); + _7 = copy _4 as *mut T (PtrToPtr); + _8 = Offset(copy _7, copy _3); + StorageDead(_7); + _9 = move _8 as *const T (PtrToPtr); + StorageDead(_8); goto -> bb3; } bb2: { - _11 = copy _3 as *const T (Transmute); + _9 = copy _3 as *const T (Transmute); goto -> bb3; } bb3: { + StorageLive(_10); + _10 = copy _9; + _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_10); + StorageDead(_9); + StorageDead(_4); + StorageDead(_6); + StorageDead(_3); StorageLive(_12); _12 = copy _11; - _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_12); - StorageDead(_11); - StorageDead(_8); - StorageDead(_3); - StorageLive(_14); - _14 = copy _13; goto -> bb4; } bb4: { - StorageLive(_16); - _15 = &mut _14; - _16 = as Iterator>::next(move _15) -> [return: bb5, unwind unreachable]; + StorageLive(_14); + _13 = &mut _12; + _14 = as Iterator>::next(move _13) -> [return: bb5, unwind unreachable]; } bb5: { - _17 = discriminant(_16); - switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; + _15 = discriminant(_14); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_16); StorageDead(_14); + StorageDead(_12); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -128,18 +120,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _18 = copy ((_16 as Some).0: &T); - StorageLive(_19); - _19 = &_2; - StorageLive(_20); - _20 = (copy _18,); - _21 = >::call(move _19, move _20) -> [return: bb9, unwind unreachable]; + _16 = copy ((_14 as Some).0: &T); + StorageLive(_17); + _17 = &_2; + StorageLive(_18); + _18 = (copy _16,); + _19 = >::call(move _17, move _18) -> [return: bb9, unwind unreachable]; } bb9: { - StorageDead(_20); - StorageDead(_19); - StorageDead(_16); + StorageDead(_18); + StorageDead(_17); + StorageDead(_14); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir index d401ed8fcf3ca..e7e39240fed58 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -4,32 +4,31 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _13: std::slice::Iter<'_, T>; - let mut _14: std::slice::Iter<'_, T>; - let mut _15: &mut std::slice::Iter<'_, T>; - let mut _16: std::option::Option<&T>; - let mut _17: isize; - let mut _19: &impl Fn(&T); - let mut _20: (&T,); - let _21: (); + let mut _11: std::slice::Iter<'_, T>; + let mut _12: std::slice::Iter<'_, T>; + let mut _13: &mut std::slice::Iter<'_, T>; + let mut _14: std::option::Option<&T>; + let mut _15: isize; + let mut _17: &impl Fn(&T); + let mut _18: (&T,); + let _19: (); scope 1 { - debug iter => _14; - let _18: &T; + debug iter => _12; + let _16: &T; scope 2 { - debug x => _18; + debug x => _16; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _5: std::ptr::NonNull<[T]>; - let mut _9: *mut T; - let mut _10: *mut T; - let mut _12: *const T; + let mut _7: *mut T; + let mut _8: *mut T; + let mut _10: *const T; scope 5 { - let _8: std::ptr::NonNull; + let _6: std::ptr::NonNull; scope 6 { - let _11: *const T; + let _9: *const T; scope 7 { } scope 12 (inlined without_provenance::) { @@ -45,8 +44,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } scope 10 (inlined NonNull::<[T]>::cast::) { - let mut _6: *mut [T]; - let mut _7: *const T; + let mut _5: *const T; scope 11 (inlined NonNull::<[T]>::as_ptr) { } } @@ -58,68 +56,62 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { bb0: { StorageLive(_3); - StorageLive(_8); - _3 = PtrMetadata(copy _1); - StorageLive(_5); + StorageLive(_6); StorageLive(_4); + _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); - _5 = NonNull::<[T]> { pointer: move _4 }; - StorageDead(_4); - StorageLive(_6); - StorageLive(_7); - _6 = copy _5 as *mut [T] (Transmute); - _7 = copy _6 as *const T (PtrToPtr); - _8 = NonNull:: { pointer: move _7 }; - StorageDead(_7); - StorageDead(_6); + StorageLive(_5); + _5 = copy _4 as *const T (PtrToPtr); + _6 = NonNull:: { pointer: move _5 }; StorageDead(_5); - StorageLive(_11); + StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_10); - StorageLive(_9); - _9 = copy _8 as *mut T (Transmute); - _10 = Offset(copy _9, copy _3); - StorageDead(_9); - _11 = move _10 as *const T (PtrToPtr); - StorageDead(_10); + StorageLive(_8); + StorageLive(_7); + _7 = copy _4 as *mut T (PtrToPtr); + _8 = Offset(copy _7, copy _3); + StorageDead(_7); + _9 = move _8 as *const T (PtrToPtr); + StorageDead(_8); goto -> bb3; } bb2: { - _11 = copy _3 as *const T (Transmute); + _9 = copy _3 as *const T (Transmute); goto -> bb3; } bb3: { + StorageLive(_10); + _10 = copy _9; + _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_10); + StorageDead(_9); + StorageDead(_4); + StorageDead(_6); + StorageDead(_3); StorageLive(_12); _12 = copy _11; - _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_12); - StorageDead(_11); - StorageDead(_8); - StorageDead(_3); - StorageLive(_14); - _14 = copy _13; goto -> bb4; } bb4: { - StorageLive(_16); - _15 = &mut _14; - _16 = as Iterator>::next(move _15) -> [return: bb5, unwind: bb11]; + StorageLive(_14); + _13 = &mut _12; + _14 = as Iterator>::next(move _13) -> [return: bb5, unwind: bb11]; } bb5: { - _17 = discriminant(_16); - switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; + _15 = discriminant(_14); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_16); StorageDead(_14); + StorageDead(_12); drop(_2) -> [return: bb7, unwind continue]; } @@ -128,18 +120,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _18 = copy ((_16 as Some).0: &T); - StorageLive(_19); - _19 = &_2; - StorageLive(_20); - _20 = (copy _18,); - _21 = >::call(move _19, move _20) -> [return: bb9, unwind: bb11]; + _16 = copy ((_14 as Some).0: &T); + StorageLive(_17); + _17 = &_2; + StorageLive(_18); + _18 = (copy _16,); + _19 = >::call(move _17, move _18) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_20); - StorageDead(_19); - StorageDead(_16); + StorageDead(_18); + StorageDead(_17); + StorageDead(_14); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir index deb12c4f1c22f..58f95d0a43231 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -4,35 +4,34 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _13: std::slice::Iter<'_, T>; - let mut _14: std::iter::Rev>; - let mut _15: std::iter::Rev>; - let mut _17: std::option::Option<&T>; - let mut _18: isize; - let mut _20: &impl Fn(&T); - let mut _21: (&T,); - let _22: (); + let mut _11: std::slice::Iter<'_, T>; + let mut _12: std::iter::Rev>; + let mut _13: std::iter::Rev>; + let mut _15: std::option::Option<&T>; + let mut _16: isize; + let mut _18: &impl Fn(&T); + let mut _19: (&T,); + let _20: (); scope 1 { - debug iter => _15; - let _19: &T; + debug iter => _13; + let _17: &T; scope 2 { - debug x => _19; + debug x => _17; } scope 18 (inlined > as Iterator>::next) { - let mut _16: &mut std::slice::Iter<'_, T>; + let mut _14: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _5: std::ptr::NonNull<[T]>; - let mut _9: *mut T; - let mut _10: *mut T; - let mut _12: *const T; + let mut _7: *mut T; + let mut _8: *mut T; + let mut _10: *const T; scope 5 { - let _8: std::ptr::NonNull; + let _6: std::ptr::NonNull; scope 6 { - let _11: *const T; + let _9: *const T; scope 7 { } scope 12 (inlined without_provenance::) { @@ -48,8 +47,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } scope 10 (inlined NonNull::<[T]>::cast::) { - let mut _6: *mut [T]; - let mut _7: *const T; + let mut _5: *const T; scope 11 (inlined NonNull::<[T]>::as_ptr) { } } @@ -64,74 +62,68 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb0: { - StorageLive(_13); + StorageLive(_11); StorageLive(_3); - StorageLive(_8); - _3 = PtrMetadata(copy _1); - StorageLive(_5); + StorageLive(_6); StorageLive(_4); + _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); - _5 = NonNull::<[T]> { pointer: move _4 }; - StorageDead(_4); - StorageLive(_6); - StorageLive(_7); - _6 = copy _5 as *mut [T] (Transmute); - _7 = copy _6 as *const T (PtrToPtr); - _8 = NonNull:: { pointer: move _7 }; - StorageDead(_7); - StorageDead(_6); + StorageLive(_5); + _5 = copy _4 as *const T (PtrToPtr); + _6 = NonNull:: { pointer: move _5 }; StorageDead(_5); - StorageLive(_11); + StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_10); - StorageLive(_9); - _9 = copy _8 as *mut T (Transmute); - _10 = Offset(copy _9, copy _3); - StorageDead(_9); - _11 = move _10 as *const T (PtrToPtr); - StorageDead(_10); + StorageLive(_8); + StorageLive(_7); + _7 = copy _4 as *mut T (PtrToPtr); + _8 = Offset(copy _7, copy _3); + StorageDead(_7); + _9 = move _8 as *const T (PtrToPtr); + StorageDead(_8); goto -> bb3; } bb2: { - _11 = copy _3 as *const T (Transmute); + _9 = copy _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageLive(_12); - _12 = copy _11; - _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_12); - StorageDead(_11); - StorageDead(_8); + StorageLive(_10); + _10 = copy _9; + _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_10); + StorageDead(_9); + StorageDead(_4); + StorageDead(_6); StorageDead(_3); - _14 = Rev::> { iter: copy _13 }; - StorageDead(_13); - StorageLive(_15); - _15 = copy _14; + _12 = Rev::> { iter: copy _11 }; + StorageDead(_11); + StorageLive(_13); + _13 = copy _12; goto -> bb4; } bb4: { - StorageLive(_17); - StorageLive(_16); - _16 = &mut (_15.0: std::slice::Iter<'_, T>); - _17 = as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind unreachable]; + StorageLive(_15); + StorageLive(_14); + _14 = &mut (_13.0: std::slice::Iter<'_, T>); + _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_16); - _18 = discriminant(_17); - switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_14); + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_17); StorageDead(_15); + StorageDead(_13); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -140,18 +132,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _19 = copy ((_17 as Some).0: &T); - StorageLive(_20); - _20 = &_2; - StorageLive(_21); - _21 = (copy _19,); - _22 = >::call(move _20, move _21) -> [return: bb9, unwind unreachable]; + _17 = copy ((_15 as Some).0: &T); + StorageLive(_18); + _18 = &_2; + StorageLive(_19); + _19 = (copy _17,); + _20 = >::call(move _18, move _19) -> [return: bb9, unwind unreachable]; } bb9: { - StorageDead(_21); - StorageDead(_20); - StorageDead(_17); + StorageDead(_19); + StorageDead(_18); + StorageDead(_15); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index acd5323eb7acd..e7ddacf314457 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -4,35 +4,34 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _13: std::slice::Iter<'_, T>; - let mut _14: std::iter::Rev>; - let mut _15: std::iter::Rev>; - let mut _17: std::option::Option<&T>; - let mut _18: isize; - let mut _20: &impl Fn(&T); - let mut _21: (&T,); - let _22: (); + let mut _11: std::slice::Iter<'_, T>; + let mut _12: std::iter::Rev>; + let mut _13: std::iter::Rev>; + let mut _15: std::option::Option<&T>; + let mut _16: isize; + let mut _18: &impl Fn(&T); + let mut _19: (&T,); + let _20: (); scope 1 { - debug iter => _15; - let _19: &T; + debug iter => _13; + let _17: &T; scope 2 { - debug x => _19; + debug x => _17; } scope 18 (inlined > as Iterator>::next) { - let mut _16: &mut std::slice::Iter<'_, T>; + let mut _14: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _5: std::ptr::NonNull<[T]>; - let mut _9: *mut T; - let mut _10: *mut T; - let mut _12: *const T; + let mut _7: *mut T; + let mut _8: *mut T; + let mut _10: *const T; scope 5 { - let _8: std::ptr::NonNull; + let _6: std::ptr::NonNull; scope 6 { - let _11: *const T; + let _9: *const T; scope 7 { } scope 12 (inlined without_provenance::) { @@ -48,8 +47,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } scope 10 (inlined NonNull::<[T]>::cast::) { - let mut _6: *mut [T]; - let mut _7: *const T; + let mut _5: *const T; scope 11 (inlined NonNull::<[T]>::as_ptr) { } } @@ -64,74 +62,68 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb0: { - StorageLive(_13); + StorageLive(_11); StorageLive(_3); - StorageLive(_8); - _3 = PtrMetadata(copy _1); - StorageLive(_5); + StorageLive(_6); StorageLive(_4); + _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); - _5 = NonNull::<[T]> { pointer: move _4 }; - StorageDead(_4); - StorageLive(_6); - StorageLive(_7); - _6 = copy _5 as *mut [T] (Transmute); - _7 = copy _6 as *const T (PtrToPtr); - _8 = NonNull:: { pointer: move _7 }; - StorageDead(_7); - StorageDead(_6); + StorageLive(_5); + _5 = copy _4 as *const T (PtrToPtr); + _6 = NonNull:: { pointer: move _5 }; StorageDead(_5); - StorageLive(_11); + StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_10); - StorageLive(_9); - _9 = copy _8 as *mut T (Transmute); - _10 = Offset(copy _9, copy _3); - StorageDead(_9); - _11 = move _10 as *const T (PtrToPtr); - StorageDead(_10); + StorageLive(_8); + StorageLive(_7); + _7 = copy _4 as *mut T (PtrToPtr); + _8 = Offset(copy _7, copy _3); + StorageDead(_7); + _9 = move _8 as *const T (PtrToPtr); + StorageDead(_8); goto -> bb3; } bb2: { - _11 = copy _3 as *const T (Transmute); + _9 = copy _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageLive(_12); - _12 = copy _11; - _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_12); - StorageDead(_11); - StorageDead(_8); + StorageLive(_10); + _10 = copy _9; + _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; + StorageDead(_10); + StorageDead(_9); + StorageDead(_4); + StorageDead(_6); StorageDead(_3); - _14 = Rev::> { iter: copy _13 }; - StorageDead(_13); - StorageLive(_15); - _15 = copy _14; + _12 = Rev::> { iter: copy _11 }; + StorageDead(_11); + StorageLive(_13); + _13 = copy _12; goto -> bb4; } bb4: { - StorageLive(_17); - StorageLive(_16); - _16 = &mut (_15.0: std::slice::Iter<'_, T>); - _17 = as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind: bb11]; + StorageLive(_15); + StorageLive(_14); + _14 = &mut (_13.0: std::slice::Iter<'_, T>); + _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11]; } bb5: { - StorageDead(_16); - _18 = discriminant(_17); - switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_14); + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_17); StorageDead(_15); + StorageDead(_13); drop(_2) -> [return: bb7, unwind continue]; } @@ -140,18 +132,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _19 = copy ((_17 as Some).0: &T); - StorageLive(_20); - _20 = &_2; - StorageLive(_21); - _21 = (copy _19,); - _22 = >::call(move _20, move _21) -> [return: bb9, unwind: bb11]; + _17 = copy ((_15 as Some).0: &T); + StorageLive(_18); + _18 = &_2; + StorageLive(_19); + _19 = (copy _17,); + _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_21); - StorageDead(_20); - StorageDead(_17); + StorageDead(_19); + StorageDead(_18); + StorageDead(_15); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir index 3f0d60b46f48b..927deabd253f1 100644 --- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir @@ -7,20 +7,16 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { debug self => _1; scope 2 (inlined Vec::::as_slice) { debug self => _1; - let mut _7: *const u8; - let mut _8: usize; + let mut _3: *const u8; + let mut _4: usize; scope 3 (inlined Vec::::as_ptr) { debug self => _1; - let mut _6: *mut u8; scope 4 (inlined alloc::raw_vec::RawVec::::ptr) { scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::) { - let mut _5: std::ptr::NonNull; scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::) { let mut _2: std::ptr::NonNull; scope 7 (inlined Unique::::cast::) { scope 8 (inlined NonNull::::cast::) { - let mut _3: *mut u8; - let mut _4: *const u8; scope 9 (inlined NonNull::::as_ptr) { } } @@ -34,9 +30,9 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { } } scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) { - debug data => _7; - debug len => _8; - let _9: *const [u8]; + debug data => _3; + debug len => _4; + let _5: *const [u8]; scope 13 (inlined core::ub_checks::check_language_ub) { scope 14 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -46,10 +42,10 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { scope 16 (inlined align_of::) { } scope 17 (inlined slice_from_raw_parts::) { - debug data => _7; - debug len => _8; + debug data => _3; + debug len => _4; scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) { - debug data_pointer => _7; + debug data_pointer => _3; } } } @@ -57,31 +53,19 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { } bb0: { - StorageLive(_6); - StorageLive(_7); - StorageLive(_5); StorageLive(_2); - _2 = copy (((((*_1).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); StorageLive(_3); + _2 = copy (((((*_1).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); + _3 = copy _2 as *const u8 (Transmute); StorageLive(_4); - _3 = copy _2 as *mut u8 (Transmute); - _4 = copy _3 as *const u8 (PtrToPtr); - _5 = NonNull:: { pointer: move _4 }; + _4 = copy ((*_1).1: usize); + StorageLive(_5); + _5 = *const [u8] from (copy _3, copy _4); + _0 = &(*_5); + StorageDead(_5); StorageDead(_4); StorageDead(_3); StorageDead(_2); - _6 = copy _5 as *mut u8 (Transmute); - StorageDead(_5); - _7 = copy _6 as *const u8 (PtrToPtr); - StorageLive(_8); - _8 = copy ((*_1).1: usize); - StorageLive(_9); - _9 = *const [u8] from (copy _7, copy _8); - _0 = &(*_9); - StorageDead(_9); - StorageDead(_8); - StorageDead(_7); - StorageDead(_6); return; } } diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir index 3f0d60b46f48b..927deabd253f1 100644 --- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir @@ -7,20 +7,16 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { debug self => _1; scope 2 (inlined Vec::::as_slice) { debug self => _1; - let mut _7: *const u8; - let mut _8: usize; + let mut _3: *const u8; + let mut _4: usize; scope 3 (inlined Vec::::as_ptr) { debug self => _1; - let mut _6: *mut u8; scope 4 (inlined alloc::raw_vec::RawVec::::ptr) { scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::) { - let mut _5: std::ptr::NonNull; scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::) { let mut _2: std::ptr::NonNull; scope 7 (inlined Unique::::cast::) { scope 8 (inlined NonNull::::cast::) { - let mut _3: *mut u8; - let mut _4: *const u8; scope 9 (inlined NonNull::::as_ptr) { } } @@ -34,9 +30,9 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { } } scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) { - debug data => _7; - debug len => _8; - let _9: *const [u8]; + debug data => _3; + debug len => _4; + let _5: *const [u8]; scope 13 (inlined core::ub_checks::check_language_ub) { scope 14 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -46,10 +42,10 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { scope 16 (inlined align_of::) { } scope 17 (inlined slice_from_raw_parts::) { - debug data => _7; - debug len => _8; + debug data => _3; + debug len => _4; scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) { - debug data_pointer => _7; + debug data_pointer => _3; } } } @@ -57,31 +53,19 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { } bb0: { - StorageLive(_6); - StorageLive(_7); - StorageLive(_5); StorageLive(_2); - _2 = copy (((((*_1).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); StorageLive(_3); + _2 = copy (((((*_1).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); + _3 = copy _2 as *const u8 (Transmute); StorageLive(_4); - _3 = copy _2 as *mut u8 (Transmute); - _4 = copy _3 as *const u8 (PtrToPtr); - _5 = NonNull:: { pointer: move _4 }; + _4 = copy ((*_1).1: usize); + StorageLive(_5); + _5 = *const [u8] from (copy _3, copy _4); + _0 = &(*_5); + StorageDead(_5); StorageDead(_4); StorageDead(_3); StorageDead(_2); - _6 = copy _5 as *mut u8 (Transmute); - StorageDead(_5); - _7 = copy _6 as *const u8 (PtrToPtr); - StorageLive(_8); - _8 = copy ((*_1).1: usize); - StorageLive(_9); - _9 = *const [u8] from (copy _7, copy _8); - _0 = &(*_9); - StorageDead(_9); - StorageDead(_8); - StorageDead(_7); - StorageDead(_6); return; } }