about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs4
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs5
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs24
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs8
-rw-r--r--compiler/rustc_middle/src/query/mod.rs5
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs9
-rw-r--r--compiler/rustc_mir_transform/src/cross_crate_inline.rs119
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs14
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs2
-rw-r--r--compiler/rustc_passes/src/reachable.rs58
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--library/alloc/src/raw_vec.rs1
-rw-r--r--library/std/src/rt.rs1
-rw-r--r--tests/assembly/asm/arm-types.rs1
-rw-r--r--tests/assembly/closure-inherit-target-feature.rs1
-rw-r--r--tests/assembly/dwarf5.rs2
-rw-r--r--tests/codegen-units/item-collection/asm-sym.rs3
-rw-r--r--tests/codegen-units/item-collection/auxiliary/cgu_export_trait_method.rs2
-rw-r--r--tests/codegen-units/item-collection/cross-crate-trait-method.rs2
-rw-r--r--tests/codegen-units/item-collection/items-within-generic-items.rs2
-rw-r--r--tests/codegen-units/item-collection/unreferenced-const-fn.rs1
-rw-r--r--tests/codegen/asm-sanitize-llvm.rs2
-rw-r--r--tests/codegen/async-fn-debug-awaitee-field.rs2
-rw-r--r--tests/codegen/debug-linkage-name.rs4
-rw-r--r--tests/codegen/default-requires-uwtable.rs2
-rw-r--r--tests/codegen/drop.rs2
-rw-r--r--tests/codegen/force-frame-pointers.rs2
-rw-r--r--tests/codegen/force-unwind-tables.rs2
-rw-r--r--tests/codegen/inline-function-args-debug-info.rs5
-rw-r--r--tests/codegen/instrument-mcount.rs2
-rw-r--r--tests/codegen/instrument-xray/basic.rs2
-rw-r--r--tests/codegen/instrument-xray/options-combine.rs6
-rw-r--r--tests/codegen/instrument-xray/options-override.rs4
-rw-r--r--tests/codegen/panic-unwind-default-uwtable.rs2
-rw-r--r--tests/codegen/personality_lifetimes.rs2
-rw-r--r--tests/codegen/sanitizer/cfi-emit-type-metadata-attr-cfi-encoding.rs2
-rw-r--r--tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs2
-rw-r--r--tests/codegen/sanitizer/cfi-generalize-pointers.rs2
-rw-r--r--tests/codegen/sanitizer/cfi-normalize-integers.rs2
-rw-r--r--tests/codegen/sanitizer/kasan-emits-instrumentation.rs2
-rw-r--r--tests/codegen/sanitizer/memtag-attr-check.rs2
-rw-r--r--tests/codegen/sanitizer/no-sanitize.rs2
-rw-r--r--tests/codegen/sanitizer/safestack-attr-check.rs2
-rw-r--r--tests/codegen/src-hash-algorithm/src-hash-algorithm-md5.rs2
-rw-r--r--tests/codegen/src-hash-algorithm/src-hash-algorithm-sha1.rs2
-rw-r--r--tests/codegen/src-hash-algorithm/src-hash-algorithm-sha256.rs2
-rw-r--r--tests/codegen/target-cpu-on-functions.rs3
-rw-r--r--tests/codegen/tied-features-strength.rs8
-rw-r--r--tests/codegen/tune-cpu-on-functions.rs2
-rw-r--r--tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff19
-rw-r--r--tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff19
-rw-r--r--tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-abort.diff124
-rw-r--r--tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-unwind.diff124
-rw-r--r--tests/mir-opt/inline/issue_106141.rs1
-rw-r--r--tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff22
-rw-r--r--tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff31
-rw-r--r--tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir11
-rw-r--r--tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir11
-rw-r--r--tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-abort.mir34
-rw-r--r--tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-unwind.mir34
-rw-r--r--tests/run-make/emit-stack-sizes/foo.rs1
-rw-r--r--tests/run-make/intrinsic-unreachable/exit-ret.rs1
-rw-r--r--tests/run-make/intrinsic-unreachable/exit-unreachable.rs1
-rw-r--r--tests/ui/hygiene/panic-location.run.stderr2
67 files changed, 434 insertions, 344 deletions
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 7799af37008..ec4fd78994e 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -770,6 +770,7 @@ fn test_unstable_options_tracking_hash() {
     );
     tracked!(codegen_backend, Some("abc".to_string()));
     tracked!(crate_attr, vec!["abc".to_string()]);
+    tracked!(cross_crate_inline_threshold, Some(200));
     tracked!(debug_info_for_profiling, true);
     tracked!(debug_macros, true);
     tracked!(dep_info_omit_d_target, true);
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 846f8d25025..d6ceaa8a091 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1273,6 +1273,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         self.root.tables.optimized_mir.get(self, id).is_some()
     }
 
+    fn cross_crate_inlinable(self, id: DefIndex) -> bool {
+        self.root.tables.cross_crate_inlinable.get(self, id).unwrap_or(false)
+    }
+
     fn get_fn_has_self_parameter(self, id: DefIndex, sess: &'a Session) -> bool {
         self.root
             .tables
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index f27eee0d79a..6b6c0d52742 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -287,6 +287,7 @@ provide! { tcx, def_id, other, cdata,
     item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) }
     is_mir_available => { cdata.is_item_mir_available(def_id.index) }
     is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) }
+    cross_crate_inlinable => { cdata.cross_crate_inlinable(def_id.index) }
 
     dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) }
     is_private_dep => {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index dee2326ae32..7c406f9bdda 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1046,7 +1046,7 @@ fn should_encode_mir(
                 || (tcx.sess.opts.output_types.should_codegen()
                     && reachable_set.contains(&def_id)
                     && (generics.requires_monomorphization(tcx)
-                        || tcx.codegen_fn_attrs(def_id).requests_inline()));
+                        || tcx.cross_crate_inlinable(def_id)));
             // The function has a `const` modifier or is in a `#[const_trait]`.
             let is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id())
                 || tcx.is_const_default_method(def_id.to_def_id());
@@ -1615,6 +1615,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             debug!("EntryBuilder::encode_mir({:?})", def_id);
             if encode_opt {
                 record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id));
+                self.tables
+                    .cross_crate_inlinable
+                    .set(def_id.to_def_id().index, Some(self.tcx.cross_crate_inlinable(def_id)));
                 record!(self.tables.closure_saved_names_of_captured_variables[def_id.to_def_id()]
                     <- tcx.closure_saved_names_of_captured_variables(def_id));
 
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 42764af52c4..2609767a85c 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -427,6 +427,7 @@ define_tables! {
     object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
     optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,
     mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
+    cross_crate_inlinable: Table<DefIndex, bool>,
     closure_saved_names_of_captured_variables: Table<DefIndex, LazyValue<IndexVec<FieldIdx, Symbol>>>,
     mir_generator_witnesses: Table<DefIndex, LazyValue<mir::GeneratorLayout<'static>>>,
     promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index bb1320942b0..34118e9e8a3 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -299,6 +299,30 @@ impl FixedSizeEncoding for bool {
     }
 }
 
+impl FixedSizeEncoding for Option<bool> {
+    type ByteArray = [u8; 1];
+
+    #[inline]
+    fn from_bytes(b: &[u8; 1]) -> Self {
+        match b[0] {
+            0 => Some(false),
+            1 => Some(true),
+            2 => None,
+            _ => unreachable!(),
+        }
+    }
+
+    #[inline]
+    fn write_to_bytes(self, b: &mut [u8; 1]) {
+        debug_assert!(!self.is_default());
+        b[0] = match self {
+            Some(false) => 0,
+            Some(true) => 1,
+            None => 2,
+        };
+    }
+}
+
 impl FixedSizeEncoding for UnusedGenericParams {
     type ByteArray = [u8; 4];
 
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index 4e5725876c4..f758c1d5e6f 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -126,14 +126,6 @@ impl CodegenFnAttrs {
         }
     }
 
-    /// Returns `true` if `#[inline]` or `#[inline(always)]` is present.
-    pub fn requests_inline(&self) -> bool {
-        match self.inline {
-            InlineAttr::Hint | InlineAttr::Always => true,
-            InlineAttr::None | InlineAttr::Never => false,
-        }
-    }
-
     /// Returns `true` if it looks like this symbol needs to be exported, for example:
     ///
     /// * `#[no_mangle]` is present
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 340c5a769db..940ab190ffc 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -2202,6 +2202,11 @@ rustc_queries! {
     query generics_require_sized_self(def_id: DefId) -> bool {
         desc { "check whether the item has a `where Self: Sized` bound" }
     }
+
+    query cross_crate_inlinable(def_id: DefId) -> bool {
+        desc { "whether the item should be made inlinable across crates" }
+        separate_provide_extern
+    }
 }
 
 rustc_query_append! { define_callbacks! }
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 0a425be52ff..0b308d5dec1 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -245,16 +245,15 @@ impl<'tcx> InstanceDef<'tcx> {
             // drops of `Option::None` before LTO. We also respect the intent of
             // `#[inline]` on `Drop::drop` implementations.
             return ty.ty_adt_def().map_or(true, |adt_def| {
-                adt_def.destructor(tcx).map_or_else(
-                    || adt_def.is_enum(),
-                    |dtor| tcx.codegen_fn_attrs(dtor.did).requests_inline(),
-                )
+                adt_def
+                    .destructor(tcx)
+                    .map_or_else(|| adt_def.is_enum(), |dtor| tcx.cross_crate_inlinable(dtor.did))
             });
         }
         if let ty::InstanceDef::ThreadLocalShim(..) = *self {
             return false;
         }
-        tcx.codegen_fn_attrs(self.def_id()).requests_inline()
+        tcx.cross_crate_inlinable(self.def_id())
     }
 
     pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool {
diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs
new file mode 100644
index 00000000000..24d081f2ac9
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs
@@ -0,0 +1,119 @@
+use rustc_attr::InlineAttr;
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::LocalDefId;
+use rustc_middle::mir::visit::Visitor;
+use rustc_middle::mir::*;
+use rustc_middle::query::Providers;
+use rustc_middle::ty::TyCtxt;
+use rustc_session::config::OptLevel;
+
+pub fn provide(providers: &mut Providers) {
+    providers.cross_crate_inlinable = cross_crate_inlinable;
+}
+
+fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
+    let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id);
+    // If this has an extern indicator, then this function is globally shared and thus will not
+    // generate cgu-internal copies which would make it cross-crate inlinable.
+    if codegen_fn_attrs.contains_extern_indicator() {
+        return false;
+    }
+
+    // Obey source annotations first; this is important because it means we can use
+    // #[inline(never)] to force code generation.
+    match codegen_fn_attrs.inline {
+        InlineAttr::Never => return false,
+        InlineAttr::Hint | InlineAttr::Always => return true,
+        _ => {}
+    }
+
+    // This just reproduces the logic from Instance::requires_inline.
+    match tcx.def_kind(def_id) {
+        DefKind::Ctor(..) | DefKind::Closure => return true,
+        DefKind::Fn | DefKind::AssocFn => {}
+        _ => return false,
+    }
+
+    // Don't do any inference when incremental compilation is enabled; the additional inlining that
+    // inference permits also creates more work for small edits.
+    if tcx.sess.opts.incremental.is_some() {
+        return false;
+    }
+
+    // Don't do any inference unless optimizations are enabled.
+    if matches!(tcx.sess.opts.optimize, OptLevel::No) {
+        return false;
+    }
+
+    if !tcx.is_mir_available(def_id) {
+        return false;
+    }
+
+    let mir = tcx.optimized_mir(def_id);
+    let mut checker =
+        CostChecker { tcx, callee_body: mir, calls: 0, statements: 0, landing_pads: 0, resumes: 0 };
+    checker.visit_body(mir);
+    checker.calls == 0
+        && checker.resumes == 0
+        && checker.landing_pads == 0
+        && checker.statements
+            <= tcx.sess.opts.unstable_opts.cross_crate_inline_threshold.unwrap_or(100)
+}
+
+struct CostChecker<'b, 'tcx> {
+    tcx: TyCtxt<'tcx>,
+    callee_body: &'b Body<'tcx>,
+    calls: usize,
+    statements: usize,
+    landing_pads: usize,
+    resumes: usize,
+}
+
+impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
+    fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) {
+        // Don't count StorageLive/StorageDead in the inlining cost.
+        match statement.kind {
+            StatementKind::StorageLive(_)
+            | StatementKind::StorageDead(_)
+            | StatementKind::Deinit(_)
+            | StatementKind::Nop => {}
+            _ => self.statements += 1,
+        }
+    }
+
+    fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, _: Location) {
+        let tcx = self.tcx;
+        match terminator.kind {
+            TerminatorKind::Drop { ref place, unwind, .. } => {
+                let ty = place.ty(self.callee_body, tcx).ty;
+                if !ty.is_trivially_pure_clone_copy() {
+                    self.calls += 1;
+                    if let UnwindAction::Cleanup(_) = unwind {
+                        self.landing_pads += 1;
+                    }
+                }
+            }
+            TerminatorKind::Call { unwind, .. } => {
+                self.calls += 1;
+                if let UnwindAction::Cleanup(_) = unwind {
+                    self.landing_pads += 1;
+                }
+            }
+            TerminatorKind::Assert { unwind, .. } => {
+                self.calls += 1;
+                if let UnwindAction::Cleanup(_) = unwind {
+                    self.landing_pads += 1;
+                }
+            }
+            TerminatorKind::UnwindResume => self.resumes += 1,
+            TerminatorKind::InlineAsm { unwind, .. } => {
+                self.statements += 1;
+                if let UnwindAction::Cleanup(_) = unwind {
+                    self.landing_pads += 1;
+                }
+            }
+            TerminatorKind::Return => {}
+            _ => self.statements += 1,
+        }
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 06ae070c908..a70371172f7 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -169,8 +169,11 @@ impl<'tcx> Inliner<'tcx> {
         caller_body: &mut Body<'tcx>,
         callsite: &CallSite<'tcx>,
     ) -> Result<std::ops::Range<BasicBlock>, &'static str> {
+        self.check_mir_is_available(caller_body, &callsite.callee)?;
+
         let callee_attrs = self.tcx.codegen_fn_attrs(callsite.callee.def_id());
-        self.check_codegen_attributes(callsite, callee_attrs)?;
+        let cross_crate_inlinable = self.tcx.cross_crate_inlinable(callsite.callee.def_id());
+        self.check_codegen_attributes(callsite, callee_attrs, cross_crate_inlinable)?;
 
         let terminator = caller_body[callsite.block].terminator.as_ref().unwrap();
         let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() };
@@ -183,9 +186,8 @@ impl<'tcx> Inliner<'tcx> {
             }
         }
 
-        self.check_mir_is_available(caller_body, &callsite.callee)?;
         let callee_body = try_instance_mir(self.tcx, callsite.callee.def)?;
-        self.check_mir_body(callsite, callee_body, callee_attrs)?;
+        self.check_mir_body(callsite, callee_body, callee_attrs, cross_crate_inlinable)?;
 
         if !self.tcx.consider_optimizing(|| {
             format!("Inline {:?} into {:?}", callsite.callee, caller_body.source)
@@ -401,6 +403,7 @@ impl<'tcx> Inliner<'tcx> {
         &self,
         callsite: &CallSite<'tcx>,
         callee_attrs: &CodegenFnAttrs,
+        cross_crate_inlinable: bool,
     ) -> Result<(), &'static str> {
         if let InlineAttr::Never = callee_attrs.inline {
             return Err("never inline hint");
@@ -414,7 +417,7 @@ impl<'tcx> Inliner<'tcx> {
             .non_erasable_generics(self.tcx, callsite.callee.def_id())
             .next()
             .is_some();
-        if !is_generic && !callee_attrs.requests_inline() {
+        if !is_generic && !cross_crate_inlinable {
             return Err("not exported");
         }
 
@@ -456,10 +459,11 @@ impl<'tcx> Inliner<'tcx> {
         callsite: &CallSite<'tcx>,
         callee_body: &Body<'tcx>,
         callee_attrs: &CodegenFnAttrs,
+        cross_crate_inlinable: bool,
     ) -> Result<(), &'static str> {
         let tcx = self.tcx;
 
-        let mut threshold = if callee_attrs.requests_inline() {
+        let mut threshold = if cross_crate_inlinable {
             self.tcx.sess.opts.unstable_opts.inline_mir_hint_threshold.unwrap_or(100)
         } else {
             self.tcx.sess.opts.unstable_opts.inline_mir_threshold.unwrap_or(50)
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 78f76f1e513..01136974730 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -62,6 +62,7 @@ mod const_prop;
 mod const_prop_lint;
 mod copy_prop;
 mod coverage;
+mod cross_crate_inline;
 mod ctfe_limit;
 mod dataflow_const_prop;
 mod dead_store_elimination;
@@ -123,6 +124,7 @@ pub fn provide(providers: &mut Providers) {
     coverage::query::provide(providers);
     ffi_unwind_calls::provide(providers);
     shim::provide(providers);
+    cross_crate_inline::provide(providers);
     *providers = Providers {
         mir_keys,
         mir_const,
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index e93368a84ba..650bb97c4d1 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -18,43 +18,10 @@ use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::config::CrateType;
 use rustc_target::spec::abi::Abi;
 
-// Returns true if the given item must be inlined because it may be
-// monomorphized or it was marked with `#[inline]`. This will only return
-// true for functions.
-fn item_might_be_inlined(tcx: TyCtxt<'_>, item: &hir::Item<'_>, attrs: &CodegenFnAttrs) -> bool {
-    if attrs.requests_inline() {
-        return true;
-    }
-
-    match item.kind {
-        hir::ItemKind::Fn(ref sig, ..) if sig.header.is_const() => true,
-        hir::ItemKind::Impl { .. } | hir::ItemKind::Fn(..) => {
-            let generics = tcx.generics_of(item.owner_id);
-            generics.requires_monomorphization(tcx)
-        }
-        _ => false,
-    }
-}
-
-fn method_might_be_inlined(
-    tcx: TyCtxt<'_>,
-    impl_item: &hir::ImplItem<'_>,
-    impl_src: LocalDefId,
-) -> bool {
-    let codegen_fn_attrs = tcx.codegen_fn_attrs(impl_item.hir_id().owner.to_def_id());
-    let generics = tcx.generics_of(impl_item.owner_id);
-    if codegen_fn_attrs.requests_inline() || generics.requires_monomorphization(tcx) {
-        return true;
-    }
-    if let hir::ImplItemKind::Fn(method_sig, _) = &impl_item.kind {
-        if method_sig.header.is_const() {
-            return true;
-        }
-    }
-    match tcx.hir().find_by_def_id(impl_src) {
-        Some(Node::Item(item)) => item_might_be_inlined(tcx, &item, codegen_fn_attrs),
-        Some(..) | None => span_bug!(impl_item.span, "impl did is not an item"),
-    }
+fn item_might_be_inlined(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
+    tcx.generics_of(def_id).requires_monomorphization(tcx)
+        || tcx.cross_crate_inlinable(def_id)
+        || tcx.is_const_fn(def_id)
 }
 
 // Information needed while computing reachability.
@@ -150,9 +117,7 @@ impl<'tcx> ReachableContext<'tcx> {
 
         match self.tcx.hir().find_by_def_id(def_id) {
             Some(Node::Item(item)) => match item.kind {
-                hir::ItemKind::Fn(..) => {
-                    item_might_be_inlined(self.tcx, &item, self.tcx.codegen_fn_attrs(def_id))
-                }
+                hir::ItemKind::Fn(..) => item_might_be_inlined(self.tcx, def_id.into()),
                 _ => false,
             },
             Some(Node::TraitItem(trait_method)) => match trait_method.kind {
@@ -164,9 +129,7 @@ impl<'tcx> ReachableContext<'tcx> {
             Some(Node::ImplItem(impl_item)) => match impl_item.kind {
                 hir::ImplItemKind::Const(..) => true,
                 hir::ImplItemKind::Fn(..) => {
-                    let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
-                    let impl_did = self.tcx.hir().get_parent_item(hir_id);
-                    method_might_be_inlined(self.tcx, impl_item, impl_did.def_id)
+                    item_might_be_inlined(self.tcx, impl_item.hir_id().owner.to_def_id())
                 }
                 hir::ImplItemKind::Type(_) => false,
             },
@@ -226,11 +189,7 @@ impl<'tcx> ReachableContext<'tcx> {
             Node::Item(item) => {
                 match item.kind {
                     hir::ItemKind::Fn(.., body) => {
-                        if item_might_be_inlined(
-                            self.tcx,
-                            &item,
-                            self.tcx.codegen_fn_attrs(item.owner_id),
-                        ) {
+                        if item_might_be_inlined(self.tcx, item.owner_id.into()) {
                             self.visit_nested_body(body);
                         }
                     }
@@ -279,8 +238,7 @@ impl<'tcx> ReachableContext<'tcx> {
                     self.visit_nested_body(body);
                 }
                 hir::ImplItemKind::Fn(_, body) => {
-                    let impl_def_id = self.tcx.local_parent(search_item);
-                    if method_might_be_inlined(self.tcx, impl_item, impl_def_id) {
+                    if item_might_be_inlined(self.tcx, impl_item.hir_id().owner.to_def_id()) {
                         self.visit_nested_body(body)
                     }
                 }
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index f33139c5c4b..11fbd9f8f86 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1452,6 +1452,8 @@ options! {
         "combine CGUs into a single one"),
     crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED],
         "inject the given attribute in the crate"),
+    cross_crate_inline_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],
+        "threshold to allow cross crate inlining of functions"),
     debug_info_for_profiling: bool = (false, parse_bool, [TRACKED],
         "emit discriminators and other data necessary for AutoFDO"),
     debug_macros: bool = (false, parse_bool, [TRACKED],
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index 01b03de6acb..625b67a79ad 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -530,6 +530,7 @@ fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
 // ensure that the code generation related to these panics is minimal as there's
 // only one location which panics rather than a bunch throughout the module.
 #[cfg(not(no_global_oom_handling))]
+#[inline(never)]
 fn capacity_overflow() -> ! {
     panic!("capacity overflow");
 }
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index f1eeb75be7c..5c83f72f3c1 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -155,6 +155,7 @@ fn lang_start_internal(
 }
 
 #[cfg(not(test))]
+#[inline(never)]
 #[lang = "start"]
 fn lang_start<T: crate::process::Termination + 'static>(
     main: fn() -> T,
diff --git a/tests/assembly/asm/arm-types.rs b/tests/assembly/asm/arm-types.rs
index b22a26ce36f..9520f932779 100644
--- a/tests/assembly/asm/arm-types.rs
+++ b/tests/assembly/asm/arm-types.rs
@@ -1,6 +1,7 @@
 // assembly-output: emit-asm
 // compile-flags: --target armv7-unknown-linux-gnueabihf
 // compile-flags: -C target-feature=+neon
+// compile-flags: -C opt-level=0
 // needs-llvm-components: arm
 
 #![feature(no_core, lang_items, rustc_attrs, repr_simd)]
diff --git a/tests/assembly/closure-inherit-target-feature.rs b/tests/assembly/closure-inherit-target-feature.rs
index 65728a15516..24802603452 100644
--- a/tests/assembly/closure-inherit-target-feature.rs
+++ b/tests/assembly/closure-inherit-target-feature.rs
@@ -22,6 +22,7 @@ pub unsafe fn sse41_blend_nofeature(x: __m128, y: __m128) -> __m128 {
     f(x, y)
 }
 
+#[no_mangle]
 #[target_feature(enable = "sse4.1")]
 pub fn sse41_blend_noinline(x: __m128, y: __m128) -> __m128 {
     let f = {
diff --git a/tests/assembly/dwarf5.rs b/tests/assembly/dwarf5.rs
index f41e6bd55be..253baafb887 100644
--- a/tests/assembly/dwarf5.rs
+++ b/tests/assembly/dwarf5.rs
@@ -1,6 +1,6 @@
 // Makes sure that `-Z dwarf-version=5` causes `rustc` to emit DWARF version 5.
 // assembly-output: emit-asm
-// compile-flags: -g --target x86_64-unknown-linux-gnu -Z dwarf-version=5
+// compile-flags: -g --target x86_64-unknown-linux-gnu -Z dwarf-version=5 -Copt-level=0
 // needs-llvm-components: x86
 
 #![feature(no_core, lang_items)]
diff --git a/tests/codegen-units/item-collection/asm-sym.rs b/tests/codegen-units/item-collection/asm-sym.rs
index 8bafb95bc16..4b05b771a9b 100644
--- a/tests/codegen-units/item-collection/asm-sym.rs
+++ b/tests/codegen-units/item-collection/asm-sym.rs
@@ -6,15 +6,18 @@ pub unsafe fn f() {
     //~ MONO_ITEM static f::S @@ asm_sym-cgu.0[External]
     static S: usize = 1;
     //~ MONO_ITEM fn f::fun @@ asm_sym-cgu.0[External]
+    #[inline(never)]
     fn fun() {}
     core::arch::asm!("/* {0} {1} */", sym S, sym fun);
 }
 
 //~ MONO_ITEM fn g @@ asm_sym-cgu.0[External]
+#[inline(never)]
 pub unsafe fn g() {
     //~ MONO_ITEM static g::S @@ asm_sym-cgu.0[Internal]
     static S: usize = 2;
     //~ MONO_ITEM fn g::fun @@ asm_sym-cgu.0[Internal]
+    #[inline(never)]
     fn fun() {}
     core::arch::asm!("/* {0} {1} */", sym S, sym fun);
 }
diff --git a/tests/codegen-units/item-collection/auxiliary/cgu_export_trait_method.rs b/tests/codegen-units/item-collection/auxiliary/cgu_export_trait_method.rs
index ecea26dc4be..e94dded55cf 100644
--- a/tests/codegen-units/item-collection/auxiliary/cgu_export_trait_method.rs
+++ b/tests/codegen-units/item-collection/auxiliary/cgu_export_trait_method.rs
@@ -1,3 +1,5 @@
+// compile-flags: -Copt-level=0
+
 #![crate_type = "lib"]
 
 pub trait Trait : Sized {
diff --git a/tests/codegen-units/item-collection/cross-crate-trait-method.rs b/tests/codegen-units/item-collection/cross-crate-trait-method.rs
index b7216a14318..778b3820f18 100644
--- a/tests/codegen-units/item-collection/cross-crate-trait-method.rs
+++ b/tests/codegen-units/item-collection/cross-crate-trait-method.rs
@@ -1,4 +1,4 @@
-// compile-flags:-Zprint-mono-items=eager -Zinline-mir=no
+// compile-flags:-Zprint-mono-items=eager -Zinline-mir=no -Copt-level=0
 
 #![deny(dead_code)]
 #![feature(start)]
diff --git a/tests/codegen-units/item-collection/items-within-generic-items.rs b/tests/codegen-units/item-collection/items-within-generic-items.rs
index d37d7f7d9b2..bb1a3be36c5 100644
--- a/tests/codegen-units/item-collection/items-within-generic-items.rs
+++ b/tests/codegen-units/item-collection/items-within-generic-items.rs
@@ -1,4 +1,4 @@
-// compile-flags:-Zprint-mono-items=eager
+// compile-flags:-Zprint-mono-items=eager -Copt-level=0
 
 #![deny(dead_code)]
 #![feature(start)]
diff --git a/tests/codegen-units/item-collection/unreferenced-const-fn.rs b/tests/codegen-units/item-collection/unreferenced-const-fn.rs
index 17b92eae00d..5f59d801504 100644
--- a/tests/codegen-units/item-collection/unreferenced-const-fn.rs
+++ b/tests/codegen-units/item-collection/unreferenced-const-fn.rs
@@ -4,6 +4,7 @@
 #![crate_type = "rlib"]
 
 //~ MONO_ITEM fn foo @@ unreferenced_const_fn-cgu.0[External]
+#[inline(never)]
 pub const fn foo(x: u32) -> u32 {
     x + 0xf00
 }
diff --git a/tests/codegen/asm-sanitize-llvm.rs b/tests/codegen/asm-sanitize-llvm.rs
index 6dcacd08cac..41bed98038e 100644
--- a/tests/codegen/asm-sanitize-llvm.rs
+++ b/tests/codegen/asm-sanitize-llvm.rs
@@ -1,5 +1,5 @@
 // FIXME(nagisa): remove the flags below once all targets support `asm!`.
-// compile-flags: --target x86_64-unknown-linux-gnu
+// compile-flags: --target x86_64-unknown-linux-gnu -Copt-level=0
 // needs-llvm-components: x86
 
 // Verify we sanitize the special tokens for the LLVM inline-assembly, ensuring people won't
diff --git a/tests/codegen/async-fn-debug-awaitee-field.rs b/tests/codegen/async-fn-debug-awaitee-field.rs
index 690505fd72b..29defe68f8b 100644
--- a/tests/codegen/async-fn-debug-awaitee-field.rs
+++ b/tests/codegen/async-fn-debug-awaitee-field.rs
@@ -3,7 +3,7 @@
 // extensions rely on the field having this name.
 
 // ignore-tidy-linelength
-// compile-flags: -C debuginfo=2 --edition=2018
+// compile-flags: -C debuginfo=2 --edition=2018 -Copt-level=0
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/debug-linkage-name.rs b/tests/codegen/debug-linkage-name.rs
index 9011a7da51d..9bf4d521fc0 100644
--- a/tests/codegen/debug-linkage-name.rs
+++ b/tests/codegen/debug-linkage-name.rs
@@ -1,8 +1,8 @@
 // Verifies that linkage name is omitted when it is
 // the same as variable / function name.
 //
-// compile-flags: -C no-prepopulate-passes
-// compile-flags: -C debuginfo=2
+// compile-flags: -C no-prepopulate-passes -Copt-level=0
+// compile-flags: -C debuginfo=2 -Copt-level=0
 #![crate_type = "lib"]
 
 pub mod xyz {
diff --git a/tests/codegen/default-requires-uwtable.rs b/tests/codegen/default-requires-uwtable.rs
index 5d77d3f14bb..26424f03568 100644
--- a/tests/codegen/default-requires-uwtable.rs
+++ b/tests/codegen/default-requires-uwtable.rs
@@ -1,5 +1,5 @@
 // revisions: WINDOWS ANDROID
-// compile-flags: -C panic=abort
+// compile-flags: -C panic=abort -Copt-level=0
 // [WINDOWS] compile-flags: --target=x86_64-pc-windows-msvc
 // [WINDOWS] needs-llvm-components: x86
 // [ANDROID] compile-flags: --target=armv7-linux-androideabi
diff --git a/tests/codegen/drop.rs b/tests/codegen/drop.rs
index 3615ef47b53..14b5840e2fe 100644
--- a/tests/codegen/drop.rs
+++ b/tests/codegen/drop.rs
@@ -7,10 +7,12 @@
 struct SomeUniqueName;
 
 impl Drop for SomeUniqueName {
+    #[inline(never)]
     fn drop(&mut self) {
     }
 }
 
+#[inline(never)]
 pub fn possibly_unwinding() {
 }
 
diff --git a/tests/codegen/force-frame-pointers.rs b/tests/codegen/force-frame-pointers.rs
index 637c4234654..5791ae47937 100644
--- a/tests/codegen/force-frame-pointers.rs
+++ b/tests/codegen/force-frame-pointers.rs
@@ -1,4 +1,4 @@
-// compile-flags: -C no-prepopulate-passes -C force-frame-pointers=y
+// compile-flags: -C no-prepopulate-passes -C force-frame-pointers=y -Copt-level=0
 
 #![crate_type="lib"]
 
diff --git a/tests/codegen/force-unwind-tables.rs b/tests/codegen/force-unwind-tables.rs
index 4c0a5602c6d..c904978c9ff 100644
--- a/tests/codegen/force-unwind-tables.rs
+++ b/tests/codegen/force-unwind-tables.rs
@@ -1,4 +1,4 @@
-// compile-flags: -C no-prepopulate-passes -C force-unwind-tables=y
+// compile-flags: -C no-prepopulate-passes -C force-unwind-tables=y -Copt-level=0
 
 #![crate_type="lib"]
 
diff --git a/tests/codegen/inline-function-args-debug-info.rs b/tests/codegen/inline-function-args-debug-info.rs
index e3d8caa49d4..ffae99e0f24 100644
--- a/tests/codegen/inline-function-args-debug-info.rs
+++ b/tests/codegen/inline-function-args-debug-info.rs
@@ -6,6 +6,7 @@
 
 #![crate_type = "lib"]
 
+#[inline(never)]
 pub fn outer_function(x: usize, y: usize) -> usize {
     inner_function(x, y) + 1
 }
@@ -13,8 +14,8 @@ pub fn outer_function(x: usize, y: usize) -> usize {
 #[inline]
 fn inner_function(aaaa: usize, bbbb: usize) -> usize {
     // CHECK: !DILocalVariable(name: "aaaa", arg: 1
-    // CHECK-SAME: line: 14
+    // CHECK-SAME: line: 15
     // CHECK: !DILocalVariable(name: "bbbb", arg: 2
-    // CHECK-SAME: line: 14
+    // CHECK-SAME: line: 15
     aaaa + bbbb
 }
diff --git a/tests/codegen/instrument-mcount.rs b/tests/codegen/instrument-mcount.rs
index b26076e7a7b..50823775a41 100644
--- a/tests/codegen/instrument-mcount.rs
+++ b/tests/codegen/instrument-mcount.rs
@@ -1,5 +1,5 @@
 //
-// compile-flags: -Z instrument-mcount
+// compile-flags: -Z instrument-mcount -Copt-level=0
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/instrument-xray/basic.rs b/tests/codegen/instrument-xray/basic.rs
index d3e49d53174..5da878474f2 100644
--- a/tests/codegen/instrument-xray/basic.rs
+++ b/tests/codegen/instrument-xray/basic.rs
@@ -1,7 +1,7 @@
 // Checks that `-Z instrument-xray` produces expected instrumentation.
 //
 // needs-xray
-// compile-flags: -Z instrument-xray=always
+// compile-flags: -Z instrument-xray=always -Copt-level=0
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/instrument-xray/options-combine.rs b/tests/codegen/instrument-xray/options-combine.rs
index f7e500b65f6..d1e56586279 100644
--- a/tests/codegen/instrument-xray/options-combine.rs
+++ b/tests/codegen/instrument-xray/options-combine.rs
@@ -1,9 +1,9 @@
 // Checks that `-Z instrument-xray` options can be specified multiple times.
 //
 // needs-xray
-// compile-flags: -Z instrument-xray=skip-exit
-// compile-flags: -Z instrument-xray=instruction-threshold=123
-// compile-flags: -Z instrument-xray=instruction-threshold=456
+// compile-flags: -Z instrument-xray=skip-exit -Copt-level=0
+// compile-flags: -Z instrument-xray=instruction-threshold=123 -Copt-level=0
+// compile-flags: -Z instrument-xray=instruction-threshold=456 -Copt-level=0
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/instrument-xray/options-override.rs b/tests/codegen/instrument-xray/options-override.rs
index 00f81837902..b1fc4c966dc 100644
--- a/tests/codegen/instrument-xray/options-override.rs
+++ b/tests/codegen/instrument-xray/options-override.rs
@@ -1,8 +1,8 @@
 // Checks that the last `-Z instrument-xray` option wins.
 //
 // needs-xray
-// compile-flags: -Z instrument-xray=always
-// compile-flags: -Z instrument-xray=never
+// compile-flags: -Z instrument-xray=always -Copt-level=0
+// compile-flags: -Z instrument-xray=never -Copt-level=0
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/panic-unwind-default-uwtable.rs b/tests/codegen/panic-unwind-default-uwtable.rs
index 4c85008cf35..b78b159d20d 100644
--- a/tests/codegen/panic-unwind-default-uwtable.rs
+++ b/tests/codegen/panic-unwind-default-uwtable.rs
@@ -1,4 +1,4 @@
-// compile-flags: -C panic=unwind -C no-prepopulate-passes
+// compile-flags: -C panic=unwind -C no-prepopulate-passes -Copt-level=0
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/personality_lifetimes.rs b/tests/codegen/personality_lifetimes.rs
index 47243bece98..b39718a8d08 100644
--- a/tests/codegen/personality_lifetimes.rs
+++ b/tests/codegen/personality_lifetimes.rs
@@ -9,10 +9,12 @@
 struct S;
 
 impl Drop for S {
+    #[inline(never)]
     fn drop(&mut self) {
     }
 }
 
+#[inline(never)]
 fn might_unwind() {
 }
 
diff --git a/tests/codegen/sanitizer/cfi-emit-type-metadata-attr-cfi-encoding.rs b/tests/codegen/sanitizer/cfi-emit-type-metadata-attr-cfi-encoding.rs
index 084d8bf803c..f16890afad0 100644
--- a/tests/codegen/sanitizer/cfi-emit-type-metadata-attr-cfi-encoding.rs
+++ b/tests/codegen/sanitizer/cfi-emit-type-metadata-attr-cfi-encoding.rs
@@ -1,7 +1,7 @@
 // Verifies that user-defined CFI encoding for types are emitted.
 //
 // needs-sanitizer-cfi
-// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi
+// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0
 
 #![crate_type="lib"]
 #![feature(cfi_encoding, extern_types)]
diff --git a/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs b/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs
index 2d8b13e2080..4ed7c27fc4e 100644
--- a/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs
+++ b/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs
@@ -1,7 +1,7 @@
 // Verifies that type metadata identifiers for functions are emitted correctly.
 //
 // needs-sanitizer-cfi
-// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi
+// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0
 
 #![crate_type="lib"]
 #![allow(dead_code)]
diff --git a/tests/codegen/sanitizer/cfi-generalize-pointers.rs b/tests/codegen/sanitizer/cfi-generalize-pointers.rs
index 677ebdb27ec..17cb42d3e74 100644
--- a/tests/codegen/sanitizer/cfi-generalize-pointers.rs
+++ b/tests/codegen/sanitizer/cfi-generalize-pointers.rs
@@ -1,7 +1,7 @@
 // Verifies that pointer types are generalized.
 //
 // needs-sanitizer-cfi
-// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers
+// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers -Copt-level=0
 
 #![crate_type="lib"]
 
diff --git a/tests/codegen/sanitizer/cfi-normalize-integers.rs b/tests/codegen/sanitizer/cfi-normalize-integers.rs
index aa3913cb8e7..9663aa54c28 100644
--- a/tests/codegen/sanitizer/cfi-normalize-integers.rs
+++ b/tests/codegen/sanitizer/cfi-normalize-integers.rs
@@ -1,7 +1,7 @@
 // Verifies that integer types are normalized.
 //
 // needs-sanitizer-cfi
-// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers
+// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -Copt-level=0
 
 #![crate_type="lib"]
 
diff --git a/tests/codegen/sanitizer/kasan-emits-instrumentation.rs b/tests/codegen/sanitizer/kasan-emits-instrumentation.rs
index 783bc47b9d0..29d50d8df24 100644
--- a/tests/codegen/sanitizer/kasan-emits-instrumentation.rs
+++ b/tests/codegen/sanitizer/kasan-emits-instrumentation.rs
@@ -1,6 +1,6 @@
 // Verifies that `-Zsanitizer=kernel-address` emits sanitizer instrumentation.
 
-// compile-flags: -Zsanitizer=kernel-address
+// compile-flags: -Zsanitizer=kernel-address -Copt-level=0
 // revisions: aarch64 riscv64imac riscv64gc x86_64
 //[aarch64] compile-flags: --target aarch64-unknown-none
 //[aarch64] needs-llvm-components: aarch64
diff --git a/tests/codegen/sanitizer/memtag-attr-check.rs b/tests/codegen/sanitizer/memtag-attr-check.rs
index 2fd362656d4..3e5e14e8429 100644
--- a/tests/codegen/sanitizer/memtag-attr-check.rs
+++ b/tests/codegen/sanitizer/memtag-attr-check.rs
@@ -2,7 +2,7 @@
 // applied when enabling the memtag sanitizer.
 //
 // needs-sanitizer-memtag
-// compile-flags: -Zsanitizer=memtag -Ctarget-feature=+mte
+// compile-flags: -Zsanitizer=memtag -Ctarget-feature=+mte -Copt-level=0
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/no-sanitize.rs b/tests/codegen/sanitizer/no-sanitize.rs
index d0b69243453..029cf8e7f5c 100644
--- a/tests/codegen/sanitizer/no-sanitize.rs
+++ b/tests/codegen/sanitizer/no-sanitize.rs
@@ -2,7 +2,7 @@
 // selectively disable sanitizer instrumentation.
 //
 // needs-sanitizer-address
-// compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static
+// compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static -Copt-level=0
 
 #![crate_type="lib"]
 #![feature(no_sanitize)]
diff --git a/tests/codegen/sanitizer/safestack-attr-check.rs b/tests/codegen/sanitizer/safestack-attr-check.rs
index b73ed00e730..b19e2d13133 100644
--- a/tests/codegen/sanitizer/safestack-attr-check.rs
+++ b/tests/codegen/sanitizer/safestack-attr-check.rs
@@ -1,7 +1,7 @@
 // This tests that the safestack attribute is applied when enabling the safe-stack sanitizer.
 //
 // needs-sanitizer-safestack
-// compile-flags: -Zsanitizer=safestack
+// compile-flags: -Zsanitizer=safestack -Copt-level=0
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/src-hash-algorithm/src-hash-algorithm-md5.rs b/tests/codegen/src-hash-algorithm/src-hash-algorithm-md5.rs
index 64be1127786..6ef0f0406d2 100644
--- a/tests/codegen/src-hash-algorithm/src-hash-algorithm-md5.rs
+++ b/tests/codegen/src-hash-algorithm/src-hash-algorithm-md5.rs
@@ -1,4 +1,4 @@
-// compile-flags: -g -Z src-hash-algorithm=md5
+// compile-flags: -g -Z src-hash-algorithm=md5 -Copt-level=0
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/src-hash-algorithm/src-hash-algorithm-sha1.rs b/tests/codegen/src-hash-algorithm/src-hash-algorithm-sha1.rs
index 54e07152142..ebfa3040aca 100644
--- a/tests/codegen/src-hash-algorithm/src-hash-algorithm-sha1.rs
+++ b/tests/codegen/src-hash-algorithm/src-hash-algorithm-sha1.rs
@@ -1,4 +1,4 @@
-// compile-flags: -g -Z src-hash-algorithm=sha1
+// compile-flags: -g -Z src-hash-algorithm=sha1 -Copt-level=0
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/src-hash-algorithm/src-hash-algorithm-sha256.rs b/tests/codegen/src-hash-algorithm/src-hash-algorithm-sha256.rs
index dc7db8e2372..5ec678d55f3 100644
--- a/tests/codegen/src-hash-algorithm/src-hash-algorithm-sha256.rs
+++ b/tests/codegen/src-hash-algorithm/src-hash-algorithm-sha256.rs
@@ -1,4 +1,4 @@
-// compile-flags: -g -Z src-hash-algorithm=sha256
+// compile-flags: -g -Z src-hash-algorithm=sha256 -Copt-level=0
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/target-cpu-on-functions.rs b/tests/codegen/target-cpu-on-functions.rs
index c043eceb5cd..d5250f22cca 100644
--- a/tests/codegen/target-cpu-on-functions.rs
+++ b/tests/codegen/target-cpu-on-functions.rs
@@ -15,7 +15,8 @@ pub extern "C" fn exported() {
 
 // CHECK-LABEL: ; target_cpu_on_functions::not_exported
 // CHECK-NEXT: ; Function Attrs:
-// CHECK-NEXT: define {{.*}}() {{.*}} #0
+// CHECK-NEXT: define {{.*}}() {{.*}} #1
+#[inline(never)]
 fn not_exported() {}
 
 // CHECK: attributes #0 = {{.*}} "target-cpu"="{{.*}}"
diff --git a/tests/codegen/tied-features-strength.rs b/tests/codegen/tied-features-strength.rs
index 51334c12158..71cea48c4da 100644
--- a/tests/codegen/tied-features-strength.rs
+++ b/tests/codegen/tied-features-strength.rs
@@ -7,16 +7,16 @@
 // are targeting older LLVM versions. Once the min supported version
 // is LLVM-14 we can remove the optional regex matching for this feature.
 
-// [ENABLE_SVE] compile-flags: -C target-feature=+sve
+// [ENABLE_SVE] compile-flags: -C target-feature=+sve -Copt-level=0
 // ENABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(\+sve,?)|(\+neon,?))*}}" }
 
-// [DISABLE_SVE] compile-flags: -C target-feature=-sve
+// [DISABLE_SVE] compile-flags: -C target-feature=-sve -Copt-level=0
 // DISABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(-sve,?)|(\+neon,?))*}}" }
 
-// [DISABLE_NEON] compile-flags: -C target-feature=-neon
+// [DISABLE_NEON] compile-flags: -C target-feature=-neon -Copt-level=0
 // DISABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(-fp-armv8,?)|(-neon,?))*}}" }
 
-// [ENABLE_NEON] compile-flags: -C target-feature=+neon
+// [ENABLE_NEON] compile-flags: -C target-feature=+neon -Copt-level=0
 // ENABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(\+fp-armv8,?)|(\+neon,?))*}}" }
 
 
diff --git a/tests/codegen/tune-cpu-on-functions.rs b/tests/codegen/tune-cpu-on-functions.rs
index ed8dc0e9383..116f0772d25 100644
--- a/tests/codegen/tune-cpu-on-functions.rs
+++ b/tests/codegen/tune-cpu-on-functions.rs
@@ -3,7 +3,7 @@
 
 // no-prefer-dynamic
 //
-// compile-flags: -C no-prepopulate-passes -C panic=abort -C linker-plugin-lto -Cpasses=name-anon-globals -Z tune-cpu=generic
+// compile-flags: -C no-prepopulate-passes -C panic=abort -C linker-plugin-lto -Cpasses=name-anon-globals -Z tune-cpu=generic -Copt-level=0
 
 #![crate_type = "staticlib"]
 
diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff
index d5e58265dcc..142e08f4d6c 100644
--- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff
+++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff
@@ -4,29 +4,20 @@
   fn main() -> () {
       let mut _0: ();
       let _1: main::Un;
-      let mut _2: u32;
-      let mut _3: u32;
       scope 1 {
           debug un => _1;
           scope 2 {
           }
-          scope 3 (inlined std::mem::drop::<u32>) {
-              debug _x => _3;
+          scope 4 (inlined std::mem::drop::<u32>) {
+              debug _x => const 1_u32;
           }
       }
+      scope 3 (inlined val) {
+      }
   
       bb0: {
           StorageLive(_1);
-          StorageLive(_2);
-          _2 = val() -> [return: bb1, unwind unreachable];
-      }
-  
-      bb1: {
-          _1 = Un { us: move _2 };
-          StorageDead(_2);
-          StorageLive(_3);
-          _3 = (_1.0: u32);
-          StorageDead(_3);
+          _1 = Un { us: const 1_u32 };
           StorageDead(_1);
           return;
       }
diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff
index 5eaaeba135b..142e08f4d6c 100644
--- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff
+++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff
@@ -4,29 +4,20 @@
   fn main() -> () {
       let mut _0: ();
       let _1: main::Un;
-      let mut _2: u32;
-      let mut _3: u32;
       scope 1 {
           debug un => _1;
           scope 2 {
           }
-          scope 3 (inlined std::mem::drop::<u32>) {
-              debug _x => _3;
+          scope 4 (inlined std::mem::drop::<u32>) {
+              debug _x => const 1_u32;
           }
       }
+      scope 3 (inlined val) {
+      }
   
       bb0: {
           StorageLive(_1);
-          StorageLive(_2);
-          _2 = val() -> [return: bb1, unwind continue];
-      }
-  
-      bb1: {
-          _1 = Un { us: move _2 };
-          StorageDead(_2);
-          StorageLive(_3);
-          _3 = (_1.0: u32);
-          StorageDead(_3);
+          _1 = Un { us: const 1_u32 };
           StorageDead(_1);
           return;
       }
diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-abort.diff
index a538756ba2d..298a6084899 100644
--- a/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-abort.diff
+++ b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-abort.diff
@@ -7,104 +7,104 @@
       debug upper => _3;
       let mut _0: std::result::Result<(), std::fmt::Error>;
       let _4: bool;
-      let mut _5: &std::fmt::Formatter<'_>;
-      let mut _7: std::option::Option<usize>;
-      let mut _8: &std::fmt::Formatter<'_>;
-      let mut _9: isize;
-      let mut _11: &mut std::fmt::Formatter<'_>;
-      let mut _12: &T;
-      let mut _13: core::num::flt2dec::Sign;
-      let mut _14: u32;
-      let mut _15: u32;
-      let mut _16: usize;
-      let mut _17: bool;
-      let mut _18: &mut std::fmt::Formatter<'_>;
-      let mut _19: &T;
-      let mut _20: core::num::flt2dec::Sign;
-      let mut _21: bool;
+      let mut _6: std::option::Option<usize>;
+      let mut _7: isize;
+      let mut _9: &mut std::fmt::Formatter<'_>;
+      let mut _10: &T;
+      let mut _11: core::num::flt2dec::Sign;
+      let mut _12: u32;
+      let mut _13: u32;
+      let mut _14: usize;
+      let mut _15: bool;
+      let mut _16: &mut std::fmt::Formatter<'_>;
+      let mut _17: &T;
+      let mut _18: core::num::flt2dec::Sign;
+      let mut _19: bool;
       scope 1 {
           debug force_sign => _4;
-          let _6: core::num::flt2dec::Sign;
+          let _5: core::num::flt2dec::Sign;
           scope 2 {
-              debug sign => _6;
+              debug sign => _5;
               scope 3 {
-                  debug precision => _10;
-                  let _10: usize;
+                  debug precision => _8;
+                  let _8: usize;
+                  scope 5 (inlined Formatter::<'_>::precision) {
+                      debug self => _1;
+                  }
               }
           }
       }
+      scope 4 (inlined Formatter::<'_>::sign_plus) {
+          debug self => _1;
+          let mut _20: u32;
+          let mut _21: u32;
+      }
   
       bb0: {
           StorageLive(_4);
+          StorageLive(_20);
+          StorageLive(_21);
+          _21 = ((*_1).0: u32);
+          _20 = BitAnd(move _21, const 1_u32);
+          StorageDead(_21);
+          _4 = Ne(move _20, const 0_u32);
+          StorageDead(_20);
           StorageLive(_5);
-          _5 = &(*_1);
-          _4 = Formatter::<'_>::sign_plus(move _5) -> [return: bb1, unwind unreachable];
+          switchInt(_4) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
-          StorageDead(_5);
-          StorageLive(_6);
-          switchInt(_4) -> [0: bb3, otherwise: bb2];
+-         _5 = MinusPlus;
++         _5 = const MinusPlus;
+          goto -> bb3;
       }
   
       bb2: {
--         _6 = MinusPlus;
-+         _6 = const MinusPlus;
-          goto -> bb4;
+-         _5 = Minus;
++         _5 = const Minus;
+          goto -> bb3;
       }
   
       bb3: {
--         _6 = Minus;
-+         _6 = const Minus;
-          goto -> bb4;
+          StorageLive(_6);
+          _6 = ((*_1).4: std::option::Option<usize>);
+          _7 = discriminant(_6);
+          switchInt(move _7) -> [1: bb4, otherwise: bb6];
       }
   
       bb4: {
-          StorageLive(_7);
-          StorageLive(_8);
-          _8 = &(*_1);
-          _7 = Formatter::<'_>::precision(move _8) -> [return: bb5, unwind unreachable];
+          _8 = ((_6 as Some).0: usize);
+          StorageLive(_11);
+          _11 = _5;
+          StorageLive(_12);
+          StorageLive(_13);
+          _13 = _8 as u32 (IntToInt);
+          _12 = Add(move _13, const 1_u32);
+          StorageDead(_13);
+          _0 = float_to_exponential_common_exact::<T>(_1, _2, move _11, move _12, _3) -> [return: bb5, unwind unreachable];
       }
   
       bb5: {
-          StorageDead(_8);
-          _9 = discriminant(_7);
-          switchInt(move _9) -> [1: bb6, otherwise: bb8];
+          StorageDead(_12);
+          StorageDead(_11);
+          goto -> bb8;
       }
   
       bb6: {
-          _10 = ((_7 as Some).0: usize);
-          StorageLive(_13);
-          _13 = _6;
-          StorageLive(_14);
-          StorageLive(_15);
-          _15 = _10 as u32 (IntToInt);
-          _14 = Add(move _15, const 1_u32);
-          StorageDead(_15);
-          _0 = float_to_exponential_common_exact::<T>(_1, _2, move _13, move _14, _3) -> [return: bb7, unwind unreachable];
+          StorageLive(_18);
+          _18 = _5;
+          _0 = float_to_exponential_common_shortest::<T>(_1, _2, move _18, _3) -> [return: bb7, unwind unreachable];
       }
   
       bb7: {
-          StorageDead(_14);
-          StorageDead(_13);
-          goto -> bb10;
+          StorageDead(_18);
+          goto -> bb8;
       }
   
       bb8: {
-          StorageLive(_20);
-          _20 = _6;
-          _0 = float_to_exponential_common_shortest::<T>(_1, _2, move _20, _3) -> [return: bb9, unwind unreachable];
-      }
-  
-      bb9: {
-          StorageDead(_20);
-          goto -> bb10;
-      }
-  
-      bb10: {
-          StorageDead(_6);
+          StorageDead(_5);
           StorageDead(_4);
-          StorageDead(_7);
+          StorageDead(_6);
           return;
       }
   }
diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-unwind.diff
index 8a3dcfab44b..037f4f7cfac 100644
--- a/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-unwind.diff
+++ b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.panic-unwind.diff
@@ -7,104 +7,104 @@
       debug upper => _3;
       let mut _0: std::result::Result<(), std::fmt::Error>;
       let _4: bool;
-      let mut _5: &std::fmt::Formatter<'_>;
-      let mut _7: std::option::Option<usize>;
-      let mut _8: &std::fmt::Formatter<'_>;
-      let mut _9: isize;
-      let mut _11: &mut std::fmt::Formatter<'_>;
-      let mut _12: &T;
-      let mut _13: core::num::flt2dec::Sign;
-      let mut _14: u32;
-      let mut _15: u32;
-      let mut _16: usize;
-      let mut _17: bool;
-      let mut _18: &mut std::fmt::Formatter<'_>;
-      let mut _19: &T;
-      let mut _20: core::num::flt2dec::Sign;
-      let mut _21: bool;
+      let mut _6: std::option::Option<usize>;
+      let mut _7: isize;
+      let mut _9: &mut std::fmt::Formatter<'_>;
+      let mut _10: &T;
+      let mut _11: core::num::flt2dec::Sign;
+      let mut _12: u32;
+      let mut _13: u32;
+      let mut _14: usize;
+      let mut _15: bool;
+      let mut _16: &mut std::fmt::Formatter<'_>;
+      let mut _17: &T;
+      let mut _18: core::num::flt2dec::Sign;
+      let mut _19: bool;
       scope 1 {
           debug force_sign => _4;
-          let _6: core::num::flt2dec::Sign;
+          let _5: core::num::flt2dec::Sign;
           scope 2 {
-              debug sign => _6;
+              debug sign => _5;
               scope 3 {
-                  debug precision => _10;
-                  let _10: usize;
+                  debug precision => _8;
+                  let _8: usize;
+                  scope 5 (inlined Formatter::<'_>::precision) {
+                      debug self => _1;
+                  }
               }
           }
       }
+      scope 4 (inlined Formatter::<'_>::sign_plus) {
+          debug self => _1;
+          let mut _20: u32;
+          let mut _21: u32;
+      }
   
       bb0: {
           StorageLive(_4);
+          StorageLive(_20);
+          StorageLive(_21);
+          _21 = ((*_1).0: u32);
+          _20 = BitAnd(move _21, const 1_u32);
+          StorageDead(_21);
+          _4 = Ne(move _20, const 0_u32);
+          StorageDead(_20);
           StorageLive(_5);
-          _5 = &(*_1);
-          _4 = Formatter::<'_>::sign_plus(move _5) -> [return: bb1, unwind continue];
+          switchInt(_4) -> [0: bb2, otherwise: bb1];
       }
   
       bb1: {
-          StorageDead(_5);
-          StorageLive(_6);
-          switchInt(_4) -> [0: bb3, otherwise: bb2];
+-         _5 = MinusPlus;
++         _5 = const MinusPlus;
+          goto -> bb3;
       }
   
       bb2: {
--         _6 = MinusPlus;
-+         _6 = const MinusPlus;
-          goto -> bb4;
+-         _5 = Minus;
++         _5 = const Minus;
+          goto -> bb3;
       }
   
       bb3: {
--         _6 = Minus;
-+         _6 = const Minus;
-          goto -> bb4;
+          StorageLive(_6);
+          _6 = ((*_1).4: std::option::Option<usize>);
+          _7 = discriminant(_6);
+          switchInt(move _7) -> [1: bb4, otherwise: bb6];
       }
   
       bb4: {
-          StorageLive(_7);
-          StorageLive(_8);
-          _8 = &(*_1);
-          _7 = Formatter::<'_>::precision(move _8) -> [return: bb5, unwind continue];
+          _8 = ((_6 as Some).0: usize);
+          StorageLive(_11);
+          _11 = _5;
+          StorageLive(_12);
+          StorageLive(_13);
+          _13 = _8 as u32 (IntToInt);
+          _12 = Add(move _13, const 1_u32);
+          StorageDead(_13);
+          _0 = float_to_exponential_common_exact::<T>(_1, _2, move _11, move _12, _3) -> [return: bb5, unwind continue];
       }
   
       bb5: {
-          StorageDead(_8);
-          _9 = discriminant(_7);
-          switchInt(move _9) -> [1: bb6, otherwise: bb8];
+          StorageDead(_12);
+          StorageDead(_11);
+          goto -> bb8;
       }
   
       bb6: {
-          _10 = ((_7 as Some).0: usize);
-          StorageLive(_13);
-          _13 = _6;
-          StorageLive(_14);
-          StorageLive(_15);
-          _15 = _10 as u32 (IntToInt);
-          _14 = Add(move _15, const 1_u32);
-          StorageDead(_15);
-          _0 = float_to_exponential_common_exact::<T>(_1, _2, move _13, move _14, _3) -> [return: bb7, unwind continue];
+          StorageLive(_18);
+          _18 = _5;
+          _0 = float_to_exponential_common_shortest::<T>(_1, _2, move _18, _3) -> [return: bb7, unwind continue];
       }
   
       bb7: {
-          StorageDead(_14);
-          StorageDead(_13);
-          goto -> bb10;
+          StorageDead(_18);
+          goto -> bb8;
       }
   
       bb8: {
-          StorageLive(_20);
-          _20 = _6;
-          _0 = float_to_exponential_common_shortest::<T>(_1, _2, move _20, _3) -> [return: bb9, unwind continue];
-      }
-  
-      bb9: {
-          StorageDead(_20);
-          goto -> bb10;
-      }
-  
-      bb10: {
-          StorageDead(_6);
+          StorageDead(_5);
           StorageDead(_4);
-          StorageDead(_7);
+          StorageDead(_6);
           return;
       }
   }
diff --git a/tests/mir-opt/inline/issue_106141.rs b/tests/mir-opt/inline/issue_106141.rs
index eed1d89172c..e442f8a7522 100644
--- a/tests/mir-opt/inline/issue_106141.rs
+++ b/tests/mir-opt/inline/issue_106141.rs
@@ -3,6 +3,7 @@ pub fn outer() -> usize {
     inner()
 }
 
+#[inline(never)]
 fn index() -> usize {
     loop {}
 }
diff --git a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff
index bee01a5f97b..b9f268df351 100644
--- a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff
@@ -8,31 +8,37 @@
       let mut _3: &fn() {foo};
       let _4: fn() {foo};
       let mut _5: ();
++     scope 1 (inlined hide_foo) {
++     }
   
       bb0: {
           StorageLive(_2);
           StorageLive(_3);
           StorageLive(_4);
-          _4 = hide_foo() -> [return: bb1, unwind unreachable];
-      }
-  
-      bb1: {
+-         _4 = hide_foo() -> [return: bb1, unwind unreachable];
+-     }
+- 
+-     bb1: {
           _3 = &_4;
           StorageLive(_5);
           _5 = ();
-          _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind unreachable];
+-         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind unreachable];
++         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb1, unwind unreachable];
       }
   
-      bb2: {
+-     bb2: {
++     bb1: {
           StorageDead(_5);
           StorageDead(_3);
           StorageDead(_4);
           StorageDead(_2);
           _0 = const ();
-          drop(_1) -> [return: bb3, unwind unreachable];
+-         drop(_1) -> [return: bb3, unwind unreachable];
++         drop(_1) -> [return: bb2, unwind unreachable];
       }
   
-      bb3: {
+-     bb3: {
++     bb2: {
           return;
       }
   }
diff --git a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff
index 5a946712ea4..8495164df9c 100644
--- a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff
@@ -8,39 +8,48 @@
       let mut _3: &fn() {foo};
       let _4: fn() {foo};
       let mut _5: ();
++     scope 1 (inlined hide_foo) {
++     }
   
       bb0: {
           StorageLive(_2);
           StorageLive(_3);
           StorageLive(_4);
-          _4 = hide_foo() -> [return: bb1, unwind: bb4];
-      }
-  
-      bb1: {
+-         _4 = hide_foo() -> [return: bb1, unwind: bb4];
+-     }
+- 
+-     bb1: {
           _3 = &_4;
           StorageLive(_5);
           _5 = ();
-          _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4];
+-         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4];
++         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb1, unwind: bb3];
       }
   
-      bb2: {
+-     bb2: {
++     bb1: {
           StorageDead(_5);
           StorageDead(_3);
           StorageDead(_4);
           StorageDead(_2);
           _0 = const ();
-          drop(_1) -> [return: bb3, unwind: bb5];
+-         drop(_1) -> [return: bb3, unwind: bb5];
++         drop(_1) -> [return: bb2, unwind: bb4];
       }
   
-      bb3: {
+-     bb3: {
++     bb2: {
           return;
       }
   
-      bb4 (cleanup): {
-          drop(_1) -> [return: bb5, unwind terminate(cleanup)];
+-     bb4 (cleanup): {
+-         drop(_1) -> [return: bb5, unwind terminate(cleanup)];
++     bb3 (cleanup): {
++         drop(_1) -> [return: bb4, unwind terminate(cleanup)];
       }
   
-      bb5 (cleanup): {
+-     bb5 (cleanup): {
++     bb4 (cleanup): {
           resume;
       }
   }
diff --git a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir
index 1d3317efd41..7af69e08ca1 100644
--- a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir
@@ -4,17 +4,14 @@ fn outer(_1: u8) -> u8 {
     debug v => _1;                       // in scope 0 at $DIR/spans.rs:9:14: 9:15
     let mut _0: u8;                      // return place in scope 0 at $DIR/spans.rs:9:24: 9:26
     let mut _2: &u8;                     // in scope 0 at $DIR/spans.rs:10:11: 10:13
+    scope 1 (inlined inner) {            // at $DIR/spans.rs:10:5: 10:14
+        debug x => _2;                   // in scope 1 at $DIR/spans.rs:13:14: 13:15
+    }
 
     bb0: {
         StorageLive(_2);                 // scope 0 at $DIR/spans.rs:10:11: 10:13
         _2 = &_1;                        // scope 0 at $DIR/spans.rs:10:11: 10:13
-        _0 = inner(move _2) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/spans.rs:10:5: 10:14
-                                         // mir::ConstOperand
-                                         // + span: $DIR/spans.rs:10:5: 10:10
-                                         // + const_: Const { ty: for<'a> fn(&'a u8) -> u8 {inner}, val: Value(inner) }
-    }
-
-    bb1: {
+        _0 = _1;                         // scope 1 at $DIR/spans.rs:14:5: 14:7
         StorageDead(_2);                 // scope 0 at $DIR/spans.rs:10:13: 10:14
         return;                          // scope 0 at $DIR/spans.rs:11:2: 11:2
     }
diff --git a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir
index aba66861f7d..7af69e08ca1 100644
--- a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir
@@ -4,17 +4,14 @@ fn outer(_1: u8) -> u8 {
     debug v => _1;                       // in scope 0 at $DIR/spans.rs:9:14: 9:15
     let mut _0: u8;                      // return place in scope 0 at $DIR/spans.rs:9:24: 9:26
     let mut _2: &u8;                     // in scope 0 at $DIR/spans.rs:10:11: 10:13
+    scope 1 (inlined inner) {            // at $DIR/spans.rs:10:5: 10:14
+        debug x => _2;                   // in scope 1 at $DIR/spans.rs:13:14: 13:15
+    }
 
     bb0: {
         StorageLive(_2);                 // scope 0 at $DIR/spans.rs:10:11: 10:13
         _2 = &_1;                        // scope 0 at $DIR/spans.rs:10:11: 10:13
-        _0 = inner(move _2) -> [return: bb1, unwind continue]; // scope 0 at $DIR/spans.rs:10:5: 10:14
-                                         // mir::ConstOperand
-                                         // + span: $DIR/spans.rs:10:5: 10:10
-                                         // + const_: Const { ty: for<'a> fn(&'a u8) -> u8 {inner}, val: Value(inner) }
-    }
-
-    bb1: {
+        _0 = _1;                         // scope 1 at $DIR/spans.rs:14:5: 14:7
         StorageDead(_2);                 // scope 0 at $DIR/spans.rs:10:13: 10:14
         return;                          // scope 0 at $DIR/spans.rs:11:2: 11:2
     }
diff --git a/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-abort.mir
index c04fdeb637d..e6ce33ed682 100644
--- a/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-abort.mir
@@ -3,44 +3,26 @@
 fn while_loop(_1: bool) -> () {
     debug c => _1;
     let mut _0: ();
-    let mut _2: bool;
-    let mut _3: bool;
+    scope 1 (inlined get_bool) {
+        debug c => _1;
+    }
+    scope 2 (inlined get_bool) {
+        debug c => _1;
+    }
 
     bb0: {
         goto -> bb1;
     }
 
     bb1: {
-        StorageLive(_2);
-        _2 = get_bool(_1) -> [return: bb2, unwind unreachable];
+        switchInt(_1) -> [0: bb3, otherwise: bb2];
     }
 
     bb2: {
-        switchInt(move _2) -> [0: bb7, otherwise: bb3];
+        switchInt(_1) -> [0: bb1, otherwise: bb3];
     }
 
     bb3: {
-        StorageLive(_3);
-        _3 = get_bool(_1) -> [return: bb4, unwind unreachable];
-    }
-
-    bb4: {
-        switchInt(move _3) -> [0: bb5, otherwise: bb6];
-    }
-
-    bb5: {
-        StorageDead(_3);
-        StorageDead(_2);
-        goto -> bb1;
-    }
-
-    bb6: {
-        StorageDead(_3);
-        goto -> bb7;
-    }
-
-    bb7: {
-        StorageDead(_2);
         return;
     }
 }
diff --git a/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-unwind.mir
index 7dc4f7ab1a8..e6ce33ed682 100644
--- a/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/while_storage.while_loop.PreCodegen.after.panic-unwind.mir
@@ -3,44 +3,26 @@
 fn while_loop(_1: bool) -> () {
     debug c => _1;
     let mut _0: ();
-    let mut _2: bool;
-    let mut _3: bool;
+    scope 1 (inlined get_bool) {
+        debug c => _1;
+    }
+    scope 2 (inlined get_bool) {
+        debug c => _1;
+    }
 
     bb0: {
         goto -> bb1;
     }
 
     bb1: {
-        StorageLive(_2);
-        _2 = get_bool(_1) -> [return: bb2, unwind continue];
+        switchInt(_1) -> [0: bb3, otherwise: bb2];
     }
 
     bb2: {
-        switchInt(move _2) -> [0: bb7, otherwise: bb3];
+        switchInt(_1) -> [0: bb1, otherwise: bb3];
     }
 
     bb3: {
-        StorageLive(_3);
-        _3 = get_bool(_1) -> [return: bb4, unwind continue];
-    }
-
-    bb4: {
-        switchInt(move _3) -> [0: bb5, otherwise: bb6];
-    }
-
-    bb5: {
-        StorageDead(_3);
-        StorageDead(_2);
-        goto -> bb1;
-    }
-
-    bb6: {
-        StorageDead(_3);
-        goto -> bb7;
-    }
-
-    bb7: {
-        StorageDead(_2);
         return;
     }
 }
diff --git a/tests/run-make/emit-stack-sizes/foo.rs b/tests/run-make/emit-stack-sizes/foo.rs
index ee51ae32886..fd0b5120578 100644
--- a/tests/run-make/emit-stack-sizes/foo.rs
+++ b/tests/run-make/emit-stack-sizes/foo.rs
@@ -1,3 +1,4 @@
 #![crate_type = "lib"]
 
+#[inline(never)]
 pub fn foo() {}
diff --git a/tests/run-make/intrinsic-unreachable/exit-ret.rs b/tests/run-make/intrinsic-unreachable/exit-ret.rs
index e7b9694d9f2..c8ba5b4599f 100644
--- a/tests/run-make/intrinsic-unreachable/exit-ret.rs
+++ b/tests/run-make/intrinsic-unreachable/exit-ret.rs
@@ -2,6 +2,7 @@
 use std::arch::asm;
 
 #[deny(unreachable_code)]
+#[inline(never)]
 pub fn exit(n: usize) -> i32 {
     unsafe {
         // Pretend this asm is an exit() syscall.
diff --git a/tests/run-make/intrinsic-unreachable/exit-unreachable.rs b/tests/run-make/intrinsic-unreachable/exit-unreachable.rs
index ec85db733df..75f893eb2df 100644
--- a/tests/run-make/intrinsic-unreachable/exit-unreachable.rs
+++ b/tests/run-make/intrinsic-unreachable/exit-unreachable.rs
@@ -5,6 +5,7 @@ use std::arch::asm;
 use std::intrinsics;
 
 #[allow(unreachable_code)]
+#[inline(never)]
 pub fn exit(n: usize) -> i32 {
     unsafe {
         // Pretend this asm is an exit() syscall.
diff --git a/tests/ui/hygiene/panic-location.run.stderr b/tests/ui/hygiene/panic-location.run.stderr
index 5ed0d9fcf1e..1fd61084130 100644
--- a/tests/ui/hygiene/panic-location.run.stderr
+++ b/tests/ui/hygiene/panic-location.run.stderr
@@ -1,3 +1,3 @@
-thread 'main' panicked at library/alloc/src/raw_vec.rs:534:5:
+thread 'main' panicked at library/alloc/src/raw_vec.rs:535:5:
 capacity overflow
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace