about summary refs log tree commit diff
path: root/src/test/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/codegen')
-rw-r--r--src/test/codegen/atomic-operations-llvm-12.rs84
-rw-r--r--src/test/codegen/atomic-operations.rs26
-rw-r--r--src/test/codegen/box-maybe-uninit-llvm14.rs26
-rw-r--r--src/test/codegen/box-maybe-uninit.rs7
-rw-r--r--src/test/codegen/consts.rs2
-rw-r--r--src/test/codegen/function-arguments.rs27
-rw-r--r--src/test/codegen/intrinsics/const_eval_select.rs1
-rw-r--r--src/test/codegen/naked-noinline.rs2
-rw-r--r--src/test/codegen/noalias-box-off.rs8
-rw-r--r--src/test/codegen/noalias-box.rs8
-rw-r--r--src/test/codegen/repr-transparent-aggregates-2.rs16
-rw-r--r--src/test/codegen/sanitizer-cfi-add-canonical-jump-tables-flag.rs (renamed from src/test/codegen/sanitizer_cfi_add_canonical_jump_tables_flag.rs)5
-rw-r--r--src/test/codegen/sanitizer-cfi-emit-type-checks.rs (renamed from src/test/codegen/sanitizer_cfi_emit_type_checks.rs)12
-rw-r--r--src/test/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs575
-rw-r--r--src/test/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi.rs31
-rw-r--r--src/test/codegen/sanitizer_cfi_emit_type_metadata.rs31
-rw-r--r--src/test/codegen/sanitizer_scs_attr_check.rs17
-rw-r--r--src/test/codegen/simd-wide-sum.rs2
-rw-r--r--src/test/codegen/vec-calloc-llvm14.rs144
-rw-r--r--src/test/codegen/vec-calloc.rs142
20 files changed, 1091 insertions, 75 deletions
diff --git a/src/test/codegen/atomic-operations-llvm-12.rs b/src/test/codegen/atomic-operations-llvm-12.rs
new file mode 100644
index 00000000000..bd4c63dcff1
--- /dev/null
+++ b/src/test/codegen/atomic-operations-llvm-12.rs
@@ -0,0 +1,84 @@
+// Code generation of atomic operations for LLVM 12
+// ignore-llvm-version: 13 - 99
+// compile-flags: -O
+#![crate_type = "lib"]
+
+use std::sync::atomic::{AtomicI32, Ordering::*};
+
+// CHECK-LABEL: @compare_exchange
+#[no_mangle]
+pub fn compare_exchange(a: &AtomicI32) {
+    // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 10 monotonic monotonic
+    // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 11 acquire acquire
+    // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 12 seq_cst seq_cst
+    let _ = a.compare_exchange(0, 10, Relaxed, Relaxed);
+    let _ = a.compare_exchange(0, 11, Relaxed, Acquire);
+    let _ = a.compare_exchange(0, 12, Relaxed, SeqCst);
+
+    // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 20 release monotonic
+    // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 21 acq_rel acquire
+    // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 22 seq_cst seq_cst
+    let _ = a.compare_exchange(0, 20, Release, Relaxed);
+    let _ = a.compare_exchange(0, 21, Release, Acquire);
+    let _ = a.compare_exchange(0, 22, Release, SeqCst);
+
+    // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 30 acquire monotonic
+    // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 31 acquire acquire
+    // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 32 seq_cst seq_cst
+    let _ = a.compare_exchange(0, 30, Acquire, Relaxed);
+    let _ = a.compare_exchange(0, 31, Acquire, Acquire);
+    let _ = a.compare_exchange(0, 32, Acquire, SeqCst);
+
+    // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 40 acq_rel monotonic
+    // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 41 acq_rel acquire
+    // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 42 seq_cst seq_cst
+    let _ = a.compare_exchange(0, 40, AcqRel, Relaxed);
+    let _ = a.compare_exchange(0, 41, AcqRel, Acquire);
+    let _ = a.compare_exchange(0, 42, AcqRel, SeqCst);
+
+    // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 50 seq_cst monotonic
+    // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 51 seq_cst acquire
+    // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 52 seq_cst seq_cst
+    let _ = a.compare_exchange(0, 50, SeqCst, Relaxed);
+    let _ = a.compare_exchange(0, 51, SeqCst, Acquire);
+    let _ = a.compare_exchange(0, 52, SeqCst, SeqCst);
+}
+
+// CHECK-LABEL: @compare_exchange_weak
+#[no_mangle]
+pub fn compare_exchange_weak(w: &AtomicI32) {
+    // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 10 monotonic monotonic
+    // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 11 acquire acquire
+    // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 12 seq_cst seq_cst
+    let _ = w.compare_exchange_weak(1, 10, Relaxed, Relaxed);
+    let _ = w.compare_exchange_weak(1, 11, Relaxed, Acquire);
+    let _ = w.compare_exchange_weak(1, 12, Relaxed, SeqCst);
+
+    // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 20 release monotonic
+    // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 21 acq_rel acquire
+    // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 22 seq_cst seq_cst
+    let _ = w.compare_exchange_weak(1, 20, Release, Relaxed);
+    let _ = w.compare_exchange_weak(1, 21, Release, Acquire);
+    let _ = w.compare_exchange_weak(1, 22, Release, SeqCst);
+
+    // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 30 acquire monotonic
+    // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 31 acquire acquire
+    // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 32 seq_cst seq_cst
+    let _ = w.compare_exchange_weak(1, 30, Acquire, Relaxed);
+    let _ = w.compare_exchange_weak(1, 31, Acquire, Acquire);
+    let _ = w.compare_exchange_weak(1, 32, Acquire, SeqCst);
+
+    // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 40 acq_rel monotonic
+    // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 41 acq_rel acquire
+    // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 42 seq_cst seq_cst
+    let _ = w.compare_exchange_weak(1, 40, AcqRel, Relaxed);
+    let _ = w.compare_exchange_weak(1, 41, AcqRel, Acquire);
+    let _ = w.compare_exchange_weak(1, 42, AcqRel, SeqCst);
+
+    // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 50 seq_cst monotonic
+    // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 51 seq_cst acquire
+    // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 52 seq_cst seq_cst
+    let _ = w.compare_exchange_weak(1, 50, SeqCst, Relaxed);
+    let _ = w.compare_exchange_weak(1, 51, SeqCst, Acquire);
+    let _ = w.compare_exchange_weak(1, 52, SeqCst, SeqCst);
+}
diff --git a/src/test/codegen/atomic-operations.rs b/src/test/codegen/atomic-operations.rs
index a14f63726bb..771cf58725a 100644
--- a/src/test/codegen/atomic-operations.rs
+++ b/src/test/codegen/atomic-operations.rs
@@ -1,5 +1,5 @@
 // Code generation of atomic operations.
-//
+// min-llvm-version: 13.0
 // compile-flags: -O
 #![crate_type = "lib"]
 
@@ -9,20 +9,32 @@ use std::sync::atomic::{AtomicI32, Ordering::*};
 #[no_mangle]
 pub fn compare_exchange(a: &AtomicI32) {
     // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 10 monotonic monotonic
+    // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 11 monotonic acquire
+    // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 12 monotonic seq_cst
     let _ = a.compare_exchange(0, 10, Relaxed, Relaxed);
+    let _ = a.compare_exchange(0, 11, Relaxed, Acquire);
+    let _ = a.compare_exchange(0, 12, Relaxed, SeqCst);
 
     // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 20 release monotonic
+    // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 21 release acquire
+    // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 22 release seq_cst
     let _ = a.compare_exchange(0, 20, Release, Relaxed);
+    let _ = a.compare_exchange(0, 21, Release, Acquire);
+    let _ = a.compare_exchange(0, 22, Release, SeqCst);
 
     // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 30 acquire monotonic
     // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 31 acquire acquire
+    // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 32 acquire seq_cst
     let _ = a.compare_exchange(0, 30, Acquire, Relaxed);
     let _ = a.compare_exchange(0, 31, Acquire, Acquire);
+    let _ = a.compare_exchange(0, 32, Acquire, SeqCst);
 
     // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 40 acq_rel monotonic
     // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 41 acq_rel acquire
+    // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 42 acq_rel seq_cst
     let _ = a.compare_exchange(0, 40, AcqRel, Relaxed);
     let _ = a.compare_exchange(0, 41, AcqRel, Acquire);
+    let _ = a.compare_exchange(0, 42, AcqRel, SeqCst);
 
     // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 50 seq_cst monotonic
     // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 51 seq_cst acquire
@@ -36,20 +48,32 @@ pub fn compare_exchange(a: &AtomicI32) {
 #[no_mangle]
 pub fn compare_exchange_weak(w: &AtomicI32) {
     // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 10 monotonic monotonic
+    // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 11 monotonic acquire
+    // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 12 monotonic seq_cst
     let _ = w.compare_exchange_weak(1, 10, Relaxed, Relaxed);
+    let _ = w.compare_exchange_weak(1, 11, Relaxed, Acquire);
+    let _ = w.compare_exchange_weak(1, 12, Relaxed, SeqCst);
 
     // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 20 release monotonic
+    // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 21 release acquire
+    // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 22 release seq_cst
     let _ = w.compare_exchange_weak(1, 20, Release, Relaxed);
+    let _ = w.compare_exchange_weak(1, 21, Release, Acquire);
+    let _ = w.compare_exchange_weak(1, 22, Release, SeqCst);
 
     // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 30 acquire monotonic
     // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 31 acquire acquire
+    // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 32 acquire seq_cst
     let _ = w.compare_exchange_weak(1, 30, Acquire, Relaxed);
     let _ = w.compare_exchange_weak(1, 31, Acquire, Acquire);
+    let _ = w.compare_exchange_weak(1, 32, Acquire, SeqCst);
 
     // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 40 acq_rel monotonic
     // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 41 acq_rel acquire
+    // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 42 acq_rel seq_cst
     let _ = w.compare_exchange_weak(1, 40, AcqRel, Relaxed);
     let _ = w.compare_exchange_weak(1, 41, AcqRel, Acquire);
+    let _ = w.compare_exchange_weak(1, 42, AcqRel, SeqCst);
 
     // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 50 seq_cst monotonic
     // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 51 seq_cst acquire
diff --git a/src/test/codegen/box-maybe-uninit-llvm14.rs b/src/test/codegen/box-maybe-uninit-llvm14.rs
new file mode 100644
index 00000000000..bd1a6599c33
--- /dev/null
+++ b/src/test/codegen/box-maybe-uninit-llvm14.rs
@@ -0,0 +1,26 @@
+// compile-flags: -O
+
+// Once we're done with llvm 14 and earlier, this test can be deleted.
+
+#![crate_type="lib"]
+
+use std::mem::MaybeUninit;
+
+// Boxing a `MaybeUninit` value should not copy junk from the stack
+#[no_mangle]
+pub fn box_uninitialized() -> Box<MaybeUninit<usize>> {
+    // CHECK-LABEL: @box_uninitialized
+    // CHECK-NOT: store
+    // CHECK-NOT: alloca
+    // CHECK-NOT: memcpy
+    // CHECK-NOT: memset
+    Box::new(MaybeUninit::uninit())
+}
+
+// FIXME: add a test for a bigger box. Currently broken, see
+// https://github.com/rust-lang/rust/issues/58201.
+
+// Hide the LLVM 15+ `allocalign` attribute in the declaration of __rust_alloc
+// from the CHECK-NOT above. We don't check the attributes here because we can't rely
+// on all of them being set until LLVM 15.
+// CHECK: declare noalias{{.*}} @__rust_alloc(i{{[0-9]+}}, i{{[0-9]+.*}})
diff --git a/src/test/codegen/box-maybe-uninit.rs b/src/test/codegen/box-maybe-uninit.rs
index 5004f787cde..e105e26f16a 100644
--- a/src/test/codegen/box-maybe-uninit.rs
+++ b/src/test/codegen/box-maybe-uninit.rs
@@ -1,4 +1,5 @@
 // compile-flags: -O
+// min-llvm-version: 15.0
 #![crate_type="lib"]
 
 use std::mem::MaybeUninit;
@@ -16,3 +17,9 @@ pub fn box_uninitialized() -> Box<MaybeUninit<usize>> {
 
 // FIXME: add a test for a bigger box. Currently broken, see
 // https://github.com/rust-lang/rust/issues/58201.
+
+// Hide the `allocalign` attribute in the declaration of __rust_alloc
+// from the CHECK-NOT above, and also verify the attributes got set reasonably.
+// CHECK: declare noalias ptr @__rust_alloc(i{{[0-9]+}}, i{{[0-9]+}} allocalign) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]]
+
+// CHECK-DAG: attributes [[RUST_ALLOC_ATTRS]] = { {{.*}} allockind("alloc,uninitialized,aligned") allocsize(0) uwtable "alloc-family"="__rust_alloc" {{.*}} }
diff --git a/src/test/codegen/consts.rs b/src/test/codegen/consts.rs
index c97223879ca..260d9de8670 100644
--- a/src/test/codegen/consts.rs
+++ b/src/test/codegen/consts.rs
@@ -10,7 +10,7 @@
 // CHECK: @STATIC = {{.*}}, align 4
 
 // This checks the constants from inline_enum_const
-// CHECK: @alloc14 = {{.*}}, align 2
+// CHECK: @alloc12 = {{.*}}, align 2
 
 // This checks the constants from {low,high}_align_const, they share the same
 // constant, but the alignment differs, so the higher one should be used
diff --git a/src/test/codegen/function-arguments.rs b/src/test/codegen/function-arguments.rs
index ae6abe7a184..bc650ebf5ee 100644
--- a/src/test/codegen/function-arguments.rs
+++ b/src/test/codegen/function-arguments.rs
@@ -5,6 +5,7 @@
 
 use std::mem::MaybeUninit;
 use std::num::NonZeroU64;
+use std::marker::PhantomPinned;
 
 pub struct S {
   _field: [i32; 8],
@@ -14,6 +15,11 @@ pub struct UnsafeInner {
   _field: std::cell::UnsafeCell<i16>,
 }
 
+pub struct NotUnpin {
+  _field: i32,
+  _marker: PhantomPinned,
+}
+
 pub enum MyBool {
   True,
   False,
@@ -91,7 +97,7 @@ pub fn static_borrow(_: &'static i32) {
 pub fn named_borrow<'r>(_: &'r i32) {
 }
 
-// CHECK: @unsafe_borrow({{i16\*|ptr}} noundef align 2 dereferenceable(2) %_1)
+// CHECK: @unsafe_borrow({{i16\*|ptr}} noundef nonnull align 2 %_1)
 // unsafe interior means this isn't actually readonly and there may be aliases ...
 #[no_mangle]
 pub fn unsafe_borrow(_: &UnsafeInner) {
@@ -109,6 +115,18 @@ pub fn mutable_unsafe_borrow(_: &mut UnsafeInner) {
 pub fn mutable_borrow(_: &mut i32) {
 }
 
+#[no_mangle]
+// CHECK: @mutable_notunpin_borrow({{i32\*|ptr}} noundef align 4 dereferenceable(4) %_1)
+// This one is *not* `noalias` because it might be self-referential.
+pub fn mutable_notunpin_borrow(_: &mut NotUnpin) {
+}
+
+// CHECK: @notunpin_borrow({{i32\*|ptr}} noalias noundef readonly align 4 dereferenceable(4) %_1)
+// But `&NotUnpin` behaves perfectly normal.
+#[no_mangle]
+pub fn notunpin_borrow(_: &NotUnpin) {
+}
+
 // CHECK: @indirect_struct({{%S\*|ptr}} noalias nocapture noundef dereferenceable(32) %_1)
 #[no_mangle]
 pub fn indirect_struct(_: S) {
@@ -215,10 +233,3 @@ pub fn enum_id_1(x: Option<Result<u16, u16>>) -> Option<Result<u16, u16>> {
 pub fn enum_id_2(x: Option<u8>) -> Option<u8> {
   x
 }
-
-// CHECK: noalias {{i8\*|ptr}} @allocator()
-#[no_mangle]
-#[rustc_allocator]
-pub fn allocator() -> *const i8 {
-  std::ptr::null()
-}
diff --git a/src/test/codegen/intrinsics/const_eval_select.rs b/src/test/codegen/intrinsics/const_eval_select.rs
index 34e653b4b9d..db8a04763d3 100644
--- a/src/test/codegen/intrinsics/const_eval_select.rs
+++ b/src/test/codegen/intrinsics/const_eval_select.rs
@@ -2,6 +2,7 @@
 
 #![crate_type = "lib"]
 #![feature(const_eval_select)]
+#![feature(core_intrinsics)]
 
 use std::intrinsics::const_eval_select;
 
diff --git a/src/test/codegen/naked-noinline.rs b/src/test/codegen/naked-noinline.rs
index 13bc139ecd0..c0ac69f4ed7 100644
--- a/src/test/codegen/naked-noinline.rs
+++ b/src/test/codegen/naked-noinline.rs
@@ -28,4 +28,4 @@ pub unsafe fn g() {
     f();
 }
 
-// CHECK: attributes [[ATTR]] = { naked noinline{{.*}} }
+// CHECK: attributes [[ATTR]] = { naked{{.*}}noinline{{.*}} }
diff --git a/src/test/codegen/noalias-box-off.rs b/src/test/codegen/noalias-box-off.rs
new file mode 100644
index 00000000000..afd17c7c160
--- /dev/null
+++ b/src/test/codegen/noalias-box-off.rs
@@ -0,0 +1,8 @@
+// compile-flags: -O -Z box-noalias=no
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @box_should_not_have_noalias_if_disabled(
+// CHECK-NOT: noalias
+#[no_mangle]
+pub fn box_should_not_have_noalias_if_disabled(_b: Box<u8>) {}
diff --git a/src/test/codegen/noalias-box.rs b/src/test/codegen/noalias-box.rs
new file mode 100644
index 00000000000..a3d1f093d8b
--- /dev/null
+++ b/src/test/codegen/noalias-box.rs
@@ -0,0 +1,8 @@
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @box_should_have_noalias_by_default(
+// CHECK: noalias
+#[no_mangle]
+pub fn box_should_have_noalias_by_default(_b: Box<u8>) {}
diff --git a/src/test/codegen/repr-transparent-aggregates-2.rs b/src/test/codegen/repr-transparent-aggregates-2.rs
index b68e8e9ebe9..df7e88f08c7 100644
--- a/src/test/codegen/repr-transparent-aggregates-2.rs
+++ b/src/test/codegen/repr-transparent-aggregates-2.rs
@@ -37,19 +37,19 @@ pub enum TeBigS {
     Variant(BigS),
 }
 
-// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], [16 x i32]
+// CHECK: define void @test_BigS({{%BigS\*|ptr}} [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], [16 x i32]
 #[no_mangle]
 pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
 
-// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], [16 x i32]
+// CHECK: define void @test_TsBigS({{%TsBigS\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], [16 x i32]
 #[no_mangle]
 pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
 
-// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], [16 x i32]
+// CHECK: define void @test_TuBigS({{%TuBigS\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], [16 x i32]
 #[no_mangle]
 pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
 
-// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], [16 x i32]
+// CHECK: define void @test_TeBigS({{%"TeBigS::Variant"\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], [16 x i32]
 #[no_mangle]
 pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
 
@@ -73,18 +73,18 @@ pub enum TeBigU {
     Variant(BigU),
 }
 
-// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], [16 x i32]
+// CHECK: define void @test_BigU({{%BigU\*|ptr}} [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], [16 x i32]
 #[no_mangle]
 pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
 
-// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS1]] sret(%TsBigU) [[BIGU_RET_ATTRS2]], [16 x i32]
+// CHECK: define void @test_TsBigU({{%TsBigU\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%TsBigU) [[BIGU_RET_ATTRS2]], [16 x i32]
 #[no_mangle]
 pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
 
-// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2]], [16 x i32]
+// CHECK: define void @test_TuBigU({{%TuBigU\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2]], [16 x i32]
 #[no_mangle]
 pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
 
-// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2]], [16 x i32]
+// CHECK: define void @test_TeBigU({{%"TeBigU::Variant"\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2]], [16 x i32]
 #[no_mangle]
 pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
diff --git a/src/test/codegen/sanitizer_cfi_add_canonical_jump_tables_flag.rs b/src/test/codegen/sanitizer-cfi-add-canonical-jump-tables-flag.rs
index 68f81808861..c42fbba7425 100644
--- a/src/test/codegen/sanitizer_cfi_add_canonical_jump_tables_flag.rs
+++ b/src/test/codegen/sanitizer-cfi-add-canonical-jump-tables-flag.rs
@@ -1,10 +1,7 @@
 // Verifies that "CFI Canonical Jump Tables" module flag is added.
 //
-// ignore-windows
 // needs-sanitizer-cfi
-// only-aarch64
-// only-x86_64
-// compile-flags: -Clto -Zsanitizer=cfi
+// compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
 
 #![crate_type="lib"]
 
diff --git a/src/test/codegen/sanitizer_cfi_emit_type_checks.rs b/src/test/codegen/sanitizer-cfi-emit-type-checks.rs
index 9ed0422ceff..8be5186de9e 100644
--- a/src/test/codegen/sanitizer_cfi_emit_type_checks.rs
+++ b/src/test/codegen/sanitizer-cfi-emit-type-checks.rs
@@ -1,21 +1,17 @@
 // Verifies that pointer type membership tests for indirect calls are emitted.
 //
-// ignore-windows
 // needs-sanitizer-cfi
-// only-aarch64
-// only-x86_64
-// compile-flags: -Clto -Cno-prepopulate-passes -Zsanitizer=cfi
+// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi
 
 #![crate_type="lib"]
 
 pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 {
     // CHECK-LABEL: define{{.*}}foo{{.*}}!type !{{[0-9]+}}
     // CHECK:       start:
-    // CHECK-NEXT:  %0 = bitcast i32 (i32)* %f to i8*
-    // CHECK-NEXT:  %1 = call i1 @llvm.type.test(i8* %0, metadata !"{{[[:print:]]+}}")
-    // CHECK-NEXT:  br i1 %1, label %type_test.pass, label %type_test.fail
+    // CHECK:       [[TT:%.+]] = call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"{{[[:print:]]+}}")
+    // CHECK-NEXT:  br i1 [[TT]], label %type_test.pass, label %type_test.fail
     // CHECK:       type_test.pass:
-    // CHECK-NEXT:  %2 = call i32 %f(i32 %arg)
+    // CHECK-NEXT:  {{%.+}} = call i32 %f(i32 %arg)
     // CHECK-NEXT:  br label %bb1
     // CHECK:       type_test.fail:
     // CHECK-NEXT:  call void @llvm.trap()
diff --git a/src/test/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs b/src/test/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs
new file mode 100644
index 00000000000..ece2adbdf43
--- /dev/null
+++ b/src/test/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs
@@ -0,0 +1,575 @@
+// 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
+
+#![crate_type="lib"]
+#![allow(dead_code)]
+#![allow(incomplete_features)]
+#![allow(unused_must_use)]
+#![feature(adt_const_params, extern_types, inline_const, type_alias_impl_trait)]
+
+extern crate core;
+use core::ffi::c_void;
+use std::marker::PhantomData;
+
+// User-defined type (structure)
+pub struct Struct1<T> {
+    member1: T,
+}
+
+// User-defined type (enum)
+pub enum Enum1<T> {
+    Variant1(T),
+}
+
+// User-defined type (union)
+pub union Union1<T> {
+    member1: std::mem::ManuallyDrop<T>,
+}
+
+// Extern type
+extern {
+    pub type type1;
+}
+
+// Trait
+pub trait Trait1<T> {
+    fn foo(&self) { }
+}
+
+// Trait implementation
+impl<T> Trait1<T> for i32 {
+    fn foo(&self) { }
+}
+
+// Trait implementation
+impl<T> Trait1<T> for Struct1<T> {
+    fn foo(&self) { }
+}
+
+// impl Trait type aliases for helping with defining other types (see below)
+pub type Type1 = impl Send;
+pub type Type2 = impl Send;
+pub type Type3 = impl Send;
+pub type Type4 = impl Send;
+pub type Type5 = impl Send;
+pub type Type6 = impl Send;
+pub type Type7 = impl Send;
+pub type Type8 = impl Send;
+pub type Type9 = impl Send;
+pub type Type10 = impl Send;
+pub type Type11 = impl Send;
+
+pub fn fn1<'a>() {
+    // Closure
+    let closure1 = || { };
+    let _: Type1 = closure1;
+
+    // Constructor
+    pub struct Foo(i32);
+    let _: Type2 = Foo;
+
+    // Type in extern path
+    extern {
+        fn foo();
+    }
+    let _: Type3 = foo;
+
+    // Type in closure path
+    || {
+        pub struct Foo;
+        let _: Type4 = Foo;
+    };
+
+    // Type in const path
+    const {
+        pub struct Foo;
+        fn foo() -> Type5 { Foo }
+    };
+
+    // Type in impl path
+    impl<T> Struct1<T> {
+        fn foo(&self) { }
+    }
+    let _: Type6 = <Struct1<i32>>::foo;
+
+    // Trait method
+    let _: Type7 = <dyn Trait1<i32>>::foo;
+
+    // Trait method
+    let _: Type8 = <i32 as Trait1<i32>>::foo;
+
+    // Trait method
+    let _: Type9 = <Struct1<i32> as Trait1<i32>>::foo;
+
+    // Const generics
+    pub struct Qux<T, const N: usize>([T; N]);
+    let _: Type10 = Qux([0; 32]);
+
+    // Lifetimes/regions
+    pub struct Quux<'a>(&'a i32);
+    pub struct Quuux<'a, 'b>(&'a i32, &'b Quux<'b>);
+    let _: Type11 = Quuux;
+}
+
+// repr(transparent) user-defined type
+struct Foo(i32);
+
+#[repr(transparent)]
+pub struct Type12 {
+    member1: (),
+    member2: PhantomData<i32>,
+    member3: Foo,
+}
+
+// Self-referencing repr(transparent) user-defined type
+#[repr(transparent)]
+pub struct Type13<'a> {
+    member1: (),
+    member2: PhantomData<i32>,
+    member3: &'a Type13<'a>,
+}
+
+pub fn foo0(_: ()) { }
+// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]]
+pub fn foo1(_: c_void, _: ()) { }
+// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]]
+pub fn foo2(_: (), _: c_void, _: c_void) { }
+// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]]
+pub fn foo3(_: *mut c_void) { }
+// CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3:[0-9]+]]
+pub fn foo4(_: *mut c_void, _: *mut ()) { }
+// CHECK: define{{.*}}foo4{{.*}}!type ![[TYPE4:[0-9]+]]
+pub fn foo5(_: *mut (), _: *mut c_void, _: *mut c_void) { }
+// CHECK: define{{.*}}foo5{{.*}}!type ![[TYPE5:[0-9]+]]
+pub fn foo6(_: *const c_void) { }
+// CHECK: define{{.*}}foo6{{.*}}!type ![[TYPE6:[0-9]+]]
+pub fn foo7(_: *const c_void, _: *const ()) { }
+// CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]]
+pub fn foo8(_: *const (), _: *const c_void, _: *const c_void) { }
+// CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]]
+pub fn foo9(_: bool) { }
+// CHECK: define{{.*}}foo9{{.*}}!type ![[TYPE9:[0-9]+]]
+pub fn foo10(_: bool, _: bool) { }
+// CHECK: define{{.*}}foo10{{.*}}!type ![[TYPE10:[0-9]+]]
+pub fn foo11(_: bool, _: bool, _: bool) { }
+// CHECK: define{{.*}}foo11{{.*}}!type ![[TYPE11:[0-9]+]]
+pub fn foo12(_: i8) { }
+// CHECK: define{{.*}}foo12{{.*}}!type ![[TYPE12:[0-9]+]]
+pub fn foo13(_: i8, _: i8) { }
+// CHECK: define{{.*}}foo13{{.*}}!type ![[TYPE13:[0-9]+]]
+pub fn foo14(_: i8, _: i8, _: i8) { }
+// CHECK: define{{.*}}foo14{{.*}}!type ![[TYPE14:[0-9]+]]
+pub fn foo15(_: i16) { }
+// CHECK: define{{.*}}foo15{{.*}}!type ![[TYPE15:[0-9]+]]
+pub fn foo16(_: i16, _: i16) { }
+// CHECK: define{{.*}}foo16{{.*}}!type ![[TYPE16:[0-9]+]]
+pub fn foo17(_: i16, _: i16, _: i16) { }
+// CHECK: define{{.*}}foo17{{.*}}!type ![[TYPE17:[0-9]+]]
+pub fn foo18(_: i32) { }
+// CHECK: define{{.*}}foo18{{.*}}!type ![[TYPE18:[0-9]+]]
+pub fn foo19(_: i32, _: i32) { }
+// CHECK: define{{.*}}foo19{{.*}}!type ![[TYPE19:[0-9]+]]
+pub fn foo20(_: i32, _: i32, _: i32) { }
+// CHECK: define{{.*}}foo20{{.*}}!type ![[TYPE20:[0-9]+]]
+pub fn foo21(_: i64) { }
+// CHECK: define{{.*}}foo21{{.*}}!type ![[TYPE21:[0-9]+]]
+pub fn foo22(_: i64, _: i64) { }
+// CHECK: define{{.*}}foo22{{.*}}!type ![[TYPE22:[0-9]+]]
+pub fn foo23(_: i64, _: i64, _: i64) { }
+// CHECK: define{{.*}}foo23{{.*}}!type ![[TYPE23:[0-9]+]]
+pub fn foo24(_: i128) { }
+// CHECK: define{{.*}}foo24{{.*}}!type ![[TYPE24:[0-9]+]]
+pub fn foo25(_: i128, _: i128) { }
+// CHECK: define{{.*}}foo25{{.*}}!type ![[TYPE25:[0-9]+]]
+pub fn foo26(_: i128, _: i128, _: i128) { }
+// CHECK: define{{.*}}foo26{{.*}}!type ![[TYPE26:[0-9]+]]
+pub fn foo27(_: isize) { }
+// CHECK: define{{.*}}foo27{{.*}}!type ![[TYPE27:[0-9]+]]
+pub fn foo28(_: isize, _: isize) { }
+// CHECK: define{{.*}}foo28{{.*}}!type ![[TYPE28:[0-9]+]]
+pub fn foo29(_: isize, _: isize, _: isize) { }
+// CHECK: define{{.*}}foo29{{.*}}!type ![[TYPE29:[0-9]+]]
+pub fn foo30(_: u8) { }
+// CHECK: define{{.*}}foo30{{.*}}!type ![[TYPE30:[0-9]+]]
+pub fn foo31(_: u8, _: u8) { }
+// CHECK: define{{.*}}foo31{{.*}}!type ![[TYPE31:[0-9]+]]
+pub fn foo32(_: u8, _: u8, _: u8) { }
+// CHECK: define{{.*}}foo32{{.*}}!type ![[TYPE32:[0-9]+]]
+pub fn foo33(_: u16) { }
+// CHECK: define{{.*}}foo33{{.*}}!type ![[TYPE33:[0-9]+]]
+pub fn foo34(_: u16, _: u16) { }
+// CHECK: define{{.*}}foo34{{.*}}!type ![[TYPE34:[0-9]+]]
+pub fn foo35(_: u16, _: u16, _: u16) { }
+// CHECK: define{{.*}}foo35{{.*}}!type ![[TYPE35:[0-9]+]]
+pub fn foo36(_: u32) { }
+// CHECK: define{{.*}}foo36{{.*}}!type ![[TYPE36:[0-9]+]]
+pub fn foo37(_: u32, _: u32) { }
+// CHECK: define{{.*}}foo37{{.*}}!type ![[TYPE37:[0-9]+]]
+pub fn foo38(_: u32, _: u32, _: u32) { }
+// CHECK: define{{.*}}foo38{{.*}}!type ![[TYPE38:[0-9]+]]
+pub fn foo39(_: u64) { }
+// CHECK: define{{.*}}foo39{{.*}}!type ![[TYPE39:[0-9]+]]
+pub fn foo40(_: u64, _: u64) { }
+// CHECK: define{{.*}}foo40{{.*}}!type ![[TYPE40:[0-9]+]]
+pub fn foo41(_: u64, _: u64, _: u64) { }
+// CHECK: define{{.*}}foo41{{.*}}!type ![[TYPE41:[0-9]+]]
+pub fn foo42(_: u128) { }
+// CHECK: define{{.*}}foo42{{.*}}!type ![[TYPE42:[0-9]+]]
+pub fn foo43(_: u128, _: u128) { }
+// CHECK: define{{.*}}foo43{{.*}}!type ![[TYPE43:[0-9]+]]
+pub fn foo44(_: u128, _: u128, _: u128) { }
+// CHECK: define{{.*}}foo44{{.*}}!type ![[TYPE44:[0-9]+]]
+pub fn foo45(_: usize) { }
+// CHECK: define{{.*}}foo45{{.*}}!type ![[TYPE45:[0-9]+]]
+pub fn foo46(_: usize, _: usize) { }
+// CHECK: define{{.*}}foo46{{.*}}!type ![[TYPE46:[0-9]+]]
+pub fn foo47(_: usize, _: usize, _: usize) { }
+// CHECK: define{{.*}}foo47{{.*}}!type ![[TYPE47:[0-9]+]]
+pub fn foo48(_: f32) { }
+// CHECK: define{{.*}}foo48{{.*}}!type ![[TYPE48:[0-9]+]]
+pub fn foo49(_: f32, _: f32) { }
+// CHECK: define{{.*}}foo49{{.*}}!type ![[TYPE49:[0-9]+]]
+pub fn foo50(_: f32, _: f32, _: f32) { }
+// CHECK: define{{.*}}foo50{{.*}}!type ![[TYPE50:[0-9]+]]
+pub fn foo51(_: f64) { }
+// CHECK: define{{.*}}foo51{{.*}}!type ![[TYPE51:[0-9]+]]
+pub fn foo52(_: f64, _: f64) { }
+// CHECK: define{{.*}}foo52{{.*}}!type ![[TYPE52:[0-9]+]]
+pub fn foo53(_: f64, _: f64, _: f64) { }
+// CHECK: define{{.*}}foo53{{.*}}!type ![[TYPE53:[0-9]+]]
+pub fn foo54(_: char) { }
+// CHECK: define{{.*}}foo54{{.*}}!type ![[TYPE54:[0-9]+]]
+pub fn foo55(_: char, _: char) { }
+// CHECK: define{{.*}}foo55{{.*}}!type ![[TYPE55:[0-9]+]]
+pub fn foo56(_: char, _: char, _: char) { }
+// CHECK: define{{.*}}foo56{{.*}}!type ![[TYPE56:[0-9]+]]
+pub fn foo57(_: &str) { }
+// CHECK: define{{.*}}foo57{{.*}}!type ![[TYPE57:[0-9]+]]
+pub fn foo58(_: &str, _: &str) { }
+// CHECK: define{{.*}}foo58{{.*}}!type ![[TYPE58:[0-9]+]]
+pub fn foo59(_: &str, _: &str, _: &str) { }
+// CHECK: define{{.*}}foo59{{.*}}!type ![[TYPE59:[0-9]+]]
+pub fn foo60(_: (i32, i32)) { }
+// CHECK: define{{.*}}foo60{{.*}}!type ![[TYPE60:[0-9]+]]
+pub fn foo61(_: (i32, i32), _: (i32, i32)) { }
+// CHECK: define{{.*}}foo61{{.*}}!type ![[TYPE61:[0-9]+]]
+pub fn foo62(_: (i32, i32), _: (i32, i32), _: (i32, i32)) { }
+// CHECK: define{{.*}}foo62{{.*}}!type ![[TYPE62:[0-9]+]]
+pub fn foo63(_: [i32; 32]) { }
+// CHECK: define{{.*}}foo63{{.*}}!type ![[TYPE63:[0-9]+]]
+pub fn foo64(_: [i32; 32], _: [i32; 32]) { }
+// CHECK: define{{.*}}foo64{{.*}}!type ![[TYPE64:[0-9]+]]
+pub fn foo65(_: [i32; 32], _: [i32; 32], _: [i32; 32]) { }
+// CHECK: define{{.*}}foo65{{.*}}!type ![[TYPE65:[0-9]+]]
+pub fn foo66(_: &[i32]) { }
+// CHECK: define{{.*}}foo66{{.*}}!type ![[TYPE66:[0-9]+]]
+pub fn foo67(_: &[i32], _: &[i32]) { }
+// CHECK: define{{.*}}foo67{{.*}}!type ![[TYPE67:[0-9]+]]
+pub fn foo68(_: &[i32], _: &[i32], _: &[i32]) { }
+// CHECK: define{{.*}}foo68{{.*}}!type ![[TYPE68:[0-9]+]]
+pub fn foo69(_: &Struct1::<i32>) { }
+// CHECK: define{{.*}}foo69{{.*}}!type ![[TYPE69:[0-9]+]]
+pub fn foo70(_: &Struct1::<i32>, _: &Struct1::<i32>) { }
+// CHECK: define{{.*}}foo70{{.*}}!type ![[TYPE70:[0-9]+]]
+pub fn foo71(_: &Struct1::<i32>, _: &Struct1::<i32>, _: &Struct1::<i32>) { }
+// CHECK: define{{.*}}foo71{{.*}}!type ![[TYPE71:[0-9]+]]
+pub fn foo72(_: &Enum1::<i32>) { }
+// CHECK: define{{.*}}foo72{{.*}}!type ![[TYPE72:[0-9]+]]
+pub fn foo73(_: &Enum1::<i32>, _: &Enum1::<i32>) { }
+// CHECK: define{{.*}}foo73{{.*}}!type ![[TYPE73:[0-9]+]]
+pub fn foo74(_: &Enum1::<i32>, _: &Enum1::<i32>, _: &Enum1::<i32>) { }
+// CHECK: define{{.*}}foo74{{.*}}!type ![[TYPE74:[0-9]+]]
+pub fn foo75(_: &Union1::<i32>) { }
+// CHECK: define{{.*}}foo75{{.*}}!type ![[TYPE75:[0-9]+]]
+pub fn foo76(_: &Union1::<i32>, _: &Union1::<i32>) { }
+// CHECK: define{{.*}}foo76{{.*}}!type ![[TYPE76:[0-9]+]]
+pub fn foo77(_: &Union1::<i32>, _: &Union1::<i32>, _: &Union1::<i32>) { }
+// CHECK: define{{.*}}foo77{{.*}}!type ![[TYPE77:[0-9]+]]
+pub fn foo78(_: *mut type1) { }
+// CHECK: define{{.*}}foo78{{.*}}!type ![[TYPE78:[0-9]+]]
+pub fn foo79(_: *mut type1, _: *mut type1) { }
+// CHECK: define{{.*}}foo79{{.*}}!type ![[TYPE79:[0-9]+]]
+pub fn foo80(_: *mut type1, _: *mut type1, _: *mut type1) { }
+// CHECK: define{{.*}}foo80{{.*}}!type ![[TYPE80:[0-9]+]]
+pub fn foo81(_: &mut i32) { }
+// CHECK: define{{.*}}foo81{{.*}}!type ![[TYPE81:[0-9]+]]
+pub fn foo82(_: &mut i32, _: &i32) { }
+// CHECK: define{{.*}}foo82{{.*}}!type ![[TYPE82:[0-9]+]]
+pub fn foo83(_: &mut i32, _: &i32, _: &i32) { }
+// CHECK: define{{.*}}foo83{{.*}}!type ![[TYPE83:[0-9]+]]
+pub fn foo84(_: &i32) { }
+// CHECK: define{{.*}}foo84{{.*}}!type ![[TYPE84:[0-9]+]]
+pub fn foo85(_: &i32, _: &mut i32) { }
+// CHECK: define{{.*}}foo85{{.*}}!type ![[TYPE85:[0-9]+]]
+pub fn foo86(_: &i32, _: &mut i32, _: &mut i32) { }
+// CHECK: define{{.*}}foo86{{.*}}!type ![[TYPE86:[0-9]+]]
+pub fn foo87(_: *mut i32) { }
+// CHECK: define{{.*}}foo87{{.*}}!type ![[TYPE87:[0-9]+]]
+pub fn foo88(_: *mut i32, _: *const i32) { }
+// CHECK: define{{.*}}foo88{{.*}}!type ![[TYPE88:[0-9]+]]
+pub fn foo89(_: *mut i32, _: *const i32, _: *const i32) { }
+// CHECK: define{{.*}}foo89{{.*}}!type ![[TYPE89:[0-9]+]]
+pub fn foo90(_: *const i32) { }
+// CHECK: define{{.*}}foo90{{.*}}!type ![[TYPE90:[0-9]+]]
+pub fn foo91(_: *const i32, _: *mut i32) { }
+// CHECK: define{{.*}}foo91{{.*}}!type ![[TYPE91:[0-9]+]]
+pub fn foo92(_: *const i32, _: *mut i32, _: *mut i32) { }
+// CHECK: define{{.*}}foo92{{.*}}!type ![[TYPE92:[0-9]+]]
+pub fn foo93(_: fn(i32) -> i32) { }
+// CHECK: define{{.*}}foo93{{.*}}!type ![[TYPE93:[0-9]+]]
+pub fn foo94(_: fn(i32) -> i32, _: fn(i32) -> i32) { }
+// CHECK: define{{.*}}foo94{{.*}}!type ![[TYPE94:[0-9]+]]
+pub fn foo95(_: fn(i32) -> i32, _: fn(i32) -> i32, _: fn(i32) -> i32) { }
+// CHECK: define{{.*}}foo95{{.*}}!type ![[TYPE95:[0-9]+]]
+pub fn foo96(_: &dyn Fn(i32) -> i32) { }
+// CHECK: define{{.*}}foo96{{.*}}!type ![[TYPE96:[0-9]+]]
+pub fn foo97(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) { }
+// CHECK: define{{.*}}foo97{{.*}}!type ![[TYPE97:[0-9]+]]
+pub fn foo98(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) { }
+// CHECK: define{{.*}}foo98{{.*}}!type ![[TYPE98:[0-9]+]]
+pub fn foo99(_: &dyn FnMut(i32) -> i32) { }
+// CHECK: define{{.*}}foo99{{.*}}!type ![[TYPE99:[0-9]+]]
+pub fn foo100(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) { }
+// CHECK: define{{.*}}foo100{{.*}}!type ![[TYPE100:[0-9]+]]
+pub fn foo101(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) { }
+// CHECK: define{{.*}}foo101{{.*}}!type ![[TYPE101:[0-9]+]]
+pub fn foo102(_: &dyn FnOnce(i32) -> i32) { }
+// CHECK: define{{.*}}foo102{{.*}}!type ![[TYPE102:[0-9]+]]
+pub fn foo103(_: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32) { }
+// CHECK: define{{.*}}foo103{{.*}}!type ![[TYPE103:[0-9]+]]
+pub fn foo104(_: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32) {}
+// CHECK: define{{.*}}foo104{{.*}}!type ![[TYPE104:[0-9]+]]
+pub fn foo105(_: &dyn Send) { }
+// CHECK: define{{.*}}foo105{{.*}}!type ![[TYPE105:[0-9]+]]
+pub fn foo106(_: &dyn Send, _: &dyn Send) { }
+// CHECK: define{{.*}}foo106{{.*}}!type ![[TYPE106:[0-9]+]]
+pub fn foo107(_: &dyn Send, _: &dyn Send, _: &dyn Send) { }
+// CHECK: define{{.*}}foo107{{.*}}!type ![[TYPE107:[0-9]+]]
+pub fn foo108(_: Type1) { }
+// CHECK: define{{.*}}foo108{{.*}}!type ![[TYPE108:[0-9]+]]
+pub fn foo109(_: Type1, _: Type1) { }
+// CHECK: define{{.*}}foo109{{.*}}!type ![[TYPE109:[0-9]+]]
+pub fn foo110(_: Type1, _: Type1, _: Type1) { }
+// CHECK: define{{.*}}foo110{{.*}}!type ![[TYPE110:[0-9]+]]
+pub fn foo111(_: Type2) { }
+// CHECK: define{{.*}}foo111{{.*}}!type ![[TYPE111:[0-9]+]]
+pub fn foo112(_: Type2, _: Type2) { }
+// CHECK: define{{.*}}foo112{{.*}}!type ![[TYPE112:[0-9]+]]
+pub fn foo113(_: Type2, _: Type2, _: Type2) { }
+// CHECK: define{{.*}}foo113{{.*}}!type ![[TYPE113:[0-9]+]]
+pub fn foo114(_: Type3) { }
+// CHECK: define{{.*}}foo114{{.*}}!type ![[TYPE114:[0-9]+]]
+pub fn foo115(_: Type3, _: Type3) { }
+// CHECK: define{{.*}}foo115{{.*}}!type ![[TYPE115:[0-9]+]]
+pub fn foo116(_: Type3, _: Type3, _: Type3) { }
+// CHECK: define{{.*}}foo116{{.*}}!type ![[TYPE116:[0-9]+]]
+pub fn foo117(_: Type4) { }
+// CHECK: define{{.*}}foo117{{.*}}!type ![[TYPE117:[0-9]+]]
+pub fn foo118(_: Type4, _: Type4) { }
+// CHECK: define{{.*}}foo118{{.*}}!type ![[TYPE118:[0-9]+]]
+pub fn foo119(_: Type4, _: Type4, _: Type4) { }
+// CHECK: define{{.*}}foo119{{.*}}!type ![[TYPE119:[0-9]+]]
+pub fn foo120(_: Type5) { }
+// CHECK: define{{.*}}foo120{{.*}}!type ![[TYPE120:[0-9]+]]
+pub fn foo121(_: Type5, _: Type5) { }
+// CHECK: define{{.*}}foo121{{.*}}!type ![[TYPE121:[0-9]+]]
+pub fn foo122(_: Type5, _: Type5, _: Type5) { }
+// CHECK: define{{.*}}foo122{{.*}}!type ![[TYPE122:[0-9]+]]
+pub fn foo123(_: Type6) { }
+// CHECK: define{{.*}}foo123{{.*}}!type ![[TYPE123:[0-9]+]]
+pub fn foo124(_: Type6, _: Type6) { }
+// CHECK: define{{.*}}foo124{{.*}}!type ![[TYPE124:[0-9]+]]
+pub fn foo125(_: Type6, _: Type6, _: Type6) { }
+// CHECK: define{{.*}}foo125{{.*}}!type ![[TYPE125:[0-9]+]]
+pub fn foo126(_: Type7) { }
+// CHECK: define{{.*}}foo126{{.*}}!type ![[TYPE126:[0-9]+]]
+pub fn foo127(_: Type7, _: Type7) { }
+// CHECK: define{{.*}}foo127{{.*}}!type ![[TYPE127:[0-9]+]]
+pub fn foo128(_: Type7, _: Type7, _: Type7) { }
+// CHECK: define{{.*}}foo128{{.*}}!type ![[TYPE128:[0-9]+]]
+pub fn foo129(_: Type8) { }
+// CHECK: define{{.*}}foo129{{.*}}!type ![[TYPE129:[0-9]+]]
+pub fn foo130(_: Type8, _: Type8) { }
+// CHECK: define{{.*}}foo130{{.*}}!type ![[TYPE130:[0-9]+]]
+pub fn foo131(_: Type8, _: Type8, _: Type8) { }
+// CHECK: define{{.*}}foo131{{.*}}!type ![[TYPE131:[0-9]+]]
+pub fn foo132(_: Type9) { }
+// CHECK: define{{.*}}foo132{{.*}}!type ![[TYPE132:[0-9]+]]
+pub fn foo133(_: Type9, _: Type9) { }
+// CHECK: define{{.*}}foo133{{.*}}!type ![[TYPE133:[0-9]+]]
+pub fn foo134(_: Type9, _: Type9, _: Type9) { }
+// CHECK: define{{.*}}foo134{{.*}}!type ![[TYPE134:[0-9]+]]
+pub fn foo135(_: Type10) { }
+// CHECK: define{{.*}}foo135{{.*}}!type ![[TYPE135:[0-9]+]]
+pub fn foo136(_: Type10, _: Type10) { }
+// CHECK: define{{.*}}foo136{{.*}}!type ![[TYPE136:[0-9]+]]
+pub fn foo137(_: Type10, _: Type10, _: Type10) { }
+// CHECK: define{{.*}}foo137{{.*}}!type ![[TYPE137:[0-9]+]]
+pub fn foo138(_: Type11) { }
+// CHECK: define{{.*}}foo138{{.*}}!type ![[TYPE138:[0-9]+]]
+pub fn foo139(_: Type11, _: Type11) { }
+// CHECK: define{{.*}}foo139{{.*}}!type ![[TYPE139:[0-9]+]]
+pub fn foo140(_: Type11, _: Type11, _: Type11) { }
+// CHECK: define{{.*}}foo140{{.*}}!type ![[TYPE140:[0-9]+]]
+pub fn foo141(_: Type12) { }
+// CHECK: define{{.*}}foo141{{.*}}!type ![[TYPE141:[0-9]+]]
+pub fn foo142(_: Type12, _: Type12) { }
+// CHECK: define{{.*}}foo142{{.*}}!type ![[TYPE142:[0-9]+]]
+pub fn foo143(_: Type12, _: Type12, _: Type12) { }
+// CHECK: define{{.*}}foo143{{.*}}!type ![[TYPE143:[0-9]+]]
+pub fn foo144(_: Type13) { }
+// CHECK: define{{.*}}foo144{{.*}}!type ![[TYPE144:[0-9]+]]
+pub fn foo145(_: Type13, _: Type13) { }
+// CHECK: define{{.*}}foo145{{.*}}!type ![[TYPE145:[0-9]+]]
+pub fn foo146(_: Type13, _: Type13, _: Type13) { }
+// CHECK: define{{.*}}foo146{{.*}}!type ![[TYPE146:[0-9]+]]
+
+// CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFvvE"}
+// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvvvE"}
+// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvvvvE"}
+// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvPvE"}
+// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvPvS_E"}
+// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvPvS_S_E"}
+// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvPKvE"}
+// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvPKvS0_E"}
+// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvPKvS0_S0_E"}
+// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvbE"}
+// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvbbE"}
+// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvbbbE"}
+// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu2i8E"}
+// CHECK: ![[TYPE13]] = !{i64 0, !"_ZTSFvu2i8S_E"}
+// CHECK: ![[TYPE14]] = !{i64 0, !"_ZTSFvu2i8S_S_E"}
+// CHECK: ![[TYPE15]] = !{i64 0, !"_ZTSFvu3i16E"}
+// CHECK: ![[TYPE16]] = !{i64 0, !"_ZTSFvu3i16S_E"}
+// CHECK: ![[TYPE17]] = !{i64 0, !"_ZTSFvu3i16S_S_E"}
+// CHECK: ![[TYPE18]] = !{i64 0, !"_ZTSFvu3i32E"}
+// CHECK: ![[TYPE19]] = !{i64 0, !"_ZTSFvu3i32S_E"}
+// CHECK: ![[TYPE20]] = !{i64 0, !"_ZTSFvu3i32S_S_E"}
+// CHECK: ![[TYPE21]] = !{i64 0, !"_ZTSFvu3i64E"}
+// CHECK: ![[TYPE22]] = !{i64 0, !"_ZTSFvu3i64S_E"}
+// CHECK: ![[TYPE23]] = !{i64 0, !"_ZTSFvu3i64S_S_E"}
+// CHECK: ![[TYPE24]] = !{i64 0, !"_ZTSFvu4i128E"}
+// CHECK: ![[TYPE25]] = !{i64 0, !"_ZTSFvu4i128S_E"}
+// CHECK: ![[TYPE26]] = !{i64 0, !"_ZTSFvu4i128S_S_E"}
+// CHECK: ![[TYPE27]] = !{i64 0, !"_ZTSFvu5isizeE"}
+// CHECK: ![[TYPE28]] = !{i64 0, !"_ZTSFvu5isizeS_E"}
+// CHECK: ![[TYPE29]] = !{i64 0, !"_ZTSFvu5isizeS_S_E"}
+// CHECK: ![[TYPE30]] = !{i64 0, !"_ZTSFvu2u8E"}
+// CHECK: ![[TYPE31]] = !{i64 0, !"_ZTSFvu2u8S_E"}
+// CHECK: ![[TYPE32]] = !{i64 0, !"_ZTSFvu2u8S_S_E"}
+// CHECK: ![[TYPE33]] = !{i64 0, !"_ZTSFvu3u16E"}
+// CHECK: ![[TYPE34]] = !{i64 0, !"_ZTSFvu3u16S_E"}
+// CHECK: ![[TYPE35]] = !{i64 0, !"_ZTSFvu3u16S_S_E"}
+// CHECK: ![[TYPE36]] = !{i64 0, !"_ZTSFvu3u32E"}
+// CHECK: ![[TYPE37]] = !{i64 0, !"_ZTSFvu3u32S_E"}
+// CHECK: ![[TYPE38]] = !{i64 0, !"_ZTSFvu3u32S_S_E"}
+// CHECK: ![[TYPE39]] = !{i64 0, !"_ZTSFvu3u64E"}
+// CHECK: ![[TYPE40]] = !{i64 0, !"_ZTSFvu3u64S_E"}
+// CHECK: ![[TYPE41]] = !{i64 0, !"_ZTSFvu3u64S_S_E"}
+// CHECK: ![[TYPE42]] = !{i64 0, !"_ZTSFvu4u128E"}
+// CHECK: ![[TYPE43]] = !{i64 0, !"_ZTSFvu4u128S_E"}
+// CHECK: ![[TYPE44]] = !{i64 0, !"_ZTSFvu4u128S_S_E"}
+// CHECK: ![[TYPE45]] = !{i64 0, !"_ZTSFvu5usizeE"}
+// CHECK: ![[TYPE46]] = !{i64 0, !"_ZTSFvu5usizeS_E"}
+// CHECK: ![[TYPE47]] = !{i64 0, !"_ZTSFvu5usizeS_S_E"}
+// CHECK: ![[TYPE48]] = !{i64 0, !"_ZTSFvu3f32E"}
+// CHECK: ![[TYPE49]] = !{i64 0, !"_ZTSFvu3f32S_E"}
+// CHECK: ![[TYPE50]] = !{i64 0, !"_ZTSFvu3f32S_S_E"}
+// CHECK: ![[TYPE51]] = !{i64 0, !"_ZTSFvu3f64E"}
+// CHECK: ![[TYPE52]] = !{i64 0, !"_ZTSFvu3f64S_E"}
+// CHECK: ![[TYPE53]] = !{i64 0, !"_ZTSFvu3f64S_S_E"}
+// CHECK: ![[TYPE54]] = !{i64 0, !"_ZTSFvu4charE"}
+// CHECK: ![[TYPE55]] = !{i64 0, !"_ZTSFvu4charS_E"}
+// CHECK: ![[TYPE56]] = !{i64 0, !"_ZTSFvu4charS_S_E"}
+// CHECK: ![[TYPE57]] = !{i64 0, !"_ZTSFvu3refIu3strEE"}
+// CHECK: ![[TYPE58]] = !{i64 0, !"_ZTSFvu3refIu3strES0_E"}
+// CHECK: ![[TYPE59]] = !{i64 0, !"_ZTSFvu3refIu3strES0_S0_E"}
+// CHECK: ![[TYPE60]] = !{i64 0, !"_ZTSFvu5tupleIu3i32S_EE"}
+// CHECK: ![[TYPE61]] = !{i64 0, !"_ZTSFvu5tupleIu3i32S_ES0_E"}
+// CHECK: ![[TYPE62]] = !{i64 0, !"_ZTSFvu5tupleIu3i32S_ES0_S0_E"}
+// CHECK: ![[TYPE63]] = !{i64 0, !"_ZTSFvA32u3i32E"}
+// CHECK: ![[TYPE64]] = !{i64 0, !"_ZTSFvA32u3i32S0_E"}
+// CHECK: ![[TYPE65]] = !{i64 0, !"_ZTSFvA32u3i32S0_S0_E"}
+// CHECK: ![[TYPE66]] = !{i64 0, !"_ZTSFvu3refIu5sliceIu3i32EEE"}
+// CHECK: ![[TYPE67]] = !{i64 0, !"_ZTSFvu3refIu5sliceIu3i32EES1_E"}
+// CHECK: ![[TYPE68]] = !{i64 0, !"_ZTSFvu3refIu5sliceIu3i32EES1_S1_E"}
+// CHECK: ![[TYPE69]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi7Struct1Iu3i32EEE"}
+// CHECK: ![[TYPE70]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi7Struct1Iu3i32EES1_E"}
+// CHECK: ![[TYPE71]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi7Struct1Iu3i32EES1_S1_E"}
+// CHECK: ![[TYPE72]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi5Enum1Iu3i32EEE"}
+// CHECK: ![[TYPE73]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi5Enum1Iu3i32EES1_E"}
+// CHECK: ![[TYPE74]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi5Enum1Iu3i32EES1_S1_E"}
+// CHECK: ![[TYPE75]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Union1Iu3i32EEE"}
+// CHECK: ![[TYPE76]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Union1Iu3i32EES1_E"}
+// CHECK: ![[TYPE77]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Union1Iu3i32EES1_S1_E"}
+// CHECK: ![[TYPE78]] = !{i64 0, !"_ZTSFvP5type1E"}
+// CHECK: ![[TYPE79]] = !{i64 0, !"_ZTSFvP5type1S0_E"}
+// CHECK: ![[TYPE80]] = !{i64 0, !"_ZTSFvP5type1S0_S0_E"}
+// CHECK: ![[TYPE81]] = !{i64 0, !"_ZTSFvU3mutu3refIu3i32EE"}
+// CHECK: ![[TYPE82]] = !{i64 0, !"_ZTSFvU3mutu3refIu3i32ES0_E"}
+// CHECK: ![[TYPE83]] = !{i64 0, !"_ZTSFvU3mutu3refIu3i32ES0_S0_E"}
+// CHECK: ![[TYPE84]] = !{i64 0, !"_ZTSFvu3refIu3i32EE"}
+// CHECK: ![[TYPE85]] = !{i64 0, !"_ZTSFvu3refIu3i32EU3mutS0_E"}
+// CHECK: ![[TYPE86]] = !{i64 0, !"_ZTSFvu3refIu3i32EU3mutS0_S1_E"}
+// CHECK: ![[TYPE87]] = !{i64 0, !"_ZTSFvPu3i32E"}
+// CHECK: ![[TYPE88]] = !{i64 0, !"_ZTSFvPu3i32PKS_E"}
+// CHECK: ![[TYPE89]] = !{i64 0, !"_ZTSFvPu3i32PKS_S2_E"}
+// CHECK: ![[TYPE90]] = !{i64 0, !"_ZTSFvPKu3i32E"}
+// CHECK: ![[TYPE91]] = !{i64 0, !"_ZTSFvPKu3i32PS_E"}
+// CHECK: ![[TYPE92]] = !{i64 0, !"_ZTSFvPKu3i32PS_S2_E"}
+// CHECK: ![[TYPE93]] = !{i64 0, !"_ZTSFvPFu3i32S_EE"}
+// CHECK: ![[TYPE94]] = !{i64 0, !"_ZTSFvPFu3i32S_ES0_E"}
+// CHECK: ![[TYPE95]] = !{i64 0, !"_ZTSFvPFu3i32S_ES0_S0_E"}
+// CHECK: ![[TYPE96]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEEE"}
+// CHECK: ![[TYPE97]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_E"}
+// CHECK: ![[TYPE98]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_S5_E"}
+// CHECK: ![[TYPE99]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEEE"}
+// CHECK: ![[TYPE100]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_E"}
+// CHECK: ![[TYPE101]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_S5_E"}
+// CHECK: ![[TYPE102]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEEE"}
+// CHECK: ![[TYPE103]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_E"}
+// CHECK: ![[TYPE104]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_S5_E"}
+// CHECK: ![[TYPE105]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEEE"}
+// CHECK: ![[TYPE106]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEES2_E"}
+// CHECK: ![[TYPE107]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEES2_S2_E"}
+// CHECK: ![[TYPE108]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NCNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn111{{[{}][{}]}}closure{{[}][}]}}Iu2i8PFvvEvEE"}
+// CHECK: ![[TYPE109]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NCNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn111{{[{}][{}]}}closure{{[}][}]}}Iu2i8PFvvEvES1_E"}
+// CHECK: ![[TYPE110]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NCNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn111{{[{}][{}]}}closure{{[}][}]}}Iu2i8PFvvEvES1_S1_E"}
+// CHECK: ![[TYPE111]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn13Foo15{{[{}][{}]}}constructor{{[}][}]}}E"}
+// CHECK: ![[TYPE112]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn13Foo15{{[{}][{}]}}constructor{{[}][}]}}S_E"}
+// CHECK: ![[TYPE113]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn13Foo15{{[{}][{}]}}constructor{{[}][}]}}S_S_E"}
+// CHECK: ![[TYPE114]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn110{{[{}][{}]}}extern{{[}][}]}}3fooE"}
+// CHECK: ![[TYPE115]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn110{{[{}][{}]}}extern{{[}][}]}}3fooS_E"}
+// CHECK: ![[TYPE116]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn110{{[{}][{}]}}extern{{[}][}]}}3fooS_S_E"}
+// CHECK: ![[TYPE117]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn1s0_11{{[{}][{}]}}closure{{[}][}]}}3FooE"}
+// CHECK: ![[TYPE118]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn1s0_11{{[{}][{}]}}closure{{[}][}]}}3FooS_E"}
+// CHECK: ![[TYPE119]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn1s0_11{{[{}][{}]}}closure{{[}][}]}}3FooS_S_E"}
+// CHECK: ![[TYPE120]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn112{{[{}][{}]}}constant{{[}][}]}}3FooE"}
+// CHECK: ![[TYPE121]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn112{{[{}][{}]}}constant{{[}][}]}}3FooS_E"}
+// CHECK: ![[TYPE122]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn112{{[{}][{}]}}constant{{[}][}]}}3FooS_S_E"}
+// CHECK: ![[TYPE123]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn18{{[{}][{}]}}impl{{[}][}]}}3fooIu3i32EE"}
+// CHECK: ![[TYPE124]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn18{{[{}][{}]}}impl{{[}][}]}}3fooIu3i32ES0_E"}
+// CHECK: ![[TYPE125]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn18{{[{}][{}]}}impl{{[}][}]}}3fooIu3i32ES0_S0_E"}
+// CHECK: ![[TYPE126]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait1Iu3i32Eu6regionES_EE"}
+// CHECK: ![[TYPE127]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait1Iu3i32Eu6regionES_ES3_E"}
+// CHECK: ![[TYPE128]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait1Iu3i32Eu6regionES_ES3_S3_E"}
+// CHECK: ![[TYPE129]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3i32S_EE"}
+// CHECK: ![[TYPE130]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3i32S_ES0_E"}
+// CHECK: ![[TYPE131]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3i32S_ES0_S0_E"}
+// CHECK: ![[TYPE132]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi7Struct1Iu3i32ES_EE"}
+// CHECK: ![[TYPE133]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi7Struct1Iu3i32ES_ES1_E"}
+// CHECK: ![[TYPE134]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi7Struct1Iu3i32ES_ES1_S1_E"}
+// CHECK: ![[TYPE135]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn13QuxIu3i32Lu5usize32EEE"}
+// CHECK: ![[TYPE136]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn13QuxIu3i32Lu5usize32EES2_E"}
+// CHECK: ![[TYPE137]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn13QuxIu3i32Lu5usize32EES2_S2_E"}
+// CHECK: ![[TYPE138]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn15Quuux15{{[{}][{}]}}constructor{{[}][}]}}Iu6regionS_EE"}
+// CHECK: ![[TYPE139]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn15Quuux15{{[{}][{}]}}constructor{{[}][}]}}Iu6regionS_ES0_E"}
+// CHECK: ![[TYPE140]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn15Quuux15{{[{}][{}]}}constructor{{[}][}]}}Iu6regionS_ES0_S0_E"}
+// CHECK: ![[TYPE141]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3FooE"}
+// CHECK: ![[TYPE142]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3FooS_E"}
+// CHECK: ![[TYPE143]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3FooS_S_E"}
+// CHECK: ![[TYPE144]] = !{i64 0, !"_ZTSFvu3refIu3refIvEEE"}
+// CHECK: ![[TYPE145]] = !{i64 0, !"_ZTSFvu3refIu3refIvEES0_E"}
+// CHECK: ![[TYPE146]] = !{i64 0, !"_ZTSFvu3refIu3refIvEES0_S0_E"}
diff --git a/src/test/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi.rs b/src/test/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi.rs
new file mode 100644
index 00000000000..bafc4c6592f
--- /dev/null
+++ b/src/test/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi.rs
@@ -0,0 +1,31 @@
+// Verifies that type metadata for functions are emitted.
+//
+// needs-sanitizer-cfi
+// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi
+
+#![crate_type="lib"]
+
+pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 {
+    // CHECK-LABEL: define{{.*}}foo
+    // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]]
+    // CHECK:       call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_E")
+    f(arg)
+}
+
+pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 {
+    // CHECK-LABEL: define{{.*}}bar
+    // CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]]
+    // CHECK:       call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E")
+    f(arg1, arg2)
+}
+
+pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 {
+    // CHECK-LABEL: define{{.*}}baz
+    // CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]]
+    // CHECK:       call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E")
+    f(arg1, arg2, arg3)
+}
+
+// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu3i32PFS_S_ES_E"}
+// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu3i32PFS_S_S_ES_S_E"}
+// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFu3i32PFS_S_S_S_ES_S_S_E"}
diff --git a/src/test/codegen/sanitizer_cfi_emit_type_metadata.rs b/src/test/codegen/sanitizer_cfi_emit_type_metadata.rs
deleted file mode 100644
index 96fced47e78..00000000000
--- a/src/test/codegen/sanitizer_cfi_emit_type_metadata.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Verifies that type metadata for functions are emitted.
-//
-// ignore-windows
-// needs-sanitizer-cfi
-// only-aarch64
-// only-x86_64
-// compile-flags: -Clto -Cno-prepopulate-passes -Zsanitizer=cfi
-
-#![crate_type="lib"]
-
-pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 {
-    // CHECK-LABEL: define{{.*}}foo{{.*}}!type !{{[0-9]+}}
-    // CHECK:       %1 = call i1 @llvm.type.test(i8* %0, metadata !"typeid1")
-    f(arg)
-}
-
-pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 {
-    // CHECK-LABEL: define{{.*}}bar{{.*}}!type !{{[0-9]+}}
-    // CHECK:       %1 = call i1 @llvm.type.test(i8* %0, metadata !"typeid2")
-    f(arg1, arg2)
-}
-
-pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 {
-    // CHECK-LABEL: define{{.*}}baz{{.*}}!type !{{[0-9]+}}
-    // CHECK:       %1 = call i1 @llvm.type.test(i8* %0, metadata !"typeid3")
-    f(arg1, arg2, arg3)
-}
-
-// CHECK: !{{[0-9]+}} = !{i64 0, !"typeid2"}
-// CHECK: !{{[0-9]+}} = !{i64 0, !"typeid3"}
-// CHECK: !{{[0-9]+}} = !{i64 0, !"typeid4"}
diff --git a/src/test/codegen/sanitizer_scs_attr_check.rs b/src/test/codegen/sanitizer_scs_attr_check.rs
new file mode 100644
index 00000000000..0b53db3b767
--- /dev/null
+++ b/src/test/codegen/sanitizer_scs_attr_check.rs
@@ -0,0 +1,17 @@
+// This tests that the shadowcallstack attribute is
+// applied when enabling the shadow-call-stack sanitizer.
+//
+// needs-sanitizer-shadow-call-stack
+// compile-flags: -Zsanitizer=shadow-call-stack
+
+#![crate_type = "lib"]
+#![feature(no_sanitize)]
+
+// CHECK: ; Function Attrs:{{.*}}shadowcallstack
+// CHECK-NEXT: scs
+pub fn scs() {}
+
+// CHECK-NOT: ; Function Attrs:{{.*}}shadowcallstack
+// CHECK-NEXT: no_scs
+#[no_sanitize(shadow_call_stack)]
+pub fn no_scs() {}
diff --git a/src/test/codegen/simd-wide-sum.rs b/src/test/codegen/simd-wide-sum.rs
index 015ac4fe4d1..04314dc291a 100644
--- a/src/test/codegen/simd-wide-sum.rs
+++ b/src/test/codegen/simd-wide-sum.rs
@@ -5,7 +5,7 @@
 #![crate_type = "lib"]
 #![feature(portable_simd)]
 
-use std::simd::Simd;
+use std::simd::{Simd, SimdUint};
 const N: usize = 8;
 
 #[no_mangle]
diff --git a/src/test/codegen/vec-calloc-llvm14.rs b/src/test/codegen/vec-calloc-llvm14.rs
new file mode 100644
index 00000000000..08302796c41
--- /dev/null
+++ b/src/test/codegen/vec-calloc-llvm14.rs
@@ -0,0 +1,144 @@
+// compile-flags: -O
+// only-x86_64
+// ignore-debug
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @vec_zero_bytes
+#[no_mangle]
+pub fn vec_zero_bytes(n: usize) -> Vec<u8> {
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+    // CHECK-NOT: call {{.*}}llvm.memset
+
+    // CHECK: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+    // CHECK-NOT: call {{.*}}llvm.memset
+
+    // CHECK: ret void
+    vec![0; n]
+}
+
+// CHECK-LABEL: @vec_one_bytes
+#[no_mangle]
+pub fn vec_one_bytes(n: usize) -> Vec<u8> {
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK: call {{.*}}__rust_alloc(
+    // CHECK: call {{.*}}llvm.memset
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK: ret void
+    vec![1; n]
+}
+
+// CHECK-LABEL: @vec_zero_scalar
+#[no_mangle]
+pub fn vec_zero_scalar(n: usize) -> Vec<i32> {
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: ret void
+    vec![0; n]
+}
+
+// CHECK-LABEL: @vec_one_scalar
+#[no_mangle]
+pub fn vec_one_scalar(n: usize) -> Vec<i32> {
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK: call {{.*}}__rust_alloc(
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK: ret void
+    vec![1; n]
+}
+
+// CHECK-LABEL: @vec_zero_rgb48
+#[no_mangle]
+pub fn vec_zero_rgb48(n: usize) -> Vec<[u16; 3]> {
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: ret void
+    vec![[0, 0, 0]; n]
+}
+
+// CHECK-LABEL: @vec_zero_array_16
+#[no_mangle]
+pub fn vec_zero_array_16(n: usize) -> Vec<[i64; 16]> {
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: ret void
+    vec![[0_i64; 16]; n]
+}
+
+// CHECK-LABEL: @vec_zero_tuple
+#[no_mangle]
+pub fn vec_zero_tuple(n: usize) -> Vec<(i16, u8, char)> {
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: ret void
+    vec![(0, 0, '\0'); n]
+}
+
+// CHECK-LABEL: @vec_non_zero_tuple
+#[no_mangle]
+pub fn vec_non_zero_tuple(n: usize) -> Vec<(i16, u8, char)> {
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK: call {{.*}}__rust_alloc(
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK: ret void
+    vec![(0, 0, 'A'); n]
+}
diff --git a/src/test/codegen/vec-calloc.rs b/src/test/codegen/vec-calloc.rs
index c616e9f1145..435a4ab5187 100644
--- a/src/test/codegen/vec-calloc.rs
+++ b/src/test/codegen/vec-calloc.rs
@@ -1,32 +1,150 @@
 // compile-flags: -O
 // only-x86_64
 // ignore-debug
+// min-llvm-version: 15.0
 
 #![crate_type = "lib"]
 
+// CHECK-LABEL: @vec_zero_bytes
+#[no_mangle]
+pub fn vec_zero_bytes(n: usize) -> Vec<u8> {
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+    // CHECK-NOT: call {{.*}}llvm.memset
+
+    // CHECK: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+    // CHECK-NOT: call {{.*}}llvm.memset
+
+    // CHECK: ret void
+    vec![0; n]
+}
+
+// CHECK-LABEL: @vec_one_bytes
+#[no_mangle]
+pub fn vec_one_bytes(n: usize) -> Vec<u8> {
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK: call {{.*}}__rust_alloc(
+    // CHECK: call {{.*}}llvm.memset
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK: ret void
+    vec![1; n]
+}
+
 // CHECK-LABEL: @vec_zero_scalar
 #[no_mangle]
 pub fn vec_zero_scalar(n: usize) -> Vec<i32> {
-    // CHECK-NOT: __rust_alloc(
-    // CHECK: __rust_alloc_zeroed(
-    // CHECK-NOT: __rust_alloc(
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: ret void
     vec![0; n]
 }
 
+// CHECK-LABEL: @vec_one_scalar
+#[no_mangle]
+pub fn vec_one_scalar(n: usize) -> Vec<i32> {
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK: call {{.*}}__rust_alloc(
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK: ret void
+    vec![1; n]
+}
+
 // CHECK-LABEL: @vec_zero_rgb48
 #[no_mangle]
 pub fn vec_zero_rgb48(n: usize) -> Vec<[u16; 3]> {
-    // CHECK-NOT: __rust_alloc(
-    // CHECK: __rust_alloc_zeroed(
-    // CHECK-NOT: __rust_alloc(
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: ret void
     vec![[0, 0, 0]; n]
 }
 
-// CHECK-LABEL: @vec_zero_array_32
+// CHECK-LABEL: @vec_zero_array_16
 #[no_mangle]
-pub fn vec_zero_array_32(n: usize) -> Vec<[i64; 32]> {
-    // CHECK-NOT: __rust_alloc(
-    // CHECK: __rust_alloc_zeroed(
-    // CHECK-NOT: __rust_alloc(
-    vec![[0_i64; 32]; n]
+pub fn vec_zero_array_16(n: usize) -> Vec<[i64; 16]> {
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: ret void
+    vec![[0_i64; 16]; n]
 }
+
+// CHECK-LABEL: @vec_zero_tuple
+#[no_mangle]
+pub fn vec_zero_tuple(n: usize) -> Vec<(i16, u8, char)> {
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc(
+
+    // CHECK: ret void
+    vec![(0, 0, '\0'); n]
+}
+
+// CHECK-LABEL: @vec_non_zero_tuple
+#[no_mangle]
+pub fn vec_non_zero_tuple(n: usize) -> Vec<(i16, u8, char)> {
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK: call {{.*}}__rust_alloc(
+
+    // CHECK-NOT: call {{.*}}alloc::vec::from_elem
+    // CHECK-NOT: call {{.*}}reserve
+    // CHECK-NOT: call {{.*}}__rust_alloc_zeroed(
+
+    // CHECK: ret void
+    vec![(0, 0, 'A'); n]
+}
+
+// Ensure that __rust_alloc_zeroed gets the right attributes for LLVM to optimize it away.
+// CHECK: declare noalias ptr @__rust_alloc_zeroed(i64, i64 allocalign) unnamed_addr [[RUST_ALLOC_ZEROED_ATTRS:#[0-9]+]]
+
+// CHECK-DAG: attributes [[RUST_ALLOC_ZEROED_ATTRS]] = { {{.*}} allockind("alloc,zeroed,aligned") allocsize(0) uwtable "alloc-family"="__rust_alloc" {{.*}} }