diff --git a/compiler/rustc_mir_transform/src/cost_checker.rs b/compiler/rustc_mir_transform/src/cost_checker.rs index 32c0d27f635c7..7e401b5482f3d 100644 --- a/compiler/rustc_mir_transform/src/cost_checker.rs +++ b/compiler/rustc_mir_transform/src/cost_checker.rs @@ -60,7 +60,15 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, _location: Location) { match rvalue { - Rvalue::NullaryOp(NullOp::UbChecks, ..) if !self.tcx.sess.ub_checks() => { + Rvalue::NullaryOp(NullOp::UbChecks, ..) + if !self + .tcx + .sess + .opts + .unstable_opts + .inline_mir_preserve_debug + .unwrap_or(self.tcx.sess.ub_checks()) => + { // If this is in optimized MIR it's because it's used later, // so if we don't need UB checks this session, give a bonus // here to offset the cost of the call later. @@ -111,12 +119,19 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { } } TerminatorKind::Assert { unwind, msg, .. } => { - self.penalty += - if msg.is_optional_overflow_check() && !self.tcx.sess.overflow_checks() { - INSTR_COST - } else { - CALL_PENALTY - }; + self.penalty += if msg.is_optional_overflow_check() + && !self + .tcx + .sess + .opts + .unstable_opts + .inline_mir_preserve_debug + .unwrap_or(self.tcx.sess.overflow_checks()) + { + INSTR_COST + } else { + CALL_PENALTY + }; if let UnwindAction::Cleanup(_) = unwind { self.penalty += LANDINGPAD_PENALTY; } 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 fbb887fe76a59..79c5bcfe9cd5c 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -7,19 +7,90 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _11: std::slice::Iter<'_, T>; let mut _12: std::iter::Rev>; let mut _13: std::iter::Rev>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _37: std::option::Option<&T>; + let mut _39: &impl Fn(&T); + let mut _40: (&T,); + let _41: (); scope 1 { debug iter => _13; - let _17: &T; + let _38: &T; scope 2 { - debug x => _17; + debug x => _38; } scope 17 (inlined > as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; + scope 18 (inlined as DoubleEndedIterator>::next_back) { + let mut _14: *const *const T; + let mut _15: *const std::ptr::NonNull; + let mut _20: bool; + let mut _21: *const T; + let _36: &T; + scope 19 { + let _16: std::ptr::NonNull; + let _22: usize; + scope 20 { + } + scope 21 { + scope 25 (inlined as PartialEq>::eq) { + let mut _17: std::ptr::NonNull; + scope 26 (inlined NonNull::::as_ptr) { + let mut _18: *const T; + } + scope 27 (inlined NonNull::::as_ptr) { + let mut _19: *const T; + } + } + } + scope 22 (inlined std::ptr::const_ptr::::addr) { + scope 23 (inlined std::ptr::const_ptr::::cast::<()>) { + } + } + scope 24 (inlined std::ptr::const_ptr::::cast::>) { + } + } + scope 28 (inlined std::slice::Iter::<'_, T>::next_back_unchecked) { + let _29: std::ptr::NonNull; + scope 29 (inlined std::slice::Iter::<'_, T>::pre_dec_end) { + let mut _23: *mut *const T; + let mut _24: *mut std::ptr::NonNull; + let mut _25: std::ptr::NonNull; + let mut _28: std::ptr::NonNull; + let mut _30: *mut *const T; + let mut _31: *mut usize; + let mut _32: usize; + let mut _33: usize; + scope 30 { + scope 31 { + } + scope 32 { + scope 35 (inlined NonNull::::sub) { + scope 36 (inlined core::num::::unchecked_neg) { + scope 37 (inlined core::ub_checks::check_language_ub) { + scope 38 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 39 (inlined NonNull::::offset) { + let mut _26: *const T; + let mut _27: *const T; + } + } + } + scope 33 (inlined std::ptr::mut_ptr::::cast::) { + } + scope 34 (inlined std::ptr::mut_ptr::::cast::>) { + } + } + } + scope 40 (inlined NonNull::::as_ref::<'_>) { + let mut _34: std::ptr::NonNull; + scope 41 (inlined NonNull::::as_ptr) { + let mut _35: *const T; + } + scope 42 (inlined std::ptr::mut_ptr::::cast_const) { + } + } + } + } } } scope 3 (inlined core::slice::::iter) { @@ -107,45 +178,147 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb4: { - StorageLive(_15); - StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable]; + StorageLive(_37); + StorageLive(_22); + StorageLive(_21); + StorageLive(_16); + StorageLive(_36); + StorageLive(_20); + switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb6]; } bb5: { + StorageLive(_15); + StorageLive(_14); + _14 = &raw const ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _15 = _14 as *const std::ptr::NonNull (PtrToPtr); StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + _16 = (*_15); + StorageDead(_15); + StorageLive(_18); + StorageLive(_19); + StorageLive(_17); + _17 = ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); + _18 = (_17.0: *const T); + StorageDead(_17); + _19 = (_16.0: *const T); + _20 = Eq(_18, _19); + StorageDead(_19); + StorageDead(_18); + goto -> bb7; } bb6: { - StorageDead(_15); - StorageDead(_13); - drop(_2) -> [return: bb7, unwind unreachable]; + _21 = ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _22 = _21 as usize (Transmute); + _20 = Eq(_22, const 0_usize); + goto -> bb7; } bb7: { - return; + switchInt(move _20) -> [0: bb8, otherwise: bb16]; } bb8: { - _17 = ((_15 as Some).0: &T); - StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (_17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind unreachable]; + StorageLive(_35); + StorageLive(_29); + StorageLive(_31); + StorageLive(_24); + switchInt(const ::IS_ZST) -> [0: bb9, otherwise: bb13]; } bb9: { - StorageDead(_19); - StorageDead(_18); - StorageDead(_15); - goto -> bb4; + StorageLive(_23); + _23 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _24 = _23 as *mut std::ptr::NonNull (PtrToPtr); + StorageDead(_23); + StorageLive(_28); + _25 = (*_24); + switchInt(const ::IS_ZST) -> [0: bb10, otherwise: bb11]; } bb10: { - unreachable; + StorageLive(_27); + StorageLive(_26); + _26 = (_25.0: *const T); + _27 = Offset(move _26, const -1_isize); + StorageDead(_26); + _28 = NonNull:: { pointer: move _27 }; + StorageDead(_27); + goto -> bb12; + } + + bb11: { + _28 = _25; + goto -> bb12; + } + + bb12: { + (*_24) = move _28; + StorageDead(_28); + _29 = (*_24); + goto -> bb14; + } + + bb13: { + StorageLive(_30); + _30 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _31 = _30 as *mut usize (PtrToPtr); + StorageDead(_30); + StorageLive(_33); + StorageLive(_32); + _32 = (*_31); + _33 = SubUnchecked(move _32, const 1_usize); + StorageDead(_32); + (*_31) = move _33; + StorageDead(_33); + _29 = ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); + goto -> bb14; + } + + bb14: { + StorageDead(_24); + StorageDead(_31); + StorageLive(_34); + _34 = _29; + _35 = (_34.0: *const T); + StorageDead(_34); + _36 = &(*_35); + StorageDead(_29); + StorageDead(_35); + _37 = Option::<&T>::Some(_36); + StorageDead(_20); + StorageDead(_36); + StorageDead(_16); + StorageDead(_21); + StorageDead(_22); + _38 = ((_37 as Some).0: &T); + StorageLive(_39); + _39 = &_2; + StorageLive(_40); + _40 = (_38,); + _41 = >::call(move _39, move _40) -> [return: bb15, unwind unreachable]; + } + + bb15: { + StorageDead(_40); + StorageDead(_39); + StorageDead(_37); + goto -> bb4; + } + + bb16: { + StorageDead(_20); + StorageDead(_36); + StorageDead(_16); + StorageDead(_21); + StorageDead(_22); + StorageDead(_37); + StorageDead(_13); + drop(_2) -> [return: bb17, unwind unreachable]; + } + + bb17: { + return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index db9409f72ab1a..7c107a23f9e0b 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -7,19 +7,90 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _11: std::slice::Iter<'_, T>; let mut _12: std::iter::Rev>; let mut _13: std::iter::Rev>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _37: std::option::Option<&T>; + let mut _39: &impl Fn(&T); + let mut _40: (&T,); + let _41: (); scope 1 { debug iter => _13; - let _17: &T; + let _38: &T; scope 2 { - debug x => _17; + debug x => _38; } scope 17 (inlined > as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; + scope 18 (inlined as DoubleEndedIterator>::next_back) { + let mut _14: *const *const T; + let mut _15: *const std::ptr::NonNull; + let mut _20: bool; + let mut _21: *const T; + let _36: &T; + scope 19 { + let _16: std::ptr::NonNull; + let _22: usize; + scope 20 { + } + scope 21 { + scope 25 (inlined as PartialEq>::eq) { + let mut _17: std::ptr::NonNull; + scope 26 (inlined NonNull::::as_ptr) { + let mut _18: *const T; + } + scope 27 (inlined NonNull::::as_ptr) { + let mut _19: *const T; + } + } + } + scope 22 (inlined std::ptr::const_ptr::::addr) { + scope 23 (inlined std::ptr::const_ptr::::cast::<()>) { + } + } + scope 24 (inlined std::ptr::const_ptr::::cast::>) { + } + } + scope 28 (inlined std::slice::Iter::<'_, T>::next_back_unchecked) { + let _29: std::ptr::NonNull; + scope 29 (inlined std::slice::Iter::<'_, T>::pre_dec_end) { + let mut _23: *mut *const T; + let mut _24: *mut std::ptr::NonNull; + let mut _25: std::ptr::NonNull; + let mut _28: std::ptr::NonNull; + let mut _30: *mut *const T; + let mut _31: *mut usize; + let mut _32: usize; + let mut _33: usize; + scope 30 { + scope 31 { + } + scope 32 { + scope 35 (inlined NonNull::::sub) { + scope 36 (inlined core::num::::unchecked_neg) { + scope 37 (inlined core::ub_checks::check_language_ub) { + scope 38 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 39 (inlined NonNull::::offset) { + let mut _26: *const T; + let mut _27: *const T; + } + } + } + scope 33 (inlined std::ptr::mut_ptr::::cast::) { + } + scope 34 (inlined std::ptr::mut_ptr::::cast::>) { + } + } + } + scope 40 (inlined NonNull::::as_ref::<'_>) { + let mut _34: std::ptr::NonNull; + scope 41 (inlined NonNull::::as_ptr) { + let mut _35: *const T; + } + scope 42 (inlined std::ptr::mut_ptr::::cast_const) { + } + } + } + } } } scope 3 (inlined core::slice::::iter) { @@ -107,53 +178,155 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb4: { - StorageLive(_15); - StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11]; + StorageLive(_37); + StorageLive(_22); + StorageLive(_21); + StorageLive(_16); + StorageLive(_36); + StorageLive(_20); + switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb6]; } bb5: { + StorageLive(_15); + StorageLive(_14); + _14 = &raw const ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _15 = _14 as *const std::ptr::NonNull (PtrToPtr); StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + _16 = (*_15); + StorageDead(_15); + StorageLive(_18); + StorageLive(_19); + StorageLive(_17); + _17 = ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); + _18 = (_17.0: *const T); + StorageDead(_17); + _19 = (_16.0: *const T); + _20 = Eq(_18, _19); + StorageDead(_19); + StorageDead(_18); + goto -> bb7; } bb6: { - StorageDead(_15); - StorageDead(_13); - drop(_2) -> [return: bb7, unwind continue]; + _21 = ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _22 = _21 as usize (Transmute); + _20 = Eq(_22, const 0_usize); + goto -> bb7; } bb7: { - return; + switchInt(move _20) -> [0: bb8, otherwise: bb18]; } bb8: { - _17 = ((_15 as Some).0: &T); - StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (_17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; + StorageLive(_35); + StorageLive(_29); + StorageLive(_31); + StorageLive(_24); + switchInt(const ::IS_ZST) -> [0: bb9, otherwise: bb13]; } bb9: { - StorageDead(_19); - StorageDead(_18); - StorageDead(_15); - goto -> bb4; + StorageLive(_23); + _23 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _24 = _23 as *mut std::ptr::NonNull (PtrToPtr); + StorageDead(_23); + StorageLive(_28); + _25 = (*_24); + switchInt(const ::IS_ZST) -> [0: bb10, otherwise: bb11]; } bb10: { - unreachable; + StorageLive(_27); + StorageLive(_26); + _26 = (_25.0: *const T); + _27 = Offset(move _26, const -1_isize); + StorageDead(_26); + _28 = NonNull:: { pointer: move _27 }; + StorageDead(_27); + goto -> bb12; + } + + bb11: { + _28 = _25; + goto -> bb12; + } + + bb12: { + (*_24) = move _28; + StorageDead(_28); + _29 = (*_24); + goto -> bb14; + } + + bb13: { + StorageLive(_30); + _30 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); + _31 = _30 as *mut usize (PtrToPtr); + StorageDead(_30); + StorageLive(_33); + StorageLive(_32); + _32 = (*_31); + _33 = SubUnchecked(move _32, const 1_usize); + StorageDead(_32); + (*_31) = move _33; + StorageDead(_33); + _29 = ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); + goto -> bb14; } - bb11 (cleanup): { - drop(_2) -> [return: bb12, unwind terminate(cleanup)]; + bb14: { + StorageDead(_24); + StorageDead(_31); + StorageLive(_34); + _34 = _29; + _35 = (_34.0: *const T); + StorageDead(_34); + _36 = &(*_35); + StorageDead(_29); + StorageDead(_35); + _37 = Option::<&T>::Some(_36); + StorageDead(_20); + StorageDead(_36); + StorageDead(_16); + StorageDead(_21); + StorageDead(_22); + _38 = ((_37 as Some).0: &T); + StorageLive(_39); + _39 = &_2; + StorageLive(_40); + _40 = (_38,); + _41 = >::call(move _39, move _40) -> [return: bb15, unwind: bb16]; } - bb12 (cleanup): { + bb15: { + StorageDead(_40); + StorageDead(_39); + StorageDead(_37); + goto -> bb4; + } + + bb16 (cleanup): { + drop(_2) -> [return: bb17, unwind terminate(cleanup)]; + } + + bb17 (cleanup): { resume; } + + bb18: { + StorageDead(_20); + StorageDead(_36); + StorageDead(_16); + StorageDead(_21); + StorageDead(_22); + StorageDead(_37); + StorageDead(_13); + drop(_2) -> [return: bb19, unwind continue]; + } + + bb19: { + return; + } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.rs b/tests/mir-opt/pre-codegen/slice_iter.rs index 3983f8a806b6b..3f89ab0e6f330 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.rs +++ b/tests/mir-opt/pre-codegen/slice_iter.rs @@ -1,5 +1,6 @@ // skip-filecheck //@ compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 +//@ only-64bit (constants for `None::<&T>` show in the output) // EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![crate_type = "lib"] diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir index 78f96bf419559..2df346c081c8e 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir @@ -3,12 +3,205 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut T> { debug it => _1; let mut _0: std::option::Option<&mut T>; + scope 1 (inlined as DoubleEndedIterator>::next_back) { + let mut _2: *const *mut T; + let mut _3: *const std::ptr::NonNull; + let mut _8: bool; + let mut _9: *mut T; + let mut _25: &mut T; + scope 2 { + let _4: std::ptr::NonNull; + let _10: usize; + scope 3 { + } + scope 4 { + scope 8 (inlined as PartialEq>::eq) { + let mut _5: std::ptr::NonNull; + scope 9 (inlined NonNull::::as_ptr) { + let mut _6: *const T; + } + scope 10 (inlined NonNull::::as_ptr) { + let mut _7: *const T; + } + } + } + scope 5 (inlined std::ptr::mut_ptr::::addr) { + scope 6 (inlined std::ptr::mut_ptr::::cast::<()>) { + } + } + scope 7 (inlined std::ptr::const_ptr::::cast::>) { + } + } + scope 11 (inlined std::slice::IterMut::<'_, T>::next_back_unchecked) { + let mut _17: std::ptr::NonNull; + scope 12 (inlined std::slice::IterMut::<'_, T>::pre_dec_end) { + let mut _11: *mut *mut T; + let mut _12: *mut std::ptr::NonNull; + let mut _13: std::ptr::NonNull; + let mut _16: std::ptr::NonNull; + let mut _18: *mut *mut T; + let mut _19: *mut usize; + let mut _20: usize; + let mut _21: usize; + scope 13 { + scope 14 { + } + scope 15 { + scope 18 (inlined NonNull::::sub) { + scope 19 (inlined core::num::::unchecked_neg) { + scope 20 (inlined core::ub_checks::check_language_ub) { + scope 21 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 22 (inlined NonNull::::offset) { + let mut _14: *const T; + let mut _15: *const T; + } + } + } + scope 16 (inlined std::ptr::mut_ptr::::cast::) { + } + scope 17 (inlined std::ptr::mut_ptr::::cast::>) { + } + } + } + scope 23 (inlined NonNull::::as_mut::<'_>) { + let mut _22: std::ptr::NonNull; + let mut _24: *mut T; + scope 24 (inlined NonNull::::as_ptr) { + let mut _23: *const T; + } + } + } + } bb0: { - _0 = as DoubleEndedIterator>::next_back(move _1) -> [return: bb1, unwind unreachable]; + StorageLive(_10); + StorageLive(_9); + StorageLive(_4); + StorageLive(_25); + StorageLive(_8); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { + StorageLive(_3); + StorageLive(_2); + _2 = &raw const ((*_1).1: *mut T); + _3 = _2 as *const std::ptr::NonNull (PtrToPtr); + StorageDead(_2); + _4 = (*_3); + StorageDead(_3); + StorageLive(_6); + StorageLive(_7); + StorageLive(_5); + _5 = ((*_1).0: std::ptr::NonNull); + _6 = (_5.0: *const T); + StorageDead(_5); + _7 = (_4.0: *const T); + _8 = Eq(_6, _7); + StorageDead(_7); + StorageDead(_6); + goto -> bb3; + } + + bb2: { + _9 = ((*_1).1: *mut T); + _10 = _9 as usize (Transmute); + _8 = Eq(_10, const 0_usize); + goto -> bb3; + } + + bb3: { + switchInt(move _8) -> [0: bb4, otherwise: bb11]; + } + + bb4: { + StorageLive(_24); + StorageLive(_17); + StorageLive(_19); + StorageLive(_12); + switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb9]; + } + + bb5: { + StorageLive(_11); + _11 = &raw mut ((*_1).1: *mut T); + _12 = _11 as *mut std::ptr::NonNull (PtrToPtr); + StorageDead(_11); + StorageLive(_16); + _13 = (*_12); + switchInt(const ::IS_ZST) -> [0: bb6, otherwise: bb7]; + } + + bb6: { + StorageLive(_15); + StorageLive(_14); + _14 = (_13.0: *const T); + _15 = Offset(move _14, const -1_isize); + StorageDead(_14); + _16 = NonNull:: { pointer: move _15 }; + StorageDead(_15); + goto -> bb8; + } + + bb7: { + _16 = _13; + goto -> bb8; + } + + bb8: { + (*_12) = move _16; + StorageDead(_16); + _17 = (*_12); + goto -> bb10; + } + + bb9: { + StorageLive(_18); + _18 = &raw mut ((*_1).1: *mut T); + _19 = _18 as *mut usize (PtrToPtr); + StorageDead(_18); + StorageLive(_21); + StorageLive(_20); + _20 = (*_19); + _21 = SubUnchecked(move _20, const 1_usize); + StorageDead(_20); + (*_19) = move _21; + StorageDead(_21); + _17 = ((*_1).0: std::ptr::NonNull); + goto -> bb10; + } + + bb10: { + StorageDead(_12); + StorageDead(_19); + StorageLive(_22); + _22 = _17; + StorageLive(_23); + _23 = (_22.0: *const T); + _24 = move _23 as *mut T (PtrToPtr); + StorageDead(_23); + StorageDead(_22); + _25 = &mut (*_24); + StorageDead(_17); + StorageDead(_24); + _0 = Option::<&mut T>::Some(_25); + goto -> bb12; + } + + bb11: { + _0 = const {transmute(0x0000000000000000): Option<&mut T>}; + goto -> bb12; + } + + bb12: { + StorageDead(_8); + StorageDead(_25); + StorageDead(_4); + StorageDead(_9); + StorageDead(_10); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir index dfe5e206fadaf..2df346c081c8e 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir @@ -3,12 +3,205 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut T> { debug it => _1; let mut _0: std::option::Option<&mut T>; + scope 1 (inlined as DoubleEndedIterator>::next_back) { + let mut _2: *const *mut T; + let mut _3: *const std::ptr::NonNull; + let mut _8: bool; + let mut _9: *mut T; + let mut _25: &mut T; + scope 2 { + let _4: std::ptr::NonNull; + let _10: usize; + scope 3 { + } + scope 4 { + scope 8 (inlined as PartialEq>::eq) { + let mut _5: std::ptr::NonNull; + scope 9 (inlined NonNull::::as_ptr) { + let mut _6: *const T; + } + scope 10 (inlined NonNull::::as_ptr) { + let mut _7: *const T; + } + } + } + scope 5 (inlined std::ptr::mut_ptr::::addr) { + scope 6 (inlined std::ptr::mut_ptr::::cast::<()>) { + } + } + scope 7 (inlined std::ptr::const_ptr::::cast::>) { + } + } + scope 11 (inlined std::slice::IterMut::<'_, T>::next_back_unchecked) { + let mut _17: std::ptr::NonNull; + scope 12 (inlined std::slice::IterMut::<'_, T>::pre_dec_end) { + let mut _11: *mut *mut T; + let mut _12: *mut std::ptr::NonNull; + let mut _13: std::ptr::NonNull; + let mut _16: std::ptr::NonNull; + let mut _18: *mut *mut T; + let mut _19: *mut usize; + let mut _20: usize; + let mut _21: usize; + scope 13 { + scope 14 { + } + scope 15 { + scope 18 (inlined NonNull::::sub) { + scope 19 (inlined core::num::::unchecked_neg) { + scope 20 (inlined core::ub_checks::check_language_ub) { + scope 21 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 22 (inlined NonNull::::offset) { + let mut _14: *const T; + let mut _15: *const T; + } + } + } + scope 16 (inlined std::ptr::mut_ptr::::cast::) { + } + scope 17 (inlined std::ptr::mut_ptr::::cast::>) { + } + } + } + scope 23 (inlined NonNull::::as_mut::<'_>) { + let mut _22: std::ptr::NonNull; + let mut _24: *mut T; + scope 24 (inlined NonNull::::as_ptr) { + let mut _23: *const T; + } + } + } + } bb0: { - _0 = as DoubleEndedIterator>::next_back(move _1) -> [return: bb1, unwind continue]; + StorageLive(_10); + StorageLive(_9); + StorageLive(_4); + StorageLive(_25); + StorageLive(_8); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { + StorageLive(_3); + StorageLive(_2); + _2 = &raw const ((*_1).1: *mut T); + _3 = _2 as *const std::ptr::NonNull (PtrToPtr); + StorageDead(_2); + _4 = (*_3); + StorageDead(_3); + StorageLive(_6); + StorageLive(_7); + StorageLive(_5); + _5 = ((*_1).0: std::ptr::NonNull); + _6 = (_5.0: *const T); + StorageDead(_5); + _7 = (_4.0: *const T); + _8 = Eq(_6, _7); + StorageDead(_7); + StorageDead(_6); + goto -> bb3; + } + + bb2: { + _9 = ((*_1).1: *mut T); + _10 = _9 as usize (Transmute); + _8 = Eq(_10, const 0_usize); + goto -> bb3; + } + + bb3: { + switchInt(move _8) -> [0: bb4, otherwise: bb11]; + } + + bb4: { + StorageLive(_24); + StorageLive(_17); + StorageLive(_19); + StorageLive(_12); + switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb9]; + } + + bb5: { + StorageLive(_11); + _11 = &raw mut ((*_1).1: *mut T); + _12 = _11 as *mut std::ptr::NonNull (PtrToPtr); + StorageDead(_11); + StorageLive(_16); + _13 = (*_12); + switchInt(const ::IS_ZST) -> [0: bb6, otherwise: bb7]; + } + + bb6: { + StorageLive(_15); + StorageLive(_14); + _14 = (_13.0: *const T); + _15 = Offset(move _14, const -1_isize); + StorageDead(_14); + _16 = NonNull:: { pointer: move _15 }; + StorageDead(_15); + goto -> bb8; + } + + bb7: { + _16 = _13; + goto -> bb8; + } + + bb8: { + (*_12) = move _16; + StorageDead(_16); + _17 = (*_12); + goto -> bb10; + } + + bb9: { + StorageLive(_18); + _18 = &raw mut ((*_1).1: *mut T); + _19 = _18 as *mut usize (PtrToPtr); + StorageDead(_18); + StorageLive(_21); + StorageLive(_20); + _20 = (*_19); + _21 = SubUnchecked(move _20, const 1_usize); + StorageDead(_20); + (*_19) = move _21; + StorageDead(_21); + _17 = ((*_1).0: std::ptr::NonNull); + goto -> bb10; + } + + bb10: { + StorageDead(_12); + StorageDead(_19); + StorageLive(_22); + _22 = _17; + StorageLive(_23); + _23 = (_22.0: *const T); + _24 = move _23 as *mut T (PtrToPtr); + StorageDead(_23); + StorageDead(_22); + _25 = &mut (*_24); + StorageDead(_17); + StorageDead(_24); + _0 = Option::<&mut T>::Some(_25); + goto -> bb12; + } + + bb11: { + _0 = const {transmute(0x0000000000000000): Option<&mut T>}; + goto -> bb12; + } + + bb12: { + StorageDead(_8); + StorageDead(_25); + StorageDead(_4); + StorageDead(_9); + StorageDead(_10); return; } }