diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 820998eed1005..476ae059649af 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1591,10 +1591,12 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { (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 + // It 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(from) => + if !self.transmute_may_have_niche_of_interest_to_backend( + inner_from, from, to, + ) => { Some(Transmute) } @@ -1642,24 +1644,65 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { } } - /// Returns `false` if we know for sure that this type has no interesting niche, - /// and thus we can skip transmuting through it without worrying. + /// Returns `false` if we're confident that the middle type doesn't have an + /// interesting niche so we can skip that step when transmuting. /// /// 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 { + fn transmute_may_have_niche_of_interest_to_backend( + &self, + from_ty: Ty<'tcx>, + middle_ty: Ty<'tcx>, + to_ty: Ty<'tcx>, + ) -> bool { + let Ok(middle_layout) = self.ecx.layout_of(middle_ty) else { // If it's too generic or something, then assume it might be interesting later. return true; }; - if layout.uninhabited { + if middle_layout.uninhabited { return true; } - match layout.backend_repr { - BackendRepr::Scalar(a) => !a.is_always_valid(&self.ecx), + match middle_layout.backend_repr { + BackendRepr::Scalar(mid) => { + if mid.is_always_valid(&self.ecx) { + // With no niche it's never interesting, so don't bother + // looking at the layout of the other two types. + false + } else if let Ok(from_layout) = self.ecx.layout_of(from_ty) + && !from_layout.uninhabited + && from_layout.size == middle_layout.size + && let BackendRepr::Scalar(from_a) = from_layout.backend_repr + && let mid_range = mid.valid_range(&self.ecx) + && let from_range = from_a.valid_range(&self.ecx) + && mid_range.contains_range(from_range, middle_layout.size) + { + // The `from_range` is a (non-strict) subset of `mid_range` + // such as if we're doing `bool` -> `ascii::Char` -> `_`, + // where `from_range: 0..=1` and `mid_range: 0..=127`, + // and thus the middle doesn't tell us anything we don't + // already know from the initial type. + false + } else if let Ok(to_layout) = self.ecx.layout_of(to_ty) + && !to_layout.uninhabited + && to_layout.size == middle_layout.size + && let BackendRepr::Scalar(to_a) = to_layout.backend_repr + && let mid_range = mid.valid_range(&self.ecx) + && let to_range = to_a.valid_range(&self.ecx) + && mid_range.contains_range(to_range, middle_layout.size) + { + // The `to_range` is a (non-strict) subset of `mid_range` + // such as if we're doing `_` -> `ascii::Char` -> `bool`, + // where `mid_range: 0..=127` and `to_range: 0..=1`, + // and thus the middle doesn't tell us anything we don't + // already know from the final type. + false + } else { + true + } + } BackendRepr::ScalarPair(a, b) => { !a.is_always_valid(&self.ecx) || !b.is_always_valid(&self.ecx) } diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index 42c95e6c9cd25..7c34b026e14be 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -13,7 +13,12 @@ use crate::{cmp, fmt, hash, mem, num}; #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[derive(Copy, Clone, PartialEq, Eq)] #[repr(transparent)] -pub struct Alignment(AlignmentEnum); +pub struct Alignment { + // This field is never used directly (nor is the enum), + // as it's just there to convey the validity invariant. + // (Hopefully it'll eventually be a pattern type instead.) + _inner_repr_trick: AlignmentEnum, +} // Alignment is `repr(usize)`, but via extra steps. const _: () = assert!(size_of::() == size_of::()); @@ -37,7 +42,7 @@ impl Alignment { /// assert_eq!(Alignment::MIN.as_usize(), 1); /// ``` #[unstable(feature = "ptr_alignment_type", issue = "102070")] - pub const MIN: Self = Self(AlignmentEnum::_Align1Shl0); + pub const MIN: Self = Self::new(1).unwrap(); /// Returns the alignment for a type. /// @@ -166,7 +171,10 @@ impl Alignment { #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] pub const fn as_usize(self) -> usize { - self.0 as usize + // Going through `as_nonzero` helps this be more clearly the inverse of + // `new_unchecked`, letting MIR optimizations fold it away. + + self.as_nonzero().get() } /// Returns the alignment as a [NonZero]<[usize]>. 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 7a60070b7074c..5a3342a45cd3d 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 @@ -16,12 +16,11 @@ scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { - let mut _6: std::num::NonZero; scope 6 { scope 8 (inlined std::ptr::Alignment::as_nonzero) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { - let _7: *const [bool; 0]; + let _6: *const [bool; 0]; scope 10 { } scope 11 (inlined NonZero::::get) { @@ -45,11 +44,8 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); - _6 = const NonZero::(core::num::niche_types::NonZeroUsizeInner(1_usize)); - StorageLive(_7); - _7 = const {0x1 as *const [bool; 0]}; + _6 = const {0x1 as *const [bool; 0]}; _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; - StorageDead(_7); StorageDead(_6); _4 = const std::ptr::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 d13d0d962a69e..2d1b05e6e9875 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 @@ -16,12 +16,11 @@ scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { - let mut _6: std::num::NonZero; scope 6 { scope 8 (inlined std::ptr::Alignment::as_nonzero) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { - let _7: *const [bool; 0]; + let _6: *const [bool; 0]; scope 10 { } scope 11 (inlined NonZero::::get) { @@ -45,11 +44,8 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); - _6 = const NonZero::(core::num::niche_types::NonZeroUsizeInner(1_usize)); - StorageLive(_7); - _7 = const {0x1 as *const [bool; 0]}; + _6 = const {0x1 as *const [bool; 0]}; _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; - StorageDead(_7); StorageDead(_6); _4 = const std::ptr::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 8701e879e9593..695a06e29d3d7 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 @@ -16,12 +16,11 @@ scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { - let mut _6: std::num::NonZero; scope 6 { scope 8 (inlined std::ptr::Alignment::as_nonzero) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { - let _7: *const [bool; 0]; + let _6: *const [bool; 0]; scope 10 { } scope 11 (inlined NonZero::::get) { @@ -45,11 +44,8 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); - _6 = const NonZero::(core::num::niche_types::NonZeroUsizeInner(1_usize)); - StorageLive(_7); - _7 = const {0x1 as *const [bool; 0]}; + _6 = const {0x1 as *const [bool; 0]}; _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; - StorageDead(_7); StorageDead(_6); _4 = const std::ptr::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 ac1c8d627baab..17714feb1432e 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 @@ -16,12 +16,11 @@ scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { - let mut _6: std::num::NonZero; scope 6 { scope 8 (inlined std::ptr::Alignment::as_nonzero) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { - let _7: *const [bool; 0]; + let _6: *const [bool; 0]; scope 10 { } scope 11 (inlined NonZero::::get) { @@ -45,11 +44,8 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); - _6 = const NonZero::(core::num::niche_types::NonZeroUsizeInner(1_usize)); - StorageLive(_7); - _7 = const {0x1 as *const [bool; 0]}; + _6 = const {0x1 as *const [bool; 0]}; _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; - StorageDead(_7); StorageDead(_6); _4 = const std::ptr::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 0205d0cc3d167..7d66d31291155 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 @@ -16,12 +16,11 @@ scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { - let mut _6: std::num::NonZero; scope 6 { scope 8 (inlined std::ptr::Alignment::as_nonzero) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { - let _7: *const [bool; 0]; + let _6: *const [bool; 0]; scope 10 { } scope 11 (inlined NonZero::::get) { @@ -45,14 +44,10 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); -- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as std::num::NonZero (Transmute); -+ _6 = const NonZero::(core::num::niche_types::NonZeroUsizeInner(1_usize)); - StorageLive(_7); -- _7 = copy _6 as *const [bool; 0] (Transmute); -- _5 = NonNull::<[bool; 0]> { pointer: copy _7 }; -+ _7 = const {0x1 as *const [bool; 0]}; +- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as *const [bool; 0] (Transmute); +- _5 = NonNull::<[bool; 0]> { pointer: copy _6 }; ++ _6 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; - StorageDead(_7); StorageDead(_6); - _4 = std::ptr::Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; + _4 = const std::ptr::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 f6babe35b5a0b..cc00bd300a3c1 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 @@ -16,12 +16,11 @@ scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { - let mut _6: std::num::NonZero; scope 6 { scope 8 (inlined std::ptr::Alignment::as_nonzero) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { - let _7: *const [bool; 0]; + let _6: *const [bool; 0]; scope 10 { } scope 11 (inlined NonZero::::get) { @@ -45,14 +44,10 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); -- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as std::num::NonZero (Transmute); -+ _6 = const NonZero::(core::num::niche_types::NonZeroUsizeInner(1_usize)); - StorageLive(_7); -- _7 = copy _6 as *const [bool; 0] (Transmute); -- _5 = NonNull::<[bool; 0]> { pointer: copy _7 }; -+ _7 = const {0x1 as *const [bool; 0]}; +- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as *const [bool; 0] (Transmute); +- _5 = NonNull::<[bool; 0]> { pointer: copy _6 }; ++ _6 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; - StorageDead(_7); StorageDead(_6); - _4 = std::ptr::Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; + _4 = const std::ptr::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 204e59415c6bd..9380cdd6ccb4c 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 @@ -16,12 +16,11 @@ scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { - let mut _6: std::num::NonZero; scope 6 { scope 8 (inlined std::ptr::Alignment::as_nonzero) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { - let _7: *const [bool; 0]; + let _6: *const [bool; 0]; scope 10 { } scope 11 (inlined NonZero::::get) { @@ -45,14 +44,10 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); -- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as std::num::NonZero (Transmute); -+ _6 = const NonZero::(core::num::niche_types::NonZeroUsizeInner(1_usize)); - StorageLive(_7); -- _7 = copy _6 as *const [bool; 0] (Transmute); -- _5 = NonNull::<[bool; 0]> { pointer: copy _7 }; -+ _7 = const {0x1 as *const [bool; 0]}; +- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as *const [bool; 0] (Transmute); +- _5 = NonNull::<[bool; 0]> { pointer: copy _6 }; ++ _6 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; - StorageDead(_7); StorageDead(_6); - _4 = std::ptr::Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; + _4 = const std::ptr::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 0cf3f43c04646..bea5643762747 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 @@ -16,12 +16,11 @@ scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { - let mut _6: std::num::NonZero; scope 6 { scope 8 (inlined std::ptr::Alignment::as_nonzero) { } scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) { - let _7: *const [bool; 0]; + let _6: *const [bool; 0]; scope 10 { } scope 11 (inlined NonZero::::get) { @@ -45,14 +44,10 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); -- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as std::num::NonZero (Transmute); -+ _6 = const NonZero::(core::num::niche_types::NonZeroUsizeInner(1_usize)); - StorageLive(_7); -- _7 = copy _6 as *const [bool; 0] (Transmute); -- _5 = NonNull::<[bool; 0]> { pointer: copy _7 }; -+ _7 = const {0x1 as *const [bool; 0]}; +- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as *const [bool; 0] (Transmute); +- _5 = NonNull::<[bool; 0]> { pointer: copy _6 }; ++ _6 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; - StorageDead(_7); StorageDead(_6); - _4 = std::ptr::Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; + _4 = const std::ptr::Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff index 2e428b778504f..cde4d281f6877 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff @@ -111,7 +111,7 @@ bb3: { - _22 = handle_alloc_error(move _18) -> unwind unreachable; -+ _22 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}) -> unwind unreachable; ++ _22 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> unwind unreachable; } bb4: { @@ -190,12 +190,12 @@ StorageLive(_24); - _24 = copy _17 as std::ptr::Alignment (Transmute); - _18 = Layout { size: copy _16, align: move _24 }; -+ _24 = const std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0); -+ _18 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}; ++ _24 = const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }}; ++ _18 = const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}; StorageDead(_24); StorageLive(_19); - _19 = std::alloc::Global::alloc_impl_runtime(copy _18, const false) -> [return: bb7, unwind unreachable]; -+ _19 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable]; ++ _19 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}, const false) -> [return: bb7, unwind unreachable]; } bb7: { diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff index 4531720ee5013..ea5622eb9a2f7 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff @@ -111,7 +111,7 @@ bb3: { - _22 = handle_alloc_error(move _18) -> unwind unreachable; -+ _22 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}) -> unwind unreachable; ++ _22 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> unwind unreachable; } bb4: { @@ -190,12 +190,12 @@ StorageLive(_24); - _24 = copy _17 as std::ptr::Alignment (Transmute); - _18 = Layout { size: copy _16, align: move _24 }; -+ _24 = const std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0); -+ _18 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}; ++ _24 = const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }}; ++ _18 = const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}; StorageDead(_24); StorageLive(_19); - _19 = std::alloc::Global::alloc_impl_runtime(copy _18, const false) -> [return: bb7, unwind unreachable]; -+ _19 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable]; ++ _19 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}, const false) -> [return: bb7, unwind unreachable]; } bb7: { diff --git a/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff b/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff index 90920dd0be8fd..a29d3331f3800 100644 --- a/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff @@ -8,10 +8,10 @@ let mut _3: fn(u8) -> u8; let _5: (); let mut _6: fn(u8) -> u8; - let mut _9: {closure@$DIR/gvn.rs:617:19: 617:21}; + let mut _9: {closure@$DIR/gvn.rs:618:19: 618:21}; let _10: (); let mut _11: fn(); - let mut _13: {closure@$DIR/gvn.rs:617:19: 617:21}; + let mut _13: {closure@$DIR/gvn.rs:618:19: 618:21}; let _14: (); let mut _15: fn(); scope 1 { @@ -19,7 +19,7 @@ let _4: fn(u8) -> u8; scope 2 { debug g => _4; - let _7: {closure@$DIR/gvn.rs:617:19: 617:21}; + let _7: {closure@$DIR/gvn.rs:618:19: 618:21}; scope 3 { debug closure => _7; let _8: fn(); @@ -62,16 +62,16 @@ StorageDead(_6); StorageDead(_5); - StorageLive(_7); -- _7 = {closure@$DIR/gvn.rs:617:19: 617:21}; +- _7 = {closure@$DIR/gvn.rs:618:19: 618:21}; - StorageLive(_8); + nop; -+ _7 = const ZeroSized: {closure@$DIR/gvn.rs:617:19: 617:21}; ++ _7 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21}; + nop; StorageLive(_9); - _9 = copy _7; - _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:617:19: 617:21}; -+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:617:19: 617:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _9 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21}; ++ _8 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_9); StorageLive(_10); StorageLive(_11); @@ -88,8 +88,8 @@ StorageLive(_13); - _13 = copy _7; - _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:617:19: 617:21}; -+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:617:19: 617:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _13 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21}; ++ _12 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_13); StorageLive(_14); StorageLive(_15); diff --git a/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff b/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff index 0aca8e508f5c3..b716fcd4e74b8 100644 --- a/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff @@ -8,10 +8,10 @@ let mut _3: fn(u8) -> u8; let _5: (); let mut _6: fn(u8) -> u8; - let mut _9: {closure@$DIR/gvn.rs:617:19: 617:21}; + let mut _9: {closure@$DIR/gvn.rs:618:19: 618:21}; let _10: (); let mut _11: fn(); - let mut _13: {closure@$DIR/gvn.rs:617:19: 617:21}; + let mut _13: {closure@$DIR/gvn.rs:618:19: 618:21}; let _14: (); let mut _15: fn(); scope 1 { @@ -19,7 +19,7 @@ let _4: fn(u8) -> u8; scope 2 { debug g => _4; - let _7: {closure@$DIR/gvn.rs:617:19: 617:21}; + let _7: {closure@$DIR/gvn.rs:618:19: 618:21}; scope 3 { debug closure => _7; let _8: fn(); @@ -62,16 +62,16 @@ StorageDead(_6); StorageDead(_5); - StorageLive(_7); -- _7 = {closure@$DIR/gvn.rs:617:19: 617:21}; +- _7 = {closure@$DIR/gvn.rs:618:19: 618:21}; - StorageLive(_8); + nop; -+ _7 = const ZeroSized: {closure@$DIR/gvn.rs:617:19: 617:21}; ++ _7 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21}; + nop; StorageLive(_9); - _9 = copy _7; - _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:617:19: 617:21}; -+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:617:19: 617:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _9 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21}; ++ _8 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_9); StorageLive(_10); StorageLive(_11); @@ -88,8 +88,8 @@ StorageLive(_13); - _13 = copy _7; - _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:617:19: 617:21}; -+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:617:19: 617:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _13 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21}; ++ _12 = const ZeroSized: {closure@$DIR/gvn.rs:618:19: 618:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_13); StorageLive(_14); StorageLive(_15); diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 3c3241fefe22e..837e8ac4d9e34 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -9,6 +9,7 @@ #![feature(freeze)] #![allow(ambiguous_wide_pointer_comparisons)] #![allow(unconditional_panic)] +#![allow(unnecessary_transmutes)] #![allow(unused)] use std::intrinsics::mir::*; @@ -985,7 +986,14 @@ unsafe fn aggregate_struct_then_transmute(id: u16, thin: *const u8) { opaque(std::intrinsics::transmute::<_, *const u8>(j)); } -unsafe fn transmute_then_transmute_again(a: u32, c: char) { +#[repr(u8)] +enum ZeroOneTwo { + Zero, + One, + Two, +} + +unsafe fn transmute_then_transmute_again(a: u32, c: char, b: bool, d: u8) { // CHECK: [[TEMP1:_[0-9]+]] = copy _1 as char (Transmute); // CHECK: [[TEMP2:_[0-9]+]] = copy [[TEMP1]] as i32 (Transmute); // CHECK: opaque::(move [[TEMP2]]) @@ -996,6 +1004,16 @@ unsafe fn transmute_then_transmute_again(a: u32, c: char) { // CHECK: opaque::(move [[TEMP]]) let x = std::intrinsics::transmute::(c); opaque(std::intrinsics::transmute::(x)); + + // CHECK: [[TEMP:_[0-9]+]] = copy _3 as u8 (Transmute); + // CHECK: opaque::(move [[TEMP]]) + let x = std::intrinsics::transmute::(b); + opaque(std::intrinsics::transmute::(x)); + + // CHECK: [[TEMP:_[0-9]+]] = copy _4 as bool (Transmute); + // CHECK: opaque::(move [[TEMP]]) + let x = std::intrinsics::transmute::(d); + opaque(std::intrinsics::transmute::(x)); } // Transmuting can skip a pointer cast so long as it wasn't a fat-to-thin cast. 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 index 962fecd2586eb..caed065536e3a 100644 --- 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 @@ -1,71 +1,135 @@ - // 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) -> () { + fn transmute_then_transmute_again(_1: u32, _2: char, _3: bool, _4: u8) -> () { debug a => _1; debug c => _2; + debug b => _3; + debug d => _4; let mut _0: (); - let _3: char; - let mut _4: u32; - let _5: (); - let mut _6: i32; - let mut _7: char; + let _5: char; + let mut _6: u32; + let _7: (); + let mut _8: i32; let mut _9: char; - let _10: (); - let mut _11: i32; - let mut _12: u32; + let mut _11: char; + let _12: (); + let mut _13: i32; + let mut _14: u32; + let mut _16: bool; + let _17: (); + let mut _18: u8; + let mut _19: ZeroOneTwo; + let mut _21: u8; + let _22: (); + let mut _23: bool; + let mut _24: ZeroOneTwo; scope 1 { - debug x => _3; - let _8: u32; + debug x => _5; + let _10: u32; scope 2 { - debug x => _8; + debug x => _10; + let _15: ZeroOneTwo; + scope 3 { + debug x => _15; + let _20: ZeroOneTwo; + scope 4 { + debug x => _20; + } + } } } bb0: { -- StorageLive(_3); +- StorageLive(_5); + nop; - StorageLive(_4); - _4 = copy _1; -- _3 = move _4 as char (Transmute); -+ _3 = copy _1 as char (Transmute); - StorageDead(_4); - StorageLive(_5); StorageLive(_6); + _6 = copy _1; +- _5 = move _6 as char (Transmute); ++ _5 = copy _1 as char (Transmute); + StorageDead(_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]; + StorageLive(_8); + StorageLive(_9); + _9 = copy _5; +- _8 = move _9 as i32 (Transmute); ++ _8 = copy _5 as i32 (Transmute); + StorageDead(_9); + _7 = opaque::(move _8) -> [return: bb1, unwind unreachable]; } bb1: { - StorageDead(_6); - StorageDead(_5); -- StorageLive(_8); + StorageDead(_8); + StorageDead(_7); +- StorageLive(_10); + nop; - StorageLive(_9); - _9 = copy _2; -- _8 = move _9 as u32 (Transmute); -+ _8 = copy _2 as u32 (Transmute); - StorageDead(_9); - StorageLive(_10); StorageLive(_11); + _11 = copy _2; +- _10 = move _11 as u32 (Transmute); ++ _10 = copy _2 as u32 (Transmute); + StorageDead(_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]; + StorageLive(_13); + StorageLive(_14); + _14 = copy _10; +- _13 = move _14 as i32 (Transmute); ++ _13 = copy _2 as i32 (Transmute); + StorageDead(_14); + _12 = opaque::(move _13) -> [return: bb2, unwind unreachable]; } bb2: { - StorageDead(_11); - StorageDead(_10); + StorageDead(_13); + StorageDead(_12); +- StorageLive(_15); ++ nop; + StorageLive(_16); + _16 = copy _3; +- _15 = move _16 as ZeroOneTwo (Transmute); ++ _15 = copy _3 as ZeroOneTwo (Transmute); + StorageDead(_16); + StorageLive(_17); + StorageLive(_18); + StorageLive(_19); +- _19 = move _15; +- _18 = move _19 as u8 (Transmute); ++ _19 = copy _15; ++ _18 = copy _3 as u8 (Transmute); + StorageDead(_19); + _17 = opaque::(move _18) -> [return: bb3, unwind unreachable]; + } + + bb3: { + StorageDead(_18); + StorageDead(_17); +- StorageLive(_20); ++ nop; + StorageLive(_21); + _21 = copy _4; +- _20 = move _21 as ZeroOneTwo (Transmute); ++ _20 = copy _4 as ZeroOneTwo (Transmute); + StorageDead(_21); + StorageLive(_22); + StorageLive(_23); + StorageLive(_24); +- _24 = move _20; +- _23 = move _24 as bool (Transmute); ++ _24 = copy _20; ++ _23 = copy _4 as bool (Transmute); + StorageDead(_24); + _22 = opaque::(move _23) -> [return: bb4, unwind unreachable]; + } + + bb4: { + StorageDead(_23); + StorageDead(_22); _0 = const (); -- StorageDead(_8); -- StorageDead(_3); +- StorageDead(_20); +- StorageDead(_15); +- StorageDead(_10); +- StorageDead(_5); ++ nop; ++ nop; + 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 index e32397c1aed07..3b25dd362cd5c 100644 --- 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 @@ -1,71 +1,135 @@ - // 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) -> () { + fn transmute_then_transmute_again(_1: u32, _2: char, _3: bool, _4: u8) -> () { debug a => _1; debug c => _2; + debug b => _3; + debug d => _4; let mut _0: (); - let _3: char; - let mut _4: u32; - let _5: (); - let mut _6: i32; - let mut _7: char; + let _5: char; + let mut _6: u32; + let _7: (); + let mut _8: i32; let mut _9: char; - let _10: (); - let mut _11: i32; - let mut _12: u32; + let mut _11: char; + let _12: (); + let mut _13: i32; + let mut _14: u32; + let mut _16: bool; + let _17: (); + let mut _18: u8; + let mut _19: ZeroOneTwo; + let mut _21: u8; + let _22: (); + let mut _23: bool; + let mut _24: ZeroOneTwo; scope 1 { - debug x => _3; - let _8: u32; + debug x => _5; + let _10: u32; scope 2 { - debug x => _8; + debug x => _10; + let _15: ZeroOneTwo; + scope 3 { + debug x => _15; + let _20: ZeroOneTwo; + scope 4 { + debug x => _20; + } + } } } bb0: { -- StorageLive(_3); +- StorageLive(_5); + nop; - StorageLive(_4); - _4 = copy _1; -- _3 = move _4 as char (Transmute); -+ _3 = copy _1 as char (Transmute); - StorageDead(_4); - StorageLive(_5); StorageLive(_6); + _6 = copy _1; +- _5 = move _6 as char (Transmute); ++ _5 = copy _1 as char (Transmute); + StorageDead(_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]; + StorageLive(_8); + StorageLive(_9); + _9 = copy _5; +- _8 = move _9 as i32 (Transmute); ++ _8 = copy _5 as i32 (Transmute); + StorageDead(_9); + _7 = opaque::(move _8) -> [return: bb1, unwind continue]; } bb1: { - StorageDead(_6); - StorageDead(_5); -- StorageLive(_8); + StorageDead(_8); + StorageDead(_7); +- StorageLive(_10); + nop; - StorageLive(_9); - _9 = copy _2; -- _8 = move _9 as u32 (Transmute); -+ _8 = copy _2 as u32 (Transmute); - StorageDead(_9); - StorageLive(_10); StorageLive(_11); + _11 = copy _2; +- _10 = move _11 as u32 (Transmute); ++ _10 = copy _2 as u32 (Transmute); + StorageDead(_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]; + StorageLive(_13); + StorageLive(_14); + _14 = copy _10; +- _13 = move _14 as i32 (Transmute); ++ _13 = copy _2 as i32 (Transmute); + StorageDead(_14); + _12 = opaque::(move _13) -> [return: bb2, unwind continue]; } bb2: { - StorageDead(_11); - StorageDead(_10); + StorageDead(_13); + StorageDead(_12); +- StorageLive(_15); ++ nop; + StorageLive(_16); + _16 = copy _3; +- _15 = move _16 as ZeroOneTwo (Transmute); ++ _15 = copy _3 as ZeroOneTwo (Transmute); + StorageDead(_16); + StorageLive(_17); + StorageLive(_18); + StorageLive(_19); +- _19 = move _15; +- _18 = move _19 as u8 (Transmute); ++ _19 = copy _15; ++ _18 = copy _3 as u8 (Transmute); + StorageDead(_19); + _17 = opaque::(move _18) -> [return: bb3, unwind continue]; + } + + bb3: { + StorageDead(_18); + StorageDead(_17); +- StorageLive(_20); ++ nop; + StorageLive(_21); + _21 = copy _4; +- _20 = move _21 as ZeroOneTwo (Transmute); ++ _20 = copy _4 as ZeroOneTwo (Transmute); + StorageDead(_21); + StorageLive(_22); + StorageLive(_23); + StorageLive(_24); +- _24 = move _20; +- _23 = move _24 as bool (Transmute); ++ _24 = copy _20; ++ _23 = copy _4 as bool (Transmute); + StorageDead(_24); + _22 = opaque::(move _23) -> [return: bb4, unwind continue]; + } + + bb4: { + StorageDead(_23); + StorageDead(_22); _0 = const (); -- StorageDead(_8); -- StorageDead(_3); +- StorageDead(_20); +- StorageDead(_15); +- StorageDead(_10); +- StorageDead(_5); ++ nop; ++ nop; + nop; + nop; return; diff --git a/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff b/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff index f56af33ea603f..9e543699da70f 100644 --- a/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff +++ b/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff @@ -7,7 +7,7 @@ let mut _2: *mut u8; scope 1 (inlined dangling_mut::) { scope 2 (inlined NonNull::::dangling) { - let mut _3: std::num::NonZero; + let _3: std::ptr::Alignment; scope 3 { scope 5 (inlined std::ptr::Alignment::as_nonzero) { } @@ -40,9 +40,9 @@ StorageLive(_1); StorageLive(_2); StorageLive(_3); -- _3 = const std::ptr::Alignment::of::::{constant#0} as std::num::NonZero (Transmute); +- _3 = const std::ptr::Alignment::of::::{constant#0}; - _2 = copy _3 as *mut u8 (Transmute); -+ _3 = const NonZero::(core::num::niche_types::NonZeroUsizeInner(1_usize)); ++ _3 = const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }}; + _2 = const {0x1 as *mut u8}; StorageDead(_3); StorageLive(_4); diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir index 6ffadd4c51db1..0adc66951e78b 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir @@ -8,9 +8,8 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { let _2: std::ptr::NonNull<[T]>; let mut _3: *mut [T]; let mut _4: *const [T]; - let _11: (); + let _10: (); scope 3 { - let _8: std::ptr::alignment::AlignmentEnum; scope 4 { scope 17 (inlined Layout::size) { } @@ -27,17 +26,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { scope 23 (inlined ::deallocate) { scope 24 (inlined std::alloc::Global::deallocate_impl) { scope 25 (inlined std::alloc::Global::deallocate_impl_runtime) { - let mut _9: *mut u8; + let mut _8: *mut u8; scope 26 (inlined Layout::size) { } scope 27 (inlined NonNull::::as_ptr) { } scope 28 (inlined std::alloc::dealloc) { - let mut _10: usize; + let mut _9: usize; scope 29 (inlined Layout::size) { } scope 30 (inlined Layout::align) { scope 31 (inlined std::ptr::Alignment::as_usize) { + scope 32 (inlined std::ptr::Alignment::as_nonzero) { + } + scope 33 (inlined NonZero::::get) { + } } } } @@ -82,7 +85,6 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { StorageLive(_4); _3 = copy _2 as *mut [T] (Transmute); _4 = copy _2 as *const [T] (Transmute); - StorageLive(_7); _5 = std::intrinsics::size_of_val::<[T]>(move _4) -> [return: bb1, unwind unreachable]; } @@ -91,23 +93,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { _6 = const ::ALIGN; _7 = copy _6 as std::ptr::Alignment (Transmute); StorageDead(_6); - _8 = copy (_7.0: std::ptr::alignment::AlignmentEnum); - StorageDead(_7); StorageDead(_4); switchInt(copy _5) -> [0: bb4, otherwise: bb2]; } bb2: { + StorageLive(_8); + _8 = copy _3 as *mut u8 (PtrToPtr); StorageLive(_9); - _9 = copy _3 as *mut u8 (PtrToPtr); - StorageLive(_10); - _10 = discriminant(_8); - _11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable]; + _9 = copy _7 as usize (Transmute); + _10 = alloc::alloc::__rust_dealloc(move _8, move _5, move _9) -> [return: bb3, unwind unreachable]; } bb3: { - StorageDead(_10); StorageDead(_9); + StorageDead(_8); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir index 6ffadd4c51db1..0adc66951e78b 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir @@ -8,9 +8,8 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { let _2: std::ptr::NonNull<[T]>; let mut _3: *mut [T]; let mut _4: *const [T]; - let _11: (); + let _10: (); scope 3 { - let _8: std::ptr::alignment::AlignmentEnum; scope 4 { scope 17 (inlined Layout::size) { } @@ -27,17 +26,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { scope 23 (inlined ::deallocate) { scope 24 (inlined std::alloc::Global::deallocate_impl) { scope 25 (inlined std::alloc::Global::deallocate_impl_runtime) { - let mut _9: *mut u8; + let mut _8: *mut u8; scope 26 (inlined Layout::size) { } scope 27 (inlined NonNull::::as_ptr) { } scope 28 (inlined std::alloc::dealloc) { - let mut _10: usize; + let mut _9: usize; scope 29 (inlined Layout::size) { } scope 30 (inlined Layout::align) { scope 31 (inlined std::ptr::Alignment::as_usize) { + scope 32 (inlined std::ptr::Alignment::as_nonzero) { + } + scope 33 (inlined NonZero::::get) { + } } } } @@ -82,7 +85,6 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { StorageLive(_4); _3 = copy _2 as *mut [T] (Transmute); _4 = copy _2 as *const [T] (Transmute); - StorageLive(_7); _5 = std::intrinsics::size_of_val::<[T]>(move _4) -> [return: bb1, unwind unreachable]; } @@ -91,23 +93,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { _6 = const ::ALIGN; _7 = copy _6 as std::ptr::Alignment (Transmute); StorageDead(_6); - _8 = copy (_7.0: std::ptr::alignment::AlignmentEnum); - StorageDead(_7); StorageDead(_4); switchInt(copy _5) -> [0: bb4, otherwise: bb2]; } bb2: { + StorageLive(_8); + _8 = copy _3 as *mut u8 (PtrToPtr); StorageLive(_9); - _9 = copy _3 as *mut u8 (PtrToPtr); - StorageLive(_10); - _10 = discriminant(_8); - _11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable]; + _9 = copy _7 as usize (Transmute); + _10 = alloc::alloc::__rust_dealloc(move _8, move _5, move _9) -> [return: bb3, unwind unreachable]; } bb3: { - StorageDead(_10); StorageDead(_9); + StorageDead(_8); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir index 6ffadd4c51db1..0adc66951e78b 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir @@ -8,9 +8,8 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { let _2: std::ptr::NonNull<[T]>; let mut _3: *mut [T]; let mut _4: *const [T]; - let _11: (); + let _10: (); scope 3 { - let _8: std::ptr::alignment::AlignmentEnum; scope 4 { scope 17 (inlined Layout::size) { } @@ -27,17 +26,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { scope 23 (inlined ::deallocate) { scope 24 (inlined std::alloc::Global::deallocate_impl) { scope 25 (inlined std::alloc::Global::deallocate_impl_runtime) { - let mut _9: *mut u8; + let mut _8: *mut u8; scope 26 (inlined Layout::size) { } scope 27 (inlined NonNull::::as_ptr) { } scope 28 (inlined std::alloc::dealloc) { - let mut _10: usize; + let mut _9: usize; scope 29 (inlined Layout::size) { } scope 30 (inlined Layout::align) { scope 31 (inlined std::ptr::Alignment::as_usize) { + scope 32 (inlined std::ptr::Alignment::as_nonzero) { + } + scope 33 (inlined NonZero::::get) { + } } } } @@ -82,7 +85,6 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { StorageLive(_4); _3 = copy _2 as *mut [T] (Transmute); _4 = copy _2 as *const [T] (Transmute); - StorageLive(_7); _5 = std::intrinsics::size_of_val::<[T]>(move _4) -> [return: bb1, unwind unreachable]; } @@ -91,23 +93,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { _6 = const ::ALIGN; _7 = copy _6 as std::ptr::Alignment (Transmute); StorageDead(_6); - _8 = copy (_7.0: std::ptr::alignment::AlignmentEnum); - StorageDead(_7); StorageDead(_4); switchInt(copy _5) -> [0: bb4, otherwise: bb2]; } bb2: { + StorageLive(_8); + _8 = copy _3 as *mut u8 (PtrToPtr); StorageLive(_9); - _9 = copy _3 as *mut u8 (PtrToPtr); - StorageLive(_10); - _10 = discriminant(_8); - _11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable]; + _9 = copy _7 as usize (Transmute); + _10 = alloc::alloc::__rust_dealloc(move _8, move _5, move _9) -> [return: bb3, unwind unreachable]; } bb3: { - StorageDead(_10); StorageDead(_9); + StorageDead(_8); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir index 6ffadd4c51db1..0adc66951e78b 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir @@ -8,9 +8,8 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { let _2: std::ptr::NonNull<[T]>; let mut _3: *mut [T]; let mut _4: *const [T]; - let _11: (); + let _10: (); scope 3 { - let _8: std::ptr::alignment::AlignmentEnum; scope 4 { scope 17 (inlined Layout::size) { } @@ -27,17 +26,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { scope 23 (inlined ::deallocate) { scope 24 (inlined std::alloc::Global::deallocate_impl) { scope 25 (inlined std::alloc::Global::deallocate_impl_runtime) { - let mut _9: *mut u8; + let mut _8: *mut u8; scope 26 (inlined Layout::size) { } scope 27 (inlined NonNull::::as_ptr) { } scope 28 (inlined std::alloc::dealloc) { - let mut _10: usize; + let mut _9: usize; scope 29 (inlined Layout::size) { } scope 30 (inlined Layout::align) { scope 31 (inlined std::ptr::Alignment::as_usize) { + scope 32 (inlined std::ptr::Alignment::as_nonzero) { + } + scope 33 (inlined NonZero::::get) { + } } } } @@ -82,7 +85,6 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { StorageLive(_4); _3 = copy _2 as *mut [T] (Transmute); _4 = copy _2 as *const [T] (Transmute); - StorageLive(_7); _5 = std::intrinsics::size_of_val::<[T]>(move _4) -> [return: bb1, unwind unreachable]; } @@ -91,23 +93,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { _6 = const ::ALIGN; _7 = copy _6 as std::ptr::Alignment (Transmute); StorageDead(_6); - _8 = copy (_7.0: std::ptr::alignment::AlignmentEnum); - StorageDead(_7); StorageDead(_4); switchInt(copy _5) -> [0: bb4, otherwise: bb2]; } bb2: { + StorageLive(_8); + _8 = copy _3 as *mut u8 (PtrToPtr); StorageLive(_9); - _9 = copy _3 as *mut u8 (PtrToPtr); - StorageLive(_10); - _10 = discriminant(_8); - _11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable]; + _9 = copy _7 as usize (Transmute); + _10 = alloc::alloc::__rust_dealloc(move _8, move _5, move _9) -> [return: bb3, unwind unreachable]; } bb3: { - StorageDead(_10); StorageDead(_9); + StorageDead(_8); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.rs b/tests/mir-opt/pre-codegen/drop_boxed_slice.rs index dddcffdd48439..cad7251421ebf 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.rs +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.rs @@ -11,8 +11,7 @@ pub unsafe fn generic_in_place(ptr: *mut Box<[T]>) { // CHECK: [[SIZE:_.+]] = std::intrinsics::size_of_val::<[T]> // CHECK: [[ALIGN:_.+]] = const ::ALIGN; // CHECK: [[B:_.+]] = copy [[ALIGN]] as std::ptr::Alignment (Transmute); - // CHECK: [[C:_.+]] = copy ([[B]].0: std::ptr::alignment::AlignmentEnum); - // CHECK: [[D:_.+]] = discriminant([[C]]); - // CHECK: = alloc::alloc::__rust_dealloc({{.+}}, move [[SIZE]], move [[D]]) -> + // CHECK: [[C:_.+]] = copy [[B]] as usize (Transmute); + // CHECK: = alloc::alloc::__rust_dealloc({{.+}}, move [[SIZE]], move [[C]]) -> std::ptr::drop_in_place(ptr) } diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff index d0fda06c115ce..b48e6fc56f430 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff @@ -63,7 +63,7 @@ bb3: { - _1 = move ((_2 as Some).0: std::alloc::Layout); -+ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}; ++ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x00000000): std::ptr::alignment::AlignmentEnum }} }}; StorageDead(_8); StorageDead(_2); StorageLive(_3); @@ -73,8 +73,8 @@ StorageLive(_7); - _7 = copy _1; - _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb4, unwind unreachable]; -+ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}; -+ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb4, unwind unreachable]; ++ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x00000000): std::ptr::alignment::AlignmentEnum }} }}; ++ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x00000000): std::ptr::alignment::AlignmentEnum }} }}, const false) -> [return: bb4, unwind unreachable]; } bb4: { diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff index 485ff902a7b9d..d0e59c06ff995 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff @@ -64,7 +64,7 @@ bb4: { - _1 = move ((_2 as Some).0: std::alloc::Layout); -+ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}; ++ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x00000000): std::ptr::alignment::AlignmentEnum }} }}; StorageDead(_8); StorageDead(_2); StorageLive(_3); @@ -74,8 +74,8 @@ StorageLive(_7); - _7 = copy _1; - _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb5, unwind continue]; -+ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}; -+ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb5, unwind continue]; ++ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x00000000): std::ptr::alignment::AlignmentEnum }} }}; ++ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x00000000): std::ptr::alignment::AlignmentEnum }} }}, const false) -> [return: bb5, unwind continue]; } bb5: { diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff index b45a0f4a9bdd0..18fc4ac0d87f1 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff @@ -63,7 +63,7 @@ bb3: { - _1 = move ((_2 as Some).0: std::alloc::Layout); -+ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}; ++ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum }} }}; StorageDead(_8); StorageDead(_2); StorageLive(_3); @@ -73,8 +73,8 @@ StorageLive(_7); - _7 = copy _1; - _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb4, unwind unreachable]; -+ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}; -+ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb4, unwind unreachable]; ++ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum }} }}; ++ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum }} }}, const false) -> [return: bb4, unwind unreachable]; } bb4: { diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff index beee899dafe6e..c109fe735e898 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff @@ -64,7 +64,7 @@ bb4: { - _1 = move ((_2 as Some).0: std::alloc::Layout); -+ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}; ++ _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum }} }}; StorageDead(_8); StorageDead(_2); StorageLive(_3); @@ -74,8 +74,8 @@ StorageLive(_7); - _7 = copy _1; - _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb5, unwind continue]; -+ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}; -+ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb5, unwind continue]; ++ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum }} }}; ++ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment {{ _inner_repr_trick: Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum }} }}, const false) -> [return: bb5, unwind continue]; } bb5: {