diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 45e397a58c098..b090fb6137b0d 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -324,7 +324,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                         &self,
                         link_llvm_intrinsics,
                         i.span,
-                        "linking to LLVM intrinsics is experimental"
+                        "linking to LLVM intrinsics is an internal feature reserved for the standard library"
                     );
                 }
             }
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index dea574a53cd7b..cc2b3e8e58025 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -321,7 +321,12 @@ pub(crate) trait FnAbiLlvmExt<'ll, 'tcx> {
     );
 
     /// Apply attributes to a function call.
-    fn apply_attrs_callsite(&self, bx: &mut Builder<'_, 'll, 'tcx>, callsite: &'ll Value);
+    fn apply_attrs_callsite(
+        &self,
+        bx: &mut Builder<'_, 'll, 'tcx>,
+        callsite: &'ll Value,
+        instance: Option<ty::Instance<'tcx>>,
+    );
 }
 
 impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
@@ -527,11 +532,18 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
 
         // If the declaration has an associated instance, compute extra attributes based on that.
         if let Some(instance) = instance {
-            llfn_attrs_from_instance(cx, llfn, instance);
+            llfn_attrs_from_instance(cx, instance, Some(llfn), |place, attrs| {
+                attributes::apply_to_llfn(llfn, place, attrs)
+            });
         }
     }
 
-    fn apply_attrs_callsite(&self, bx: &mut Builder<'_, 'll, 'tcx>, callsite: &'ll Value) {
+    fn apply_attrs_callsite(
+        &self,
+        bx: &mut Builder<'_, 'll, 'tcx>,
+        callsite: &'ll Value,
+        instance: Option<ty::Instance<'tcx>>,
+    ) {
         let mut func_attrs = SmallVec::<[_; 2]>::new();
         if self.ret.layout.abi.is_uninhabited() {
             func_attrs.push(llvm::AttributeKind::NoReturn.create_attr(bx.cx.llcx));
@@ -649,6 +661,18 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
                 &[element_type_attr],
             );
         }
+
+        // If the call site has an associated instance, compute extra attributes based on that.
+        // However, only do that for calls to imported functions: all the others have these
+        // attributes applied already to the declaration, so we can save some work by not also
+        // applying them here (and this really shows in perf).
+        if let Some(instance) = instance
+            && bx.tcx.is_foreign_item(instance.def_id())
+        {
+            llfn_attrs_from_instance(bx.cx, instance, None, |place, attrs| {
+                attributes::apply_to_callsite(callsite, place, attrs)
+            });
+        }
     }
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 9d4497d73a8ae..067975dc72c90 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -14,8 +14,8 @@ use crate::context::CodegenCx;
 use crate::errors::{MissingFeatures, SanitizerMemtagRequiresMte, TargetFeatureDisableOrEnable};
 use crate::llvm::AttributePlace::Function;
 use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects};
+use crate::llvm_util;
 use crate::value::Value;
-use crate::{attributes, llvm_util};
 
 pub(crate) fn apply_to_llfn(llfn: &Value, idx: AttributePlace, attrs: &[&Attribute]) {
     if !attrs.is_empty() {
@@ -324,13 +324,18 @@ fn create_alloc_family_attr(llcx: &llvm::Context) -> &llvm::Attribute {
     llvm::CreateAttrStringValue(llcx, "alloc-family", "__rust_alloc")
 }
 
-/// Helper for `FnAbi::apply_attrs_llfn`:
+/// Helper for `FnAbi::apply_attrs_*`:
 /// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
 /// attributes.
+///
+/// `apply_attrs` is called to apply the attributes, so this can be used both for declarations and
+/// calls. However, some things are not represented as attributes and can only be set on
+/// declarations, so `declare_llfn` should be `Some` if this is a declaration.
 pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
-    llfn: &'ll Value,
     instance: ty::Instance<'tcx>,
+    declare_llfn: Option<&'ll Value>,
+    apply_attrs: impl Fn(AttributePlace, &[&Attribute]),
 ) {
     let codegen_fn_attrs = cx.tcx.codegen_fn_attrs(instance.def_id());
 
@@ -445,7 +450,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
         to_add.push(create_alloc_family_attr(cx.llcx));
         // apply to argument place instead of function
         let alloc_align = AttributeKind::AllocAlign.create_attr(cx.llcx);
-        attributes::apply_to_llfn(llfn, AttributePlace::Argument(1), &[alloc_align]);
+        apply_attrs(AttributePlace::Argument(1), &[alloc_align]);
         to_add.push(llvm::CreateAllocSizeAttr(cx.llcx, 0));
         let mut flags = AllocKindFlags::Alloc | AllocKindFlags::Aligned;
         if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR) {
@@ -456,7 +461,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
         to_add.push(llvm::CreateAllocKindAttr(cx.llcx, flags));
         // apply to return place instead of function (unlike all other attributes applied in this function)
         let no_alias = AttributeKind::NoAlias.create_attr(cx.llcx);
-        attributes::apply_to_llfn(llfn, AttributePlace::ReturnValue, &[no_alias]);
+        apply_attrs(AttributePlace::ReturnValue, &[no_alias]);
     }
     if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::REALLOCATOR) {
         to_add.push(create_alloc_family_attr(cx.llcx));
@@ -466,26 +471,28 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
         ));
         // applies to argument place instead of function place
         let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx);
-        attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]);
+        apply_attrs(AttributePlace::Argument(0), &[allocated_pointer]);
         // apply to argument place instead of function
         let alloc_align = AttributeKind::AllocAlign.create_attr(cx.llcx);
-        attributes::apply_to_llfn(llfn, AttributePlace::Argument(2), &[alloc_align]);
+        apply_attrs(AttributePlace::Argument(2), &[alloc_align]);
         to_add.push(llvm::CreateAllocSizeAttr(cx.llcx, 3));
         let no_alias = AttributeKind::NoAlias.create_attr(cx.llcx);
-        attributes::apply_to_llfn(llfn, AttributePlace::ReturnValue, &[no_alias]);
+        apply_attrs(AttributePlace::ReturnValue, &[no_alias]);
     }
     if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::DEALLOCATOR) {
         to_add.push(create_alloc_family_attr(cx.llcx));
         to_add.push(llvm::CreateAllocKindAttr(cx.llcx, AllocKindFlags::Free));
         // applies to argument place instead of function place
         let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx);
-        attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]);
+        apply_attrs(AttributePlace::Argument(0), &[allocated_pointer]);
     }
     if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY) {
         to_add.push(llvm::CreateAttrString(cx.llcx, "cmse_nonsecure_entry"));
     }
     if let Some(align) = codegen_fn_attrs.alignment {
-        llvm::set_alignment(llfn, align);
+        if let Some(llfn) = declare_llfn {
+            llvm::set_alignment(llfn, align);
+        }
     }
     if let Some(backchain) = backchain_attr(cx) {
         to_add.push(backchain);
@@ -503,24 +510,27 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
     let function_features =
         codegen_fn_attrs.target_features.iter().map(|f| f.name.as_str()).collect::<Vec<&str>>();
 
-    if let Some(f) = llvm_util::check_tied_features(
-        cx.tcx.sess,
-        &function_features.iter().map(|f| (*f, true)).collect(),
-    ) {
-        let span = cx
-            .tcx
-            .get_attrs(instance.def_id(), sym::target_feature)
-            .next()
-            .map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span);
-        cx.tcx
-            .dcx()
-            .create_err(TargetFeatureDisableOrEnable {
-                features: f,
-                span: Some(span),
-                missing_features: Some(MissingFeatures),
-            })
-            .emit();
-        return;
+    // HACK: Avoid emitting the lint twice.
+    if declare_llfn.is_some() {
+        if let Some(f) = llvm_util::check_tied_features(
+            cx.tcx.sess,
+            &function_features.iter().map(|f| (*f, true)).collect(),
+        ) {
+            let span = cx
+                .tcx
+                .get_attrs(instance.def_id(), sym::target_feature)
+                .next()
+                .map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span);
+            cx.tcx
+                .dcx()
+                .create_err(TargetFeatureDisableOrEnable {
+                    features: f,
+                    span: Some(span),
+                    missing_features: Some(MissingFeatures),
+                })
+                .emit();
+            return;
+        }
     }
 
     let function_features = function_features
@@ -562,7 +572,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
         to_add.push(llvm::CreateAttrStringValue(cx.llcx, "target-features", &target_features));
     }
 
-    attributes::apply_to_llfn(llfn, Function, &to_add);
+    apply_attrs(Function, &to_add);
 }
 
 fn wasm_import_module(tcx: TyCtxt<'_>, id: DefId) -> Option<&String> {
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 40783825cae57..dd3587222a309 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -262,7 +262,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
             )
         };
         if let Some(fn_abi) = fn_abi {
-            fn_abi.apply_attrs_callsite(self, invoke);
+            fn_abi.apply_attrs_callsite(self, invoke, instance);
         }
         invoke
     }
@@ -1307,7 +1307,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
             )
         };
         if let Some(fn_abi) = fn_abi {
-            fn_abi.apply_attrs_callsite(self, call);
+            fn_abi.apply_attrs_callsite(self, call, instance);
         }
         call
     }
@@ -1657,7 +1657,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
             )
         };
         if let Some(fn_abi) = fn_abi {
-            fn_abi.apply_attrs_callsite(self, callbr);
+            fn_abi.apply_attrs_callsite(self, callbr, instance);
         }
         callbr
     }
diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs
index 4e4500b637328..bca1848f5b7fa 100644
--- a/compiler/rustc_codegen_llvm/src/declare.rs
+++ b/compiler/rustc_codegen_llvm/src/declare.rs
@@ -12,8 +12,9 @@
 //! * When in doubt, define.
 
 use itertools::Itertools;
-use rustc_codegen_ssa::traits::TypeMembershipMethods;
+use rustc_codegen_ssa::traits::{BaseTypeMethods, TypeMembershipMethods};
 use rustc_data_structures::fx::FxIndexSet;
+use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::ty::{Instance, Ty};
 use rustc_sanitizers::{cfi, kcfi};
 use smallvec::SmallVec;
@@ -127,6 +128,42 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
     ) -> &'ll Value {
         debug!("declare_rust_fn(name={:?}, fn_abi={:?})", name, fn_abi);
 
+        // FFI imports need to be treated specially: in Rust one can import the same function
+        // with different signatures, but LLVM can only import each function once. Within a
+        // codegen unit, whatever declaration we set up last will "win"; across codegen units,
+        // LLVM is doing some sort of unspecified merging as part of LTO.
+        // This is partially unsound due to LLVM bugs (https://github.com/llvm/llvm-project/issues/58976),
+        // but on the Rust side we try to ensure soundness by making the least amount of promises
+        // for these imports: no matter the signatures, we declare all functions as `fn()`.
+        // If the same symbol is declared both as a function and a static, we just hope that
+        // doesn't lead to unsoundness (or LLVM crashes)...
+        let is_foreign_item = instance.is_some_and(|i| self.tcx.is_foreign_item(i.def_id()));
+        // If this is a Rust native allocator function, we want its attributes, so we do not
+        // treat it like the other FFI imports. If a user declares `__rust_alloc` we're going to have
+        // one import with the attributes and one with the default signature; that should hopefully be fine
+        // even if LLVM only sees the default one.
+        let is_rust_alloc_fn = instance.is_some_and(|i| {
+            let codegen_fn_flags = self.tcx.codegen_fn_attrs(i.def_id()).flags;
+            codegen_fn_flags.contains(CodegenFnAttrFlags::ALLOCATOR)
+                || codegen_fn_flags.contains(CodegenFnAttrFlags::ALLOCATOR_ZEROED)
+                || codegen_fn_flags.contains(CodegenFnAttrFlags::REALLOCATOR)
+                || codegen_fn_flags.contains(CodegenFnAttrFlags::DEALLOCATOR)
+        });
+        // If this is calling an LLVM intrinsic, we must set the right signature or LLVM complains.
+        // These are also unstable to call so nobody but us can screw up their signature.
+        let is_llvm_builtin = name.starts_with("llvm.");
+        if is_foreign_item && !is_rust_alloc_fn && !is_llvm_builtin {
+            return declare_raw_fn(
+                self,
+                name,
+                llvm::CallConv::CCallConv,
+                llvm::UnnamedAddr::Global,
+                llvm::Visibility::Default,
+                // The function type for `fn()`.
+                self.type_func(&[], self.type_void()),
+            );
+        }
+
         // Function addresses in Rust are never significant, allowing functions to
         // be merged.
         let llfn = declare_raw_fn(
diff --git a/tests/codegen/aarch64-struct-align-128.rs b/tests/codegen/aarch64-struct-align-128.rs
index 3fed19d96b122..49cf093967124 100644
--- a/tests/codegen/aarch64-struct-align-128.rs
+++ b/tests/codegen/aarch64-struct-align-128.rs
@@ -39,12 +39,17 @@ pub struct Wrapped8 {
 }
 
 extern "C" {
-    // linux:  declare void @test_8([2 x i64], [2 x i64], [2 x i64])
-    // darwin: declare void @test_8([2 x i64], [2 x i64], [2 x i64])
-    // win:    declare void @test_8([2 x i64], [2 x i64], [2 x i64])
     fn test_8(a: Align8, b: Transparent8, c: Wrapped8);
 }
 
+#[no_mangle]
+fn call_test_8(a: Align8, b: Transparent8, c: Wrapped8) {
+    // linux:  call void @test_8([2 x i64] {{%.*}}, [2 x i64] {{%.*}}, [2 x i64] {{%.*}})
+    // darwin: call void @test_8([2 x i64] {{%.*}}, [2 x i64] {{%.*}}, [2 x i64] {{%.*}})
+    // win:    call void @test_8([2 x i64] {{%.*}}, [2 x i64] {{%.*}}, [2 x i64] {{%.*}})
+    unsafe { test_8(a, b, c) }
+}
+
 // Passed as `i128`, since it's an aggregate with size <= 128 bits, align = 128 bits.
 // EXCEPT on Linux, where there's a special case to use its unadjusted alignment,
 // making it the same as `Align8`, so it's be passed as `[i64 x 2]`.
@@ -69,12 +74,17 @@ pub struct Wrapped16 {
 }
 
 extern "C" {
-    // linux:  declare void @test_16([2 x i64], [2 x i64], i128)
-    // darwin: declare void @test_16(i128, i128, i128)
-    // win:    declare void @test_16(i128, i128, i128)
     fn test_16(a: Align16, b: Transparent16, c: Wrapped16);
 }
 
+#[no_mangle]
+fn call_test_16(a: Align16, b: Transparent16, c: Wrapped16) {
+    // linux:  call void @test_16([2 x i64] {{%.*}}, [2 x i64] {{%.*}}, i128 {{%.*}})
+    // darwin: call void @test_16(i128 {{%.*}}, i128 {{%.*}}, i128 {{%.*}})
+    // win:    call void @test_16(i128 {{%.*}}, i128 {{%.*}}, i128 {{%.*}})
+    unsafe { test_16(a, b, c) }
+}
+
 // Passed as `i128`, since it's an aggregate with size <= 128 bits, align = 128 bits.
 #[repr(C)]
 pub struct I128 {
@@ -94,12 +104,17 @@ pub struct WrappedI128 {
 }
 
 extern "C" {
-    // linux:  declare void @test_i128(i128, i128, i128)
-    // darwin: declare void @test_i128(i128, i128, i128)
-    // win:    declare void @test_i128(i128, i128, i128)
     fn test_i128(a: I128, b: TransparentI128, c: WrappedI128);
 }
 
+#[no_mangle]
+fn call_test_i128(a: I128, b: TransparentI128, c: WrappedI128) {
+    // linux:  call void @test_i128(i128 {{%.*}}, i128 {{%.*}}, i128 {{%.*}})
+    // darwin: call void @test_i128(i128 {{%.*}}, i128 {{%.*}}, i128 {{%.*}})
+    // win:    call void @test_i128(i128 {{%.*}}, i128 {{%.*}}, i128 {{%.*}})
+    unsafe { test_i128(a, b, c) }
+}
+
 // Passed as `[2 x i64]`, since it's an aggregate with size <= 128 bits, align < 128 bits.
 // Note that the Linux special case does not apply, because packing is not considered "adjustment".
 #[repr(C)]
@@ -121,12 +136,17 @@ pub struct WrappedPacked {
 }
 
 extern "C" {
-    // linux:  declare void @test_packed([2 x i64], [2 x i64], [2 x i64])
-    // darwin: declare void @test_packed([2 x i64], [2 x i64], [2 x i64])
-    // win:    declare void @test_packed([2 x i64], [2 x i64], [2 x i64])
     fn test_packed(a: Packed, b: TransparentPacked, c: WrappedPacked);
 }
 
+#[no_mangle]
+fn call_test_packed(a: Packed, b: TransparentPacked, c: WrappedPacked) {
+    // linux:  call void @test_packed([2 x i64] {{%.*}}, [2 x i64] {{%.*}}, [2 x i64] {{%.*}})
+    // darwin: call void @test_packed([2 x i64] {{%.*}}, [2 x i64] {{%.*}}, [2 x i64] {{%.*}})
+    // win:    call void @test_packed([2 x i64] {{%.*}}, [2 x i64] {{%.*}}, [2 x i64] {{%.*}})
+    unsafe { test_packed(a, b, c) }
+}
+
 pub unsafe fn main(
     a1: Align8,
     a2: Transparent8,
@@ -141,8 +161,8 @@ pub unsafe fn main(
     d2: TransparentPacked,
     d3: WrappedPacked,
 ) {
-    test_8(a1, a2, a3);
-    test_16(b1, b2, b3);
-    test_i128(c1, c2, c3);
-    test_packed(d1, d2, d3);
+    call_test_8(a1, a2, a3);
+    call_test_16(b1, b2, b3);
+    call_test_i128(c1, c2, c3);
+    call_test_packed(d1, d2, d3);
 }
diff --git a/tests/codegen/align-byval-vector.rs b/tests/codegen/align-byval-vector.rs
index 60d49f9308197..af23862ec6566 100644
--- a/tests/codegen/align-byval-vector.rs
+++ b/tests/codegen/align-byval-vector.rs
@@ -37,18 +37,18 @@ pub struct DoubleFoo {
 }
 
 extern "C" {
-    // x86-linux: declare void @f({{.*}}byval([32 x i8]) align 4{{.*}})
-    // x86-darwin: declare void @f({{.*}}byval([32 x i8]) align 16{{.*}})
     fn f(foo: Foo);
 
-    // x86-linux: declare void @g({{.*}}byval([64 x i8]) align 4{{.*}})
-    // x86-darwin: declare void @g({{.*}}byval([64 x i8]) align 16{{.*}})
     fn g(foo: DoubleFoo);
 }
 
 pub fn main() {
+    // x86-linux: call void @f({{.*}}byval([32 x i8]) align 4 {{.*}})
+    // x86-darwin: call void @f({{.*}}byval([32 x i8]) align 16 {{.*}})
     unsafe { f(Foo { a: i32x4([1, 2, 3, 4]), b: 0 }) }
 
+    // x86-linux: call void @g({{.*}}byval([64 x i8]) align 4 {{.*}})
+    // x86-darwin: call void @g({{.*}}byval([64 x i8]) align 16 {{.*}})
     unsafe {
         g(DoubleFoo {
             one: Foo { a: i32x4([1, 2, 3, 4]), b: 0 },
diff --git a/tests/codegen/align-byval.rs b/tests/codegen/align-byval.rs
index 223696229cb1b..c6d336f6fdc94 100644
--- a/tests/codegen/align-byval.rs
+++ b/tests/codegen/align-byval.rs
@@ -107,6 +107,10 @@ pub struct ForceAlign16 {
 // CHECK-LABEL: @call_na1
 #[no_mangle]
 pub unsafe fn call_na1(x: NaturalAlign1) {
+    extern "C" {
+        fn natural_align_1(x: NaturalAlign1);
+    }
+
     // CHECK: start:
 
     // m68k: [[ALLOCA:%[a-z0-9+]]] = alloca [2 x i8], align 1
@@ -115,9 +119,9 @@ pub unsafe fn call_na1(x: NaturalAlign1) {
     // wasm: [[ALLOCA:%[a-z0-9+]]] = alloca [2 x i8], align 1
     // wasm: call void @natural_align_1({{.*}}byval([2 x i8]) align 1{{.*}} [[ALLOCA]])
 
-    // x86_64-linux: call void @natural_align_1(i16
+    // x86_64-linux: call void @natural_align_1(i16 %
 
-    // x86_64-windows: call void @natural_align_1(i16
+    // x86_64-windows: call void @natural_align_1(i16 %
 
     // i686-linux: [[ALLOCA:%[a-z0-9+]]] = alloca [2 x i8], align 4
     // i686-linux: call void @natural_align_1({{.*}}byval([2 x i8]) align 4{{.*}} [[ALLOCA]])
@@ -130,12 +134,19 @@ pub unsafe fn call_na1(x: NaturalAlign1) {
 // CHECK-LABEL: @call_na2
 #[no_mangle]
 pub unsafe fn call_na2(x: NaturalAlign2) {
+    extern "C" {
+        fn natural_align_2(x: NaturalAlign2);
+    }
+
     // CHECK: start:
 
-    // m68k-NEXT: call void @natural_align_2
-    // wasm-NEXT: call void @natural_align_2
-    // x86_64-linux-NEXT: call void @natural_align_2
+    // m68k-NEXT: call void @natural_align_2({{.*}}byval([34 x i8]) align 2{{.*}})
+    // wasm-NEXT: call void @natural_align_2({{.*}}byval([34 x i8]) align 2{{.*}})
+    // x86_64-linux-NEXT: call void @natural_align_2({{.*}}byval([34 x i8]) align 2{{.*}})
+
     // x86_64-windows-NEXT: call void @natural_align_2
+    // x86_64-windows-NOT: byval
+    // x86_64-windows-SAME: align 2{{.*}})
 
     // i686-linux: [[ALLOCA:%[0-9]+]] = alloca [34 x i8], align 4
     // i686-linux: call void @natural_align_2({{.*}}byval([34 x i8]) align 4{{.*}} [[ALLOCA]])
@@ -148,198 +159,175 @@ pub unsafe fn call_na2(x: NaturalAlign2) {
 // CHECK-LABEL: @call_fa4
 #[no_mangle]
 pub unsafe fn call_fa4(x: ForceAlign4) {
-    // CHECK: start:
-    // CHECK-NEXT: call void @force_align_4
-    force_align_4(x);
-}
+    extern "C" {
+        fn force_align_4(x: ForceAlign4);
+    }
 
-// CHECK-LABEL: @call_na8
-#[no_mangle]
-pub unsafe fn call_na8(x: NaturalAlign8) {
     // CHECK: start:
-    // CHECK-NEXT: call void @natural_align_8
-    natural_align_8(x);
-}
-
-// CHECK-LABEL: @call_fa8
-#[no_mangle]
-pub unsafe fn call_fa8(x: ForceAlign8) {
-    // CHECK: start:
-    // CHECK-NEXT: call void @force_align_8
-    force_align_8(x);
-}
-
-// CHECK-LABEL: @call_lfa8
-#[no_mangle]
-pub unsafe fn call_lfa8(x: LowerFA8) {
-    // CHECK: start:
-    // CHECK-NEXT: call void @lower_fa8
-    lower_fa8(x);
-}
-
-// CHECK-LABEL: @call_wfa8
-#[no_mangle]
-pub unsafe fn call_wfa8(x: WrappedFA8) {
-    // CHECK: start:
-    // CHECK-NEXT: call void @wrapped_fa8
-    wrapped_fa8(x);
-}
-
-// CHECK-LABEL: @call_tfa8
-#[no_mangle]
-pub unsafe fn call_tfa8(x: TransparentFA8) {
-    // CHECK: start:
-    // CHECK-NEXT: call void @transparent_fa8
-    transparent_fa8(x);
-}
-
-// CHECK-LABEL: @call_fa16
-#[no_mangle]
-pub unsafe fn call_fa16(x: ForceAlign16) {
-    // CHECK: start:
-    // CHECK-NEXT: call void @force_align_16
-    force_align_16(x);
-}
-
-extern "C" {
-    // m68k: declare void @natural_align_1({{.*}}byval([2 x i8]) align 1{{.*}})
-
-    // wasm: declare void @natural_align_1({{.*}}byval([2 x i8]) align 1{{.*}})
-
-    // x86_64-linux: declare void @natural_align_1(i16)
-
-    // x86_64-windows: declare void @natural_align_1(i16)
-
-    // i686-linux: declare void @natural_align_1({{.*}}byval([2 x i8]) align 4{{.*}})
+    // m68k-NEXT: call void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
 
-    // i686-windows: declare void @natural_align_1({{.*}}byval([2 x i8]) align 4{{.*}})
-    fn natural_align_1(x: NaturalAlign1);
+    // wasm-NEXT: call void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
 
-    // m68k: declare void @natural_align_2({{.*}}byval([34 x i8]) align 2{{.*}})
+    // x86_64-linux-NEXT: call void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
 
-    // wasm: declare void @natural_align_2({{.*}}byval([34 x i8]) align 2{{.*}})
-
-    // x86_64-linux: declare void @natural_align_2({{.*}}byval([34 x i8]) align 2{{.*}})
-
-    // x86_64-windows: declare void @natural_align_2(
-    // x86_64-windows-NOT: byval
-    // x86_64-windows-SAME: align 2{{.*}})
-
-    // i686-linux: declare void @natural_align_2({{.*}}byval([34 x i8]) align 4{{.*}})
-
-    // i686-windows: declare void @natural_align_2({{.*}}byval([34 x i8]) align 4{{.*}})
-    fn natural_align_2(x: NaturalAlign2);
-
-    // m68k: declare void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
-
-    // wasm: declare void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
-
-    // x86_64-linux: declare void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
-
-    // x86_64-windows: declare void @force_align_4(
+    // x86_64-windows-NEXT: call void @force_align_4(
     // x86_64-windows-NOT: byval
     // x86_64-windows-SAME: align 4{{.*}})
 
-    // i686-linux: declare void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
+    // i686-linux-NEXT: call void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
 
-    // i686-windows: declare void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
-    fn force_align_4(x: ForceAlign4);
+    // i686-windows-NEXT: call void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
+    force_align_4(x);
+}
 
-    // m68k: declare void @natural_align_8({{.*}}byval([24 x i8]) align 4{{.*}})
+// CHECK-LABEL: @call_na8
+#[no_mangle]
+pub unsafe fn call_na8(x: NaturalAlign8) {
+    extern "C" {
+        fn natural_align_8(x: NaturalAlign8);
+    }
+
+    // CHECK: start:
+    // m68k-NEXT: call void @natural_align_8({{.*}}byval([24 x i8]) align 4{{.*}})
 
-    // wasm: declare void @natural_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
+    // wasm-NEXT: call void @natural_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
 
-    // x86_64-linux: declare void @natural_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
+    // x86_64-linux-NEXT: call void @natural_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
 
-    // x86_64-windows: declare void @natural_align_8(
+    // x86_64-windows-NEXT: call void @natural_align_8(
     // x86_64-windows-NOT: byval
     // x86_64-windows-SAME: align 8{{.*}})
 
-    // i686-linux: declare void @natural_align_8({{.*}}byval([24 x i8]) align 4{{.*}})
+    // i686-linux-NEXT: call void @natural_align_8({{.*}}byval([24 x i8]) align 4{{.*}})
 
-    // i686-windows: declare void @natural_align_8({{.*}}byval([24 x i8]) align 4{{.*}})
-    fn natural_align_8(x: NaturalAlign8);
+    // i686-windows-NEXT: call void @natural_align_8({{.*}}byval([24 x i8]) align 4{{.*}})
+    natural_align_8(x);
+}
 
-    // m68k: declare void @force_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
+// CHECK-LABEL: @call_fa8
+#[no_mangle]
+pub unsafe fn call_fa8(x: ForceAlign8) {
+    extern "C" {
+        fn force_align_8(x: ForceAlign8);
+    }
+
+    // CHECK: start:
+    // m68k-NEXT: call void @force_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
 
-    // wasm: declare void @force_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
+    // wasm-NEXT: call void @force_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
 
-    // x86_64-linux: declare void @force_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
+    // x86_64-linux-NEXT: call void @force_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
 
-    // x86_64-windows: declare void @force_align_8(
+    // x86_64-windows-NEXT: call void @force_align_8(
     // x86_64-windows-NOT: byval
     // x86_64-windows-SAME: align 8{{.*}})
 
-    // i686-linux: declare void @force_align_8({{.*}}byval([24 x i8]) align 4{{.*}})
+    // i686-linux-NEXT: call void @force_align_8({{.*}}byval([24 x i8]) align 4{{.*}})
 
-    // i686-windows: declare void @force_align_8(
+    // i686-windows-NEXT: call void @force_align_8(
     // i686-windows-NOT: byval
     // i686-windows-SAME: align 8{{.*}})
-    fn force_align_8(x: ForceAlign8);
+    force_align_8(x);
+}
 
-    // m68k: declare void @lower_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
+// CHECK-LABEL: @call_lfa8
+#[no_mangle]
+pub unsafe fn call_lfa8(x: LowerFA8) {
+    extern "C" {
+        fn lower_fa8(x: LowerFA8);
+    }
+
+    // CHECK: start:
+    // m68k-NEXT: call void @lower_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
 
-    // wasm: declare void @lower_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
+    // wasm-NEXT: call void @lower_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
 
-    // x86_64-linux: declare void @lower_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
+    // x86_64-linux-NEXT: call void @lower_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
 
-    // x86_64-windows: declare void @lower_fa8(
+    // x86_64-windows-NEXT: call void @lower_fa8(
     // x86_64-windows-NOT: byval
     // x86_64-windows-SAME: align 8{{.*}})
 
-    // i686-linux: declare void @lower_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
+    // i686-linux-NEXT: call void @lower_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
 
-    // i686-windows: declare void @lower_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
-    fn lower_fa8(x: LowerFA8);
+    // i686-windows-NEXT: call void @lower_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
+    lower_fa8(x);
+}
 
-    // m68k: declare void @wrapped_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
+// CHECK-LABEL: @call_wfa8
+#[no_mangle]
+pub unsafe fn call_wfa8(x: WrappedFA8) {
+    extern "C" {
+        fn wrapped_fa8(x: WrappedFA8);
+    }
+
+    // CHECK: start:
+    // m68k-NEXT: call void @wrapped_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
 
-    // wasm: declare void @wrapped_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
+    // wasm-NEXT: call void @wrapped_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
 
-    // x86_64-linux: declare void @wrapped_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
+    // x86_64-linux-NEXT: call void @wrapped_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
 
-    // x86_64-windows: declare void @wrapped_fa8(
+    // x86_64-windows-NEXT: call void @wrapped_fa8(
     // x86_64-windows-NOT: byval
     // x86_64-windows-SAME: align 8{{.*}})
 
-    // i686-linux: declare void @wrapped_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
+    // i686-linux-NEXT: call void @wrapped_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
 
-    // i686-windows: declare void @wrapped_fa8(
+    // i686-windows-NEXT: call void @wrapped_fa8(
     // i686-windows-NOT: byval
     // i686-windows-SAME: align 8{{.*}})
-    fn wrapped_fa8(x: WrappedFA8);
+    wrapped_fa8(x);
+}
 
-    // m68k: declare void @transparent_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
+// CHECK-LABEL: @call_tfa8
+#[no_mangle]
+pub unsafe fn call_tfa8(x: TransparentFA8) {
+    extern "C" {
+        fn transparent_fa8(x: TransparentFA8);
+    }
 
-    // wasm: declare void @transparent_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
+    // CHECK: start:
+    // m68k-NEXT: call void @transparent_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
 
-    // x86_64-linux: declare void @transparent_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
+    // wasm-NEXT: call void @transparent_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
 
-    // x86_64-windows: declare void @transparent_fa8(
+    // x86_64-linux-NEXT: call void @transparent_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
+
+    // x86_64-windows-NEXT: call void @transparent_fa8(
     // x86_64-windows-NOT: byval
     // x86_64-windows-SAME: align 8{{.*}})
 
-    // i686-linux: declare void @transparent_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
+    // i686-linux-NEXT: call void @transparent_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
 
-    // i686-windows: declare void @transparent_fa8(
+    // i686-windows-NEXT: call void @transparent_fa8(
     // i686-windows-NOT: byval
     // i686-windows-SAME: align 8{{.*}})
-    fn transparent_fa8(x: TransparentFA8);
+    transparent_fa8(x);
+}
 
-    // m68k: declare void @force_align_16({{.*}}byval([80 x i8]) align 16{{.*}})
+// CHECK-LABEL: @call_fa16
+#[no_mangle]
+pub unsafe fn call_fa16(x: ForceAlign16) {
+    extern "C" {
+        fn force_align_16(x: ForceAlign16);
+    }
 
-    // wasm: declare void @force_align_16({{.*}}byval([80 x i8]) align 16{{.*}})
+    // CHECK: start:
+    // m68k-NEXT: call void @force_align_16({{.*}}byval([80 x i8]) align 16{{.*}})
+
+    // wasm-NEXT: call void @force_align_16({{.*}}byval([80 x i8]) align 16{{.*}})
 
-    // x86_64-linux: declare void @force_align_16({{.*}}byval([80 x i8]) align 16{{.*}})
+    // x86_64-linux-NEXT: call void @force_align_16({{.*}}byval([80 x i8]) align 16{{.*}})
 
-    // x86_64-windows: declare void @force_align_16(
+    // x86_64-windows-NEXT: call void @force_align_16(
     // x86_64-windows-NOT: byval
     // x86_64-windows-SAME: align 16{{.*}})
 
-    // i686-linux: declare void @force_align_16({{.*}}byval([80 x i8]) align 4{{.*}})
+    // i686-linux-NEXT: call void @force_align_16({{.*}}byval([80 x i8]) align 4{{.*}})
 
-    // i686-windows: declare void @force_align_16(
+    // i686-windows-NEXT: call void @force_align_16(
     // i686-windows-NOT: byval
     // i686-windows-SAME: align 16{{.*}})
-    fn force_align_16(x: ForceAlign16);
+    force_align_16(x);
 }
diff --git a/tests/codegen/box-uninit-bytes.rs b/tests/codegen/box-uninit-bytes.rs
index 63a6c7b841560..70a2f91ab66d9 100644
--- a/tests/codegen/box-uninit-bytes.rs
+++ b/tests/codegen/box-uninit-bytes.rs
@@ -8,7 +8,7 @@ use std::mem::MaybeUninit;
 pub fn box_uninitialized() -> Box<MaybeUninit<usize>> {
     // CHECK-LABEL: @box_uninitialized
     // CHECK-NOT: store
-    // CHECK-NOT: alloca
+    // CHECK-NOT: alloca{{ }}
     // CHECK-NOT: memcpy
     // CHECK-NOT: memset
     Box::new(MaybeUninit::uninit())
@@ -19,7 +19,7 @@ pub fn box_uninitialized() -> Box<MaybeUninit<usize>> {
 pub fn box_uninitialized2() -> Box<MaybeUninit<[usize; 1024 * 1024]>> {
     // CHECK-LABEL: @box_uninitialized2
     // CHECK-NOT: store
-    // CHECK-NOT: alloca
+    // CHECK-NOT: alloca{{ }}
     // CHECK-NOT: memcpy
     // CHECK-NOT: memset
     Box::new(MaybeUninit::uninit())
@@ -32,7 +32,7 @@ pub struct LotsaPadding(usize);
 #[no_mangle]
 pub fn box_lotsa_padding() -> Box<LotsaPadding> {
     // CHECK-LABEL: @box_lotsa_padding
-    // CHECK-NOT: alloca
+    // CHECK-NOT: alloca{{ }}
     // CHECK-NOT: getelementptr
     // CHECK-NOT: memcpy
     // CHECK-NOT: memset
diff --git a/tests/codegen/cffi/ffi-const.rs b/tests/codegen/cffi/ffi-const.rs
index 564b8f7f8d8d2..d241642cb2838 100644
--- a/tests/codegen/cffi/ffi-const.rs
+++ b/tests/codegen/cffi/ffi-const.rs
@@ -2,15 +2,18 @@
 #![crate_type = "lib"]
 #![feature(ffi_const)]
 
+#[no_mangle]
 pub fn bar() {
+    // CHECK-LABEL: @bar
+    // CHECK: @foo
+    // CHECK-SAME: [[ATTRS:#[0-9]+]]
     unsafe { foo() }
 }
 
 extern "C" {
-    // CHECK-LABEL: declare{{.*}}void @foo()
-    // CHECK-SAME: [[ATTRS:#[0-9]+]]
-    // The attribute changed from `readnone` to `memory(none)` with LLVM 16.0.
-    // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readnone|memory\(none\)}}{{.*}} }
     #[ffi_const]
     pub fn foo();
 }
+
+// The attribute changed from `readnone` to `memory(none)` with LLVM 16.0.
+// CHECK: attributes [[ATTRS]] = { {{.*}}{{readnone|memory\(none\)}}{{.*}} }
diff --git a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs
index ae8d8383f5b91..338ef325f2099 100644
--- a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs
+++ b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs
@@ -1,6 +1,6 @@
 //@ revisions: linux apple
 //@ min-llvm-version: 19
-//@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes -Zlint-llvm-ir -Cllvm-args=-lint-abort-on-error
+//@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes -Zlint-llvm-ir
 
 //@[linux] compile-flags: --target x86_64-unknown-linux-gnu
 //@[linux] needs-llvm-components: x86
diff --git a/tests/codegen/cffi/ffi-pure.rs b/tests/codegen/cffi/ffi-pure.rs
index 601509d5c90fe..17a39ba2690c2 100644
--- a/tests/codegen/cffi/ffi-pure.rs
+++ b/tests/codegen/cffi/ffi-pure.rs
@@ -2,15 +2,18 @@
 #![crate_type = "lib"]
 #![feature(ffi_pure)]
 
+#[no_mangle]
 pub fn bar() {
+    // CHECK-LABEL: @bar
+    // CHECK: @foo
+    // CHECK-SAME: [[ATTRS:#[0-9]+]]
     unsafe { foo() }
 }
 
 extern "C" {
-    // CHECK-LABEL: declare{{.*}}void @foo()
-    // CHECK-SAME: [[ATTRS:#[0-9]+]]
-    // The attribute changed from `readonly` to `memory(read)` with LLVM 16.0.
-    // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readonly|memory\(read\)}}{{.*}} }
     #[ffi_pure]
     pub fn foo();
 }
+
+// The attribute changed from `readonly` to `memory(read)` with LLVM 16.0.
+// CHECK: attributes [[ATTRS]] = { {{.*}}{{readonly|memory\(read\)}}{{.*}} }
diff --git a/tests/codegen/issues/issue-111603.rs b/tests/codegen/issues/issue-111603.rs
index 41bfb493ff580..ca5b073bea0f8 100644
--- a/tests/codegen/issues/issue-111603.rs
+++ b/tests/codegen/issues/issue-111603.rs
@@ -12,7 +12,7 @@ pub fn new_from_array(x: u64) -> Arc<[u64]> {
 
     // CHECK: alloca
     // CHECK-SAME: [8000 x i8]
-    // CHECK-NOT: alloca
+    // CHECK-NOT: alloca{{ }}
     let array = [x; 1000];
     Arc::new(array)
 }
diff --git a/tests/codegen/iter-repeat-n-trivial-drop.rs b/tests/codegen/iter-repeat-n-trivial-drop.rs
index 7de224b92d853..f2abefd9c59ec 100644
--- a/tests/codegen/iter-repeat-n-trivial-drop.rs
+++ b/tests/codegen/iter-repeat-n-trivial-drop.rs
@@ -47,7 +47,7 @@ pub fn iter_repeat_n_next(it: &mut std::iter::RepeatN<NotCopy>) -> Option<NotCop
 #[no_mangle]
 // CHECK-LABEL: @vec_extend_via_iter_repeat_n
 pub fn vec_extend_via_iter_repeat_n() -> Vec<u8> {
-    // CHECK: %[[ADDR:.+]] = tail call {{(noalias )?}}noundef dereferenceable_or_null(1234) ptr @__rust_alloc(i64 noundef 1234, i64 noundef 1)
+    // CHECK: %[[ADDR:.+]] = tail call {{(noalias )?}}noundef dereferenceable_or_null(1234) ptr @__rust_alloc(i64 noundef 1234, i64 {{(allocalign )?}}noundef 1)
     // CHECK: tail call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(1234) %[[ADDR]], i8 42, i64 1234,
 
     let n = 1234_usize;
diff --git a/tests/codegen/no_builtins-at-crate.rs b/tests/codegen/no_builtins-at-crate.rs
index ba1d31f60c390..234fb8e99842e 100644
--- a/tests/codegen/no_builtins-at-crate.rs
+++ b/tests/codegen/no_builtins-at-crate.rs
@@ -10,15 +10,13 @@
 pub unsafe extern "C" fn __aeabi_memcpy(dest: *mut u8, src: *const u8, size: usize) {
     // CHECK: call
     // CHECK-SAME: @memcpy(
+    // CHECK-SAME: #2
     memcpy(dest, src, size);
 }
 
-// CHECK: declare
-// CHECK-SAME: @memcpy
-// CHECK-SAME: #0
 extern "C" {
     pub fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8;
 }
 
-// CHECK: attributes #0
+// CHECK: attributes #2
 // CHECK-SAME: "no-builtins"
diff --git a/tests/codegen/pic-relocation-model.rs b/tests/codegen/pic-relocation-model.rs
index a1d1678a6bda5..54fbc2092d1c6 100644
--- a/tests/codegen/pic-relocation-model.rs
+++ b/tests/codegen/pic-relocation-model.rs
@@ -8,10 +8,7 @@ pub fn call_foreign_fn() -> u8 {
     unsafe { foreign_fn() }
 }
 
-// (Allow but do not require `zeroext` here, because it is not worth effort to
-// spell out which targets have it and which ones do not; see rust#97800.)
-
-// CHECK: declare{{( zeroext)?}} i8 @foreign_fn()
+// CHECK: declare void @foreign_fn()
 extern "C" {
     fn foreign_fn() -> u8;
 }
diff --git a/tests/codegen/pie-relocation-model.rs b/tests/codegen/pie-relocation-model.rs
index b10af69345228..a678b4baa08df 100644
--- a/tests/codegen/pie-relocation-model.rs
+++ b/tests/codegen/pie-relocation-model.rs
@@ -13,7 +13,7 @@ pub fn call_foreign_fn() -> u8 {
 
 // External functions are still marked as non-dso_local, since we don't know if the symbol
 // is defined in the binary or in the shared library.
-// CHECK: declare zeroext i8 @foreign_fn()
+// CHECK: declare void @foreign_fn()
 extern "C" {
     fn foreign_fn() -> u8;
 }
diff --git a/tests/codegen/powerpc64le-struct-align-128.rs b/tests/codegen/powerpc64le-struct-align-128.rs
index 3981cd1212961..555fb9596b40d 100644
--- a/tests/codegen/powerpc64le-struct-align-128.rs
+++ b/tests/codegen/powerpc64le-struct-align-128.rs
@@ -32,10 +32,15 @@ pub struct Wrapped8 {
 }
 
 extern "C" {
-    // CHECK: declare void @test_8([2 x i64], [2 x i64], [2 x i64])
     fn test_8(a: Align8, b: Transparent8, c: Wrapped8);
 }
 
+#[no_mangle]
+fn call_test_8(a: Align8, b: Transparent8, c: Wrapped8) {
+    // CHECK: call void @test_8([2 x i64] {{%.*}}, [2 x i64] {{%.*}}, [2 x i64] {{%.*}})
+    unsafe { test_8(a, b, c) }
+}
+
 #[repr(C)]
 #[repr(align(16))]
 pub struct Align16 {
@@ -54,11 +59,16 @@ pub struct Wrapped16 {
 }
 
 extern "C" {
-    // It's important that this produces [1 x i128]  rather than just i128!
-    // CHECK: declare void @test_16([1 x i128], [1 x i128], [1 x i128])
     fn test_16(a: Align16, b: Transparent16, c: Wrapped16);
 }
 
+#[no_mangle]
+fn call_test_16(a: Align16, b: Transparent16, c: Wrapped16) {
+    // It's important that this produces [1 x i128]  rather than just i128!
+    // CHECK: call void @test_16([1 x i128] {{%.*}}, [1 x i128] {{%.*}}, [1 x i128] {{%.*}})
+    unsafe { test_16(a, b, c) }
+}
+
 #[repr(C)]
 #[repr(align(32))]
 pub struct Align32 {
@@ -78,10 +88,15 @@ pub struct Wrapped32 {
 }
 
 extern "C" {
-    // CHECK: declare void @test_32([2 x i128], [2 x i128], [2 x i128])
     fn test_32(a: Align32, b: Transparent32, c: Wrapped32);
 }
 
+#[no_mangle]
+fn call_test_32(a: Align32, b: Transparent32, c: Wrapped32) {
+    // CHECK: call void @test_32([2 x i128] {{%.*}}, [2 x i128] {{%.*}}, [2 x i128] {{%.*}})
+    unsafe { test_32(a, b, c) }
+}
+
 pub unsafe fn main(
     a1: Align8,
     a2: Transparent8,
@@ -93,7 +108,7 @@ pub unsafe fn main(
     c2: Transparent32,
     c3: Wrapped32,
 ) {
-    test_8(a1, a2, a3);
-    test_16(b1, b2, b3);
-    test_32(c1, c2, c3);
+    call_test_8(a1, a2, a3);
+    call_test_16(b1, b2, b3);
+    call_test_32(c1, c2, c3);
 }
diff --git a/tests/codegen/unwind-extern-imports.rs b/tests/codegen/unwind-extern-imports.rs
index dfae8aae64a51..0dbddfa4061c2 100644
--- a/tests/codegen/unwind-extern-imports.rs
+++ b/tests/codegen/unwind-extern-imports.rs
@@ -3,9 +3,20 @@
 
 #![crate_type = "lib"]
 
+// The flag are only at the call sites, not at the declarations.
+// CHECK-LABEL: @force_declare
+#[no_mangle]
+pub unsafe fn force_declare() {
+    // CHECK: call void @extern_fn() [[NOUNWIND_ATTR:#[0-9]+]]
+    extern_fn();
+    // Call without attributes.
+    // CHECK: call void @c_unwind_extern_fn() [[UNWIND_ATTR:#[0-9]+]]
+    c_unwind_extern_fn();
+}
+
 extern "C" {
-    // CHECK: Function Attrs:{{.*}}nounwind
-    // CHECK-NEXT: declare{{.*}}void @extern_fn
+    // CHECK-NOT: nounwind
+    // CHECK: declare{{.*}}void @extern_fn
     fn extern_fn();
 }
 
@@ -15,7 +26,6 @@ extern "C-unwind" {
     fn c_unwind_extern_fn();
 }
 
-pub unsafe fn force_declare() {
-    extern_fn();
-    c_unwind_extern_fn();
-}
+// CHECK: attributes [[NOUNWIND_ATTR]] = { {{.*}}nounwind{{.*}} }
+// CHECK: attributes [[UNWIND_ATTR]]
+// CHECK-NOT: nounwind
diff --git a/tests/codegen/unwind-landingpad-cold.rs b/tests/codegen/unwind-landingpad-cold.rs
index fa200bc300cf9..9d9b1bf07566a 100644
--- a/tests/codegen/unwind-landingpad-cold.rs
+++ b/tests/codegen/unwind-landingpad-cold.rs
@@ -8,7 +8,8 @@
 
 // CHECK-LABEL: @check_cold
 // CHECK: {{(call|invoke) void .+}}drop_in_place{{.+}} [[ATTRIBUTES:#[0-9]+]]
-// CHECK: attributes [[ATTRIBUTES]] = { cold }
+// CHECK: attributes [[ATTRIBUTES]]
+// CHECK-SAME: cold
 #[no_mangle]
 pub fn check_cold(f: fn(), x: Box<u32>) {
     // this may unwind
diff --git a/tests/ui/extern/auxiliary/foreign-vectorcall.rs b/tests/ui/extern/auxiliary/foreign-vectorcall.rs
new file mode 100644
index 0000000000000..834678fc88dc0
--- /dev/null
+++ b/tests/ui/extern/auxiliary/foreign-vectorcall.rs
@@ -0,0 +1,10 @@
+// Make the aux build not use `dylib` to avoid https://github.com/rust-lang/rust/issues/130196
+//@ no-prefer-dynamic
+#![feature(abi_vectorcall)]
+#![crate_type = "lib"]
+
+#[no_mangle]
+#[inline(never)]
+pub extern "vectorcall" fn call_with_42(i: i32) {
+    assert_eq!(i, 42);
+}
diff --git a/tests/ui/extern/extern-vectorcall.rs b/tests/ui/extern/extern-vectorcall.rs
index c0d872bc14beb..2cd7c70a31e87 100644
--- a/tests/ui/extern/extern-vectorcall.rs
+++ b/tests/ui/extern/extern-vectorcall.rs
@@ -1,10 +1,19 @@
 //@ run-pass
+//@ aux-build:foreign-vectorcall.rs
 //@ revisions: x64 x32
 //@ [x64]only-x86_64
 //@ [x32]only-x86
 
 #![feature(abi_vectorcall)]
 
+extern crate foreign_vectorcall;
+
+// Import this as a foreign function, that's the code path we are interested in
+// (LLVM has to do some name mangling here).
+extern "vectorcall" {
+    fn call_with_42(i: i32);
+}
+
 trait A {
     extern "vectorcall" fn test1(i: i32);
 }
@@ -24,4 +33,5 @@ extern "vectorcall" fn test2(i: i32) {
 fn main() {
     <S as A>::test1(1);
     test2(2);
+    unsafe { call_with_42(42) };
 }
diff --git a/tests/ui/feature-gates/feature-gate-link_llvm_intrinsics.rs b/tests/ui/feature-gates/feature-gate-link_llvm_intrinsics.rs
index 7391ea94ebc04..30dba599a95a2 100644
--- a/tests/ui/feature-gates/feature-gate-link_llvm_intrinsics.rs
+++ b/tests/ui/feature-gates/feature-gate-link_llvm_intrinsics.rs
@@ -1,7 +1,7 @@
 extern "C" {
     #[link_name = "llvm.sqrt.f32"]
     fn sqrt(x: f32) -> f32;
-//~^ ERROR linking to LLVM intrinsics is experimental
+//~^ ERROR linking to LLVM intrinsics
 }
 
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-link_llvm_intrinsics.stderr b/tests/ui/feature-gates/feature-gate-link_llvm_intrinsics.stderr
index 686007dcbb7ea..106b93f770e63 100644
--- a/tests/ui/feature-gates/feature-gate-link_llvm_intrinsics.stderr
+++ b/tests/ui/feature-gates/feature-gate-link_llvm_intrinsics.stderr
@@ -1,4 +1,4 @@
-error[E0658]: linking to LLVM intrinsics is experimental
+error[E0658]: linking to LLVM intrinsics is an internal feature reserved for the standard library
   --> $DIR/feature-gate-link_llvm_intrinsics.rs:3:5
    |
 LL |     fn sqrt(x: f32) -> f32;
diff --git a/tests/ui/issues/issue-20313.rs b/tests/ui/issues/issue-20313.rs
index a72af650c7071..e51d3935bf55f 100644
--- a/tests/ui/issues/issue-20313.rs
+++ b/tests/ui/issues/issue-20313.rs
@@ -1,6 +1,6 @@
 extern "C" {
     #[link_name = "llvm.sqrt.f32"]
-    fn sqrt(x: f32) -> f32; //~ ERROR linking to LLVM intrinsics is experimental
+    fn sqrt(x: f32) -> f32; //~ ERROR linking to LLVM intrinsics
 }
 
 fn main() {}
diff --git a/tests/ui/issues/issue-20313.stderr b/tests/ui/issues/issue-20313.stderr
index a61495440f0fa..4d963efec055f 100644
--- a/tests/ui/issues/issue-20313.stderr
+++ b/tests/ui/issues/issue-20313.stderr
@@ -1,4 +1,4 @@
-error[E0658]: linking to LLVM intrinsics is experimental
+error[E0658]: linking to LLVM intrinsics is an internal feature reserved for the standard library
   --> $DIR/issue-20313.rs:3:5
    |
 LL |     fn sqrt(x: f32) -> f32;