about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBen Kimock <kimockb@gmail.com>2023-02-24 16:33:22 -0500
committerBen Kimock <kimockb@gmail.com>2023-03-18 14:29:13 -0400
commita98ddb6de1723a30777c68983c74bcb45ec52580 (patch)
tree4bd90af22f174b82ccd7257e917fd7de3bb93394
parent2a628bd99c39b69e88b24c622e3d246dd5573353 (diff)
downloadrust-a98ddb6de1723a30777c68983c74bcb45ec52580.tar.gz
rust-a98ddb6de1723a30777c68983c74bcb45ec52580.zip
Enable inlining of diverging functions
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs7
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.rs17
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff115
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir102
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff115
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir102
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.rs10
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff55
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir41
9 files changed, 557 insertions, 7 deletions
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 9cba8870f23..27fad8a655e 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -424,13 +424,6 @@ impl<'tcx> Inliner<'tcx> {
         debug!("    final inline threshold = {}", threshold);
 
         // FIXME: Give a bonus to functions with only a single caller
-        let diverges = matches!(
-            callee_body.basic_blocks[START_BLOCK].terminator().kind,
-            TerminatorKind::Unreachable | TerminatorKind::Call { target: None, .. }
-        );
-        if diverges && !matches!(callee_attrs.inline, InlineAttr::Always) {
-            return Err("callee diverges unconditionally");
-        }
 
         let mut checker = CostChecker {
             tcx: self.tcx,
diff --git a/tests/mir-opt/inline/unchecked_shifts.rs b/tests/mir-opt/inline/unchecked_shifts.rs
new file mode 100644
index 00000000000..e55fa745abc
--- /dev/null
+++ b/tests/mir-opt/inline/unchecked_shifts.rs
@@ -0,0 +1,17 @@
+#![crate_type = "lib"]
+#![feature(unchecked_math)]
+
+// ignore-debug: the debug assertions prevent the inlining we are testing for
+// compile-flags: -Zmir-opt-level=2 -Zinline-mir
+
+// EMIT_MIR unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff
+// EMIT_MIR unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir
+pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 {
+    a.unchecked_shl(b)
+}
+
+// EMIT_MIR unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff
+// EMIT_MIR unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir
+pub unsafe fn unchecked_shr_signed_smaller(a: i16, b: u32) -> i16 {
+    a.unchecked_shr(b)
+}
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff
new file mode 100644
index 00000000000..5fd918b3aa5
--- /dev/null
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff
@@ -0,0 +1,115 @@
+- // MIR for `unchecked_shl_unsigned_smaller` before Inline
++ // MIR for `unchecked_shl_unsigned_smaller` after Inline
+  
+  fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 {
+      debug a => _1;                       // in scope 0 at $DIR/unchecked_shifts.rs:+0:46: +0:47
+      debug b => _2;                       // in scope 0 at $DIR/unchecked_shifts.rs:+0:54: +0:55
+      let mut _0: u16;                     // return place in scope 0 at $DIR/unchecked_shifts.rs:+0:65: +0:68
+      let mut _3: u16;                     // in scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6
+      let mut _4: u32;                     // in scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22
++     scope 1 (inlined core::num::<impl u16>::unchecked_shl) { // at $DIR/unchecked_shifts.rs:10:7: 10:23
++         debug self => _3;                // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++         debug rhs => _4;                 // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++         let mut _5: u16;                 // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++         let mut _6: std::option::Option<u16>; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++         let mut _7: std::result::Result<u16, std::num::TryFromIntError>; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++         scope 2 {
++             scope 3 (inlined Result::<u16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++                 debug self => _7;        // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++                 let mut _8: isize;       // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++                 let _9: u16;             // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++                 scope 4 {
++                     debug x => _9;       // in scope 4 at $SRC_DIR/core/src/result.rs:LL:COL
++                 }
++                 scope 5 {
++                     scope 6 {
++                         debug x => const TryFromIntError(()); // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
++                     }
++                 }
++             }
++             scope 7 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++                 debug self => _6;        // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
++                 let mut _10: &std::option::Option<u16>; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
++                 let mut _11: isize;      // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
++                 scope 8 {
++                     debug val => _5;     // in scope 8 at $SRC_DIR/core/src/option.rs:LL:COL
++                 }
++                 scope 9 {
++                     scope 11 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL
++                         scope 12 {
++                             scope 13 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
++                             }
++                         }
++                     }
++                 }
++                 scope 10 (inlined Option::<u16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL
++                     debug self => _10;   // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL
++                 }
++             }
++         }
++     }
+  
+      bb0: {
+          StorageLive(_3);                 // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6
+          _3 = _1;                         // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6
+          StorageLive(_4);                 // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22
+          _4 = _2;                         // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22
+-         _0 = core::num::<impl u16>::unchecked_shl(move _3, move _4) -> bb1; // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:23
++         StorageLive(_5);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++         StorageLive(_6);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++         StorageLive(_7);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++         _7 = <u32 as TryInto<u16>>::try_into(_4) -> bb1; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+                                           // mir::Constant
+-                                          // + span: $DIR/unchecked_shifts.rs:10:7: 10:20
+-                                          // + literal: Const { ty: unsafe fn(u16, u32) -> u16 {core::num::<impl u16>::unchecked_shl}, val: Value(<ZST>) }
++                                          // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++                                          // + literal: Const { ty: fn(u32) -> Result<u16, <u32 as TryInto<u16>>::Error> {<u32 as TryInto<u16>>::try_into}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
++         StorageLive(_9);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++         _8 = discriminant(_7);           // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++         switchInt(move _8) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++     }
++ 
++     bb2: {
++         StorageDead(_9);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++         StorageDead(_7);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++         StorageLive(_10);                // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++         _11 = discriminant(_6);          // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
++         switchInt(move _11) -> [1: bb7, otherwise: bb5]; // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
++     }
++ 
++     bb3: {
++         StorageDead(_5);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+          StorageDead(_4);                 // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23
+          StorageDead(_3);                 // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23
+          return;                          // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2
++     }
++ 
++     bb4: {
++         _6 = Option::<u16>::None;        // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
++         goto -> bb2;                     // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
++     }
++ 
++     bb5: {
++         unreachable;                     // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++     }
++ 
++     bb6: {
++         _9 = move ((_7 as Ok).0: u16);   // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++         _6 = Option::<u16>::Some(move _9); // scope 4 at $SRC_DIR/core/src/result.rs:LL:COL
++         goto -> bb2;                     // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++     }
++ 
++     bb7: {
++         _5 = move ((_6 as Some).0: u16); // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
++         StorageDead(_10);                // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++         StorageDead(_6);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++         _0 = unchecked_shl::<u16>(_3, move _5) -> bb3; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++                                          // mir::Constant
++                                          // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
++                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::<u16>}, val: Value(<ZST>) }
+      }
+  }
+  
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir
new file mode 100644
index 00000000000..c5501cef743
--- /dev/null
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir
@@ -0,0 +1,102 @@
+// MIR for `unchecked_shl_unsigned_smaller` after PreCodegen
+
+fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 {
+    debug a => _1;                       // in scope 0 at $DIR/unchecked_shifts.rs:+0:46: +0:47
+    debug b => _2;                       // in scope 0 at $DIR/unchecked_shifts.rs:+0:54: +0:55
+    let mut _0: u16;                     // return place in scope 0 at $DIR/unchecked_shifts.rs:+0:65: +0:68
+    scope 1 (inlined core::num::<impl u16>::unchecked_shl) { // at $DIR/unchecked_shifts.rs:10:7: 10:23
+        debug self => _1;                // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        debug rhs => _2;                 // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        let mut _3: u16;                 // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        let mut _4: std::option::Option<u16>; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        let mut _5: std::result::Result<u16, std::num::TryFromIntError>; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        scope 2 {
+            scope 3 (inlined Result::<u16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+                debug self => _5;        // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+                let mut _6: isize;       // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+                let _7: u16;             // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+                scope 4 {
+                    debug x => _7;       // in scope 4 at $SRC_DIR/core/src/result.rs:LL:COL
+                }
+                scope 5 {
+                    scope 6 {
+                        debug x => const TryFromIntError(()); // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+                    }
+                }
+            }
+            scope 7 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+                debug self => _4;        // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
+                let mut _8: &std::option::Option<u16>; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
+                let mut _9: isize;       // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
+                scope 8 {
+                    debug val => _3;     // in scope 8 at $SRC_DIR/core/src/option.rs:LL:COL
+                }
+                scope 9 {
+                    scope 11 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL
+                        scope 12 {
+                            scope 13 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+                            }
+                        }
+                    }
+                }
+                scope 10 (inlined Option::<u16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL
+                    debug self => _8;    // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL
+                }
+            }
+        }
+    }
+
+    bb0: {
+        StorageLive(_3);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        StorageLive(_4);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        StorageLive(_5);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        _5 = <u32 as TryInto<u16>>::try_into(_2) -> bb1; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+                                         // mir::Constant
+                                         // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+                                         // + literal: Const { ty: fn(u32) -> Result<u16, <u32 as TryInto<u16>>::Error> {<u32 as TryInto<u16>>::try_into}, val: Value(<ZST>) }
+    }
+
+    bb1: {
+        StorageLive(_7);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        _6 = discriminant(_5);           // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+        switchInt(move _6) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+    }
+
+    bb2: {
+        StorageDead(_7);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        StorageDead(_5);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        StorageLive(_8);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        _9 = discriminant(_4);           // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
+        switchInt(move _9) -> [1: bb7, otherwise: bb5]; // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
+    }
+
+    bb3: {
+        StorageDead(_3);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        return;                          // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2
+    }
+
+    bb4: {
+        _4 = Option::<u16>::None;        // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+        goto -> bb2;                     // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+    }
+
+    bb5: {
+        unreachable;                     // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+    }
+
+    bb6: {
+        _7 = move ((_5 as Ok).0: u16);   // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+        _4 = Option::<u16>::Some(move _7); // scope 4 at $SRC_DIR/core/src/result.rs:LL:COL
+        goto -> bb2;                     // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+    }
+
+    bb7: {
+        _3 = move ((_4 as Some).0: u16); // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
+        StorageDead(_8);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        StorageDead(_4);                 // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        _0 = unchecked_shl::<u16>(_1, move _3) -> bb3; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+                                         // mir::Constant
+                                         // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+                                         // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::<u16>}, val: Value(<ZST>) }
+    }
+}
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff
new file mode 100644
index 00000000000..68d3b21fc2a
--- /dev/null
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff
@@ -0,0 +1,115 @@
+- // MIR for `unchecked_shr_signed_smaller` before Inline
++ // MIR for `unchecked_shr_signed_smaller` after Inline
+  
+  fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 {
+      debug a => _1;                       // in scope 0 at $DIR/unchecked_shifts.rs:+0:44: +0:45
+      debug b => _2;                       // in scope 0 at $DIR/unchecked_shifts.rs:+0:52: +0:53
+      let mut _0: i16;                     // return place in scope 0 at $DIR/unchecked_shifts.rs:+0:63: +0:66
+      let mut _3: i16;                     // in scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6
+      let mut _4: u32;                     // in scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22
++     scope 1 (inlined core::num::<impl i16>::unchecked_shr) { // at $DIR/unchecked_shifts.rs:16:7: 16:23
++         debug self => _3;                // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++         debug rhs => _4;                 // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++         let mut _5: i16;                 // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++         let mut _6: std::option::Option<i16>; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++         let mut _7: std::result::Result<i16, std::num::TryFromIntError>; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++         scope 2 {
++             scope 3 (inlined Result::<i16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++                 debug self => _7;        // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++                 let mut _8: isize;       // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++                 let _9: i16;             // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++                 scope 4 {
++                     debug x => _9;       // in scope 4 at $SRC_DIR/core/src/result.rs:LL:COL
++                 }
++                 scope 5 {
++                     scope 6 {
++                         debug x => const TryFromIntError(()); // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
++                     }
++                 }
++             }
++             scope 7 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++                 debug self => _6;        // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
++                 let mut _10: &std::option::Option<i16>; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
++                 let mut _11: isize;      // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
++                 scope 8 {
++                     debug val => _5;     // in scope 8 at $SRC_DIR/core/src/option.rs:LL:COL
++                 }
++                 scope 9 {
++                     scope 11 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL
++                         scope 12 {
++                             scope 13 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
++                             }
++                         }
++                     }
++                 }
++                 scope 10 (inlined Option::<i16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL
++                     debug self => _10;   // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL
++                 }
++             }
++         }
++     }
+  
+      bb0: {
+          StorageLive(_3);                 // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6
+          _3 = _1;                         // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6
+          StorageLive(_4);                 // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22
+          _4 = _2;                         // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22
+-         _0 = core::num::<impl i16>::unchecked_shr(move _3, move _4) -> bb1; // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:23
++         StorageLive(_5);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++         StorageLive(_6);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++         StorageLive(_7);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++         _7 = <u32 as TryInto<i16>>::try_into(_4) -> bb1; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+                                           // mir::Constant
+-                                          // + span: $DIR/unchecked_shifts.rs:16:7: 16:20
+-                                          // + literal: Const { ty: unsafe fn(i16, u32) -> i16 {core::num::<impl i16>::unchecked_shr}, val: Value(<ZST>) }
++                                          // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++                                          // + literal: Const { ty: fn(u32) -> Result<i16, <u32 as TryInto<i16>>::Error> {<u32 as TryInto<i16>>::try_into}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
++         StorageLive(_9);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++         _8 = discriminant(_7);           // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++         switchInt(move _8) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++     }
++ 
++     bb2: {
++         StorageDead(_9);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++         StorageDead(_7);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++         StorageLive(_10);                // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++         _11 = discriminant(_6);          // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
++         switchInt(move _11) -> [1: bb7, otherwise: bb5]; // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
++     }
++ 
++     bb3: {
++         StorageDead(_5);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+          StorageDead(_4);                 // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23
+          StorageDead(_3);                 // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23
+          return;                          // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2
++     }
++ 
++     bb4: {
++         _6 = Option::<i16>::None;        // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
++         goto -> bb2;                     // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
++     }
++ 
++     bb5: {
++         unreachable;                     // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++     }
++ 
++     bb6: {
++         _9 = move ((_7 as Ok).0: i16);   // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++         _6 = Option::<i16>::Some(move _9); // scope 4 at $SRC_DIR/core/src/result.rs:LL:COL
++         goto -> bb2;                     // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
++     }
++ 
++     bb7: {
++         _5 = move ((_6 as Some).0: i16); // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
++         StorageDead(_10);                // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++         StorageDead(_6);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++         _0 = unchecked_shr::<i16>(_3, move _5) -> bb3; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++                                          // mir::Constant
++                                          // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL
++                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::<i16>}, val: Value(<ZST>) }
+      }
+  }
+  
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir
new file mode 100644
index 00000000000..ed3a89ceace
--- /dev/null
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir
@@ -0,0 +1,102 @@
+// MIR for `unchecked_shr_signed_smaller` after PreCodegen
+
+fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 {
+    debug a => _1;                       // in scope 0 at $DIR/unchecked_shifts.rs:+0:44: +0:45
+    debug b => _2;                       // in scope 0 at $DIR/unchecked_shifts.rs:+0:52: +0:53
+    let mut _0: i16;                     // return place in scope 0 at $DIR/unchecked_shifts.rs:+0:63: +0:66
+    scope 1 (inlined core::num::<impl i16>::unchecked_shr) { // at $DIR/unchecked_shifts.rs:16:7: 16:23
+        debug self => _1;                // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        debug rhs => _2;                 // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        let mut _3: i16;                 // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        let mut _4: std::option::Option<i16>; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        let mut _5: std::result::Result<i16, std::num::TryFromIntError>; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        scope 2 {
+            scope 3 (inlined Result::<i16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+                debug self => _5;        // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+                let mut _6: isize;       // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+                let _7: i16;             // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+                scope 4 {
+                    debug x => _7;       // in scope 4 at $SRC_DIR/core/src/result.rs:LL:COL
+                }
+                scope 5 {
+                    scope 6 {
+                        debug x => const TryFromIntError(()); // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+                    }
+                }
+            }
+            scope 7 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+                debug self => _4;        // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
+                let mut _8: &std::option::Option<i16>; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
+                let mut _9: isize;       // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
+                scope 8 {
+                    debug val => _3;     // in scope 8 at $SRC_DIR/core/src/option.rs:LL:COL
+                }
+                scope 9 {
+                    scope 11 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL
+                        scope 12 {
+                            scope 13 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+                            }
+                        }
+                    }
+                }
+                scope 10 (inlined Option::<i16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL
+                    debug self => _8;    // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL
+                }
+            }
+        }
+    }
+
+    bb0: {
+        StorageLive(_3);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        StorageLive(_4);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        StorageLive(_5);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        _5 = <u32 as TryInto<i16>>::try_into(_2) -> bb1; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+                                         // mir::Constant
+                                         // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+                                         // + literal: Const { ty: fn(u32) -> Result<i16, <u32 as TryInto<i16>>::Error> {<u32 as TryInto<i16>>::try_into}, val: Value(<ZST>) }
+    }
+
+    bb1: {
+        StorageLive(_7);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        _6 = discriminant(_5);           // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+        switchInt(move _6) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+    }
+
+    bb2: {
+        StorageDead(_7);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        StorageDead(_5);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        StorageLive(_8);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        _9 = discriminant(_4);           // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
+        switchInt(move _9) -> [1: bb7, otherwise: bb5]; // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
+    }
+
+    bb3: {
+        StorageDead(_3);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        return;                          // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2
+    }
+
+    bb4: {
+        _4 = Option::<i16>::None;        // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+        goto -> bb2;                     // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+    }
+
+    bb5: {
+        unreachable;                     // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+    }
+
+    bb6: {
+        _7 = move ((_5 as Ok).0: i16);   // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+        _4 = Option::<i16>::Some(move _7); // scope 4 at $SRC_DIR/core/src/result.rs:LL:COL
+        goto -> bb2;                     // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL
+    }
+
+    bb7: {
+        _3 = move ((_4 as Some).0: i16); // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL
+        StorageDead(_8);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        StorageDead(_4);                 // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        _0 = unchecked_shr::<i16>(_1, move _3) -> bb3; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+                                         // mir::Constant
+                                         // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+                                         // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::<i16>}, val: Value(<ZST>) }
+    }
+}
diff --git a/tests/mir-opt/inline/unwrap_unchecked.rs b/tests/mir-opt/inline/unwrap_unchecked.rs
new file mode 100644
index 00000000000..c3581093f66
--- /dev/null
+++ b/tests/mir-opt/inline/unwrap_unchecked.rs
@@ -0,0 +1,10 @@
+#![crate_type = "lib"]
+
+// ignore-debug: the debug assertions prevent the inlining we are testing for
+// compile-flags: -Zmir-opt-level=2 -Zinline-mir
+
+// EMIT_MIR unwrap_unchecked.unwrap_unchecked.Inline.diff
+// EMIT_MIR unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir
+pub unsafe fn unwrap_unchecked<T>(slf: Option<T>) -> T {
+    slf.unwrap_unchecked()
+}
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff
new file mode 100644
index 00000000000..7f73306a825
--- /dev/null
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff
@@ -0,0 +1,55 @@
+- // MIR for `unwrap_unchecked` before Inline
++ // MIR for `unwrap_unchecked` after Inline
+  
+  fn unwrap_unchecked(_1: Option<T>) -> T {
+      debug slf => _1;                     // in scope 0 at $DIR/unwrap_unchecked.rs:+0:35: +0:38
+      let mut _0: T;                       // return place in scope 0 at $DIR/unwrap_unchecked.rs:+0:54: +0:55
+      let mut _2: std::option::Option<T>;  // in scope 0 at $DIR/unwrap_unchecked.rs:+1:5: +1:8
++     scope 1 (inlined #[track_caller] Option::<T>::unwrap_unchecked) { // at $DIR/unwrap_unchecked.rs:9:9: 9:27
++         debug self => _2;                // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL
++         let mut _3: &std::option::Option<T>; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL
++         let mut _4: isize;               // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL
++         scope 2 {
++             debug val => _0;             // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL
++         }
++         scope 3 {
++             scope 5 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL
++                 scope 6 {
++                     scope 7 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
++                     }
++                 }
++             }
++         }
++         scope 4 (inlined Option::<T>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL
++             debug self => _3;            // in scope 4 at $SRC_DIR/core/src/option.rs:LL:COL
++         }
++     }
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/unwrap_unchecked.rs:+1:5: +1:8
+          _2 = move _1;                    // scope 0 at $DIR/unwrap_unchecked.rs:+1:5: +1:8
+-         _0 = Option::<T>::unwrap_unchecked(move _2) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/unwrap_unchecked.rs:+1:5: +1:27
+-                                          // mir::Constant
+-                                          // + span: $DIR/unwrap_unchecked.rs:9:9: 9:25
+-                                          // + literal: Const { ty: unsafe fn(Option<T>) -> T {Option::<T>::unwrap_unchecked}, val: Value(<ZST>) }
++         StorageLive(_3);                 // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27
++         _4 = discriminant(_2);           // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL
++         switchInt(move _4) -> [0: bb1, 1: bb2, otherwise: bb1]; // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL
+      }
+  
+      bb1: {
+-         StorageDead(_2);                 // scope 0 at $DIR/unwrap_unchecked.rs:+1:26: +1:27
+-         return;                          // scope 0 at $DIR/unwrap_unchecked.rs:+2:2: +2:2
++         unreachable;                     // scope 6 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+      }
+  
+-     bb2 (cleanup): {
+-         resume;                          // scope 0 at $DIR/unwrap_unchecked.rs:+0:1: +2:2
++     bb2: {
++         _0 = move ((_2 as Some).0: T);   // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL
++         StorageDead(_3);                 // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27
++         StorageDead(_2);                 // scope 0 at $DIR/unwrap_unchecked.rs:+1:26: +1:27
++         return;                          // scope 0 at $DIR/unwrap_unchecked.rs:+2:2: +2:2
+      }
+  }
+  
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir
new file mode 100644
index 00000000000..33cd3785336
--- /dev/null
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir
@@ -0,0 +1,41 @@
+// MIR for `unwrap_unchecked` after PreCodegen
+
+fn unwrap_unchecked(_1: Option<T>) -> T {
+    debug slf => _1;                     // in scope 0 at $DIR/unwrap_unchecked.rs:+0:35: +0:38
+    let mut _0: T;                       // return place in scope 0 at $DIR/unwrap_unchecked.rs:+0:54: +0:55
+    scope 1 (inlined #[track_caller] Option::<T>::unwrap_unchecked) { // at $DIR/unwrap_unchecked.rs:9:9: 9:27
+        debug self => _1;                // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL
+        let mut _2: &std::option::Option<T>; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL
+        let mut _3: isize;               // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL
+        scope 2 {
+            debug val => _0;             // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL
+        }
+        scope 3 {
+            scope 5 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL
+                scope 6 {
+                    scope 7 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+                    }
+                }
+            }
+        }
+        scope 4 (inlined Option::<T>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL
+            debug self => _2;            // in scope 4 at $SRC_DIR/core/src/option.rs:LL:COL
+        }
+    }
+
+    bb0: {
+        StorageLive(_2);                 // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27
+        _3 = discriminant(_1);           // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL
+        switchInt(move _3) -> [1: bb2, otherwise: bb1]; // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL
+    }
+
+    bb1: {
+        unreachable;                     // scope 6 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+    }
+
+    bb2: {
+        _0 = move ((_1 as Some).0: T);   // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL
+        StorageDead(_2);                 // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27
+        return;                          // scope 0 at $DIR/unwrap_unchecked.rs:+2:2: +2:2
+    }
+}