about summary refs log tree commit diff
path: root/tests/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'tests/codegen')
-rw-r--r--tests/codegen/asm-maybe-uninit.rs27
-rw-r--r--tests/codegen/box-uninit-bytes.rs (renamed from tests/codegen/box-maybe-uninit.rs)14
-rw-r--r--tests/codegen/cold-call-declare-and-call.rs13
-rw-r--r--tests/codegen/debuginfo-inline-callsite-location.rs28
-rw-r--r--tests/codegen/issues/issue-115385-llvm-jump-threading.rs46
-rw-r--r--tests/codegen/lib-optimizations/iter-sum.rs15
-rw-r--r--tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs4
-rw-r--r--tests/codegen/mem-replace-simple-type.rs21
-rw-r--r--tests/codegen/move-before-nocapture-ref-arg.rs22
-rw-r--r--tests/codegen/repr/transparent.rs1
-rw-r--r--tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs43
-rw-r--r--tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs12
-rw-r--r--tests/codegen/slice-as_chunks.rs6
-rw-r--r--tests/codegen/slice-iter-nonnull.rs6
-rw-r--r--tests/codegen/sroa-fragment-debuginfo.rs46
-rw-r--r--tests/codegen/swap-small-types.rs33
-rw-r--r--tests/codegen/tuple-layout-opt.rs1
17 files changed, 305 insertions, 33 deletions
diff --git a/tests/codegen/asm-maybe-uninit.rs b/tests/codegen/asm-maybe-uninit.rs
new file mode 100644
index 00000000000..d7e4a948954
--- /dev/null
+++ b/tests/codegen/asm-maybe-uninit.rs
@@ -0,0 +1,27 @@
+// compile-flags: -O
+// only-x86_64
+
+#![crate_type = "rlib"]
+#![allow(asm_sub_register)]
+
+use std::mem::MaybeUninit;
+use std::arch::asm;
+
+// CHECK-LABEL: @int
+#[no_mangle]
+pub unsafe fn int(x: MaybeUninit<i32>) -> MaybeUninit<i32> {
+    let y: MaybeUninit<i32>;
+    asm!("/*{}{}*/", in(reg) x, out(reg) y);
+    y
+}
+
+// CHECK-LABEL: @inout
+#[no_mangle]
+pub unsafe fn inout(mut x: i32) -> MaybeUninit<u32> {
+    let mut y: MaybeUninit<u32>;
+    asm!("/*{}*/", inout(reg) x => y);
+    asm!("/*{}*/", inout(reg) y => x);
+    asm!("/*{}*/", inlateout(reg) x => y);
+    asm!("/*{}*/", inlateout(reg) y => x);
+    y
+}
diff --git a/tests/codegen/box-maybe-uninit.rs b/tests/codegen/box-uninit-bytes.rs
index 282af99b067..732da0a1794 100644
--- a/tests/codegen/box-maybe-uninit.rs
+++ b/tests/codegen/box-uninit-bytes.rs
@@ -25,6 +25,20 @@ pub fn box_uninitialized2() -> Box<MaybeUninit<[usize; 1024 * 1024]>> {
     Box::new(MaybeUninit::uninit())
 }
 
+#[repr(align(1024))]
+pub struct LotsaPadding(usize);
+
+// Boxing a value with padding should not copy junk from the stack
+#[no_mangle]
+pub fn box_lotsa_padding() -> Box<LotsaPadding> {
+    // CHECK-LABEL: @box_lotsa_padding
+    // CHECK-NOT: alloca
+    // CHECK-NOT: getelementptr
+    // CHECK-NOT: memcpy
+    // CHECK-NOT: memset
+    Box::new(LotsaPadding(42))
+}
+
 // 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 {{(dso_local )?}}noalias noundef ptr @__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+}} allocalign noundef) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]]
diff --git a/tests/codegen/cold-call-declare-and-call.rs b/tests/codegen/cold-call-declare-and-call.rs
index 71d49478bfc..572dc407f51 100644
--- a/tests/codegen/cold-call-declare-and-call.rs
+++ b/tests/codegen/cold-call-declare-and-call.rs
@@ -1,12 +1,21 @@
+// revisions: NORMAL WINDOWS
 // compile-flags: -C no-prepopulate-passes
+//[NORMAL] ignore-windows
+//[WINDOWS] only-windows
+//[WINDOWS] only-x86_64
 
 #![crate_type = "lib"]
 #![feature(rust_cold_cc)]
 
 // wasm marks the definition as `dso_local`, so allow that as optional.
 
-// CHECK: define{{( dso_local)?}} coldcc void @this_should_never_happen(i16
-// CHECK: call coldcc void @this_should_never_happen(i16
+// NORMAL: define{{( dso_local)?}} preserve_mostcc void @this_should_never_happen(i16
+// NORMAL: call preserve_mostcc void @this_should_never_happen(i16
+
+// See the comment in `Target::adjust_abi` for why this differs
+
+// WINDOWS: define void @this_should_never_happen(i16
+// WINDOWS: call void @this_should_never_happen(i16
 
 #[no_mangle]
 pub extern "rust-cold" fn this_should_never_happen(x: u16) {}
diff --git a/tests/codegen/debuginfo-inline-callsite-location.rs b/tests/codegen/debuginfo-inline-callsite-location.rs
new file mode 100644
index 00000000000..b1475ee7931
--- /dev/null
+++ b/tests/codegen/debuginfo-inline-callsite-location.rs
@@ -0,0 +1,28 @@
+// compile-flags: -g -O
+
+// Check that each inline call site for the same function uses the same "sub-program" so that LLVM
+// can correctly merge the debug info if it merges the inlined code (e.g., for merging of tail
+// calls to panic.
+
+// CHECK:       tail call void @_ZN4core9panicking5panic17h{{([0-9a-z]{16})}}E
+// CHECK-SAME:  !dbg ![[#first_dbg:]]
+// CHECK:       tail call void @_ZN4core9panicking5panic17h{{([0-9a-z]{16})}}E
+// CHECK-SAME:  !dbg ![[#second_dbg:]]
+
+// CHECK-DAG:   ![[#func_dbg:]] = distinct !DISubprogram(name: "unwrap<i32>"
+// CHECK-DAG:   ![[#first_scope:]] = distinct !DILexicalBlock(scope: ![[#func_dbg]],
+// CHECK:       ![[#second_scope:]] = distinct !DILexicalBlock(scope: ![[#func_dbg]],
+// CHECK:       ![[#first_dbg]] = !DILocation(line: [[#]]
+// CHECK-SAME:  scope: ![[#first_scope]], inlinedAt: ![[#]])
+// CHECK:       ![[#second_dbg]] = !DILocation(line: [[#]]
+// CHECK-SAME:  scope: ![[#second_scope]], inlinedAt: ![[#]])
+
+#![crate_type = "lib"]
+
+#[no_mangle]
+extern "C" fn add_numbers(x: &Option<i32>, y: &Option<i32>) -> i32 {
+    let x1 = x.unwrap();
+    let y1 = y.unwrap();
+
+    x1 + y1
+}
diff --git a/tests/codegen/issues/issue-115385-llvm-jump-threading.rs b/tests/codegen/issues/issue-115385-llvm-jump-threading.rs
new file mode 100644
index 00000000000..142e3596d96
--- /dev/null
+++ b/tests/codegen/issues/issue-115385-llvm-jump-threading.rs
@@ -0,0 +1,46 @@
+// compile-flags: -O -Ccodegen-units=1
+
+#![crate_type = "lib"]
+
+#[repr(i64)]
+pub enum Boolean {
+    False = 0,
+    True = 1,
+}
+
+impl Clone for Boolean {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+impl Copy for Boolean {}
+
+extern "C" {
+    fn set_value(foo: *mut i64);
+    fn bar();
+}
+
+pub fn foo(x: bool) {
+    let mut foo = core::mem::MaybeUninit::<i64>::uninit();
+    unsafe {
+        set_value(foo.as_mut_ptr());
+    }
+
+    if x {
+        let l1 = unsafe { *foo.as_mut_ptr().cast::<Boolean>() };
+        if matches!(l1, Boolean::False) {
+            unsafe {
+                *foo.as_mut_ptr() = 0;
+            }
+        }
+    }
+
+    let l2 = unsafe { *foo.as_mut_ptr() };
+    if l2 == 2 {
+        // CHECK: call void @bar
+        unsafe {
+            bar();
+        }
+    }
+}
diff --git a/tests/codegen/lib-optimizations/iter-sum.rs b/tests/codegen/lib-optimizations/iter-sum.rs
new file mode 100644
index 00000000000..ff7ca6ef6c1
--- /dev/null
+++ b/tests/codegen/lib-optimizations/iter-sum.rs
@@ -0,0 +1,15 @@
+// ignore-debug: the debug assertions get in the way
+// compile-flags: -O
+// only-x86_64 (vectorization varies between architectures)
+#![crate_type = "lib"]
+
+
+// Ensure that slice + take + sum gets vectorized.
+// Currently this relies on the slice::Iter::try_fold implementation
+// CHECK-LABEL: @slice_take_sum
+#[no_mangle]
+pub fn slice_take_sum(s: &[u64], l: usize) -> u64 {
+    // CHECK: vector.body:
+    // CHECK: ret
+    s.iter().take(l).sum()
+}
diff --git a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs
index 7555553c2c5..591ccd45ab6 100644
--- a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs
+++ b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs
@@ -250,11 +250,11 @@ pub struct IntDoubleInt {
     c: i32,
 }
 
-// CHECK: define void @f_int_double_int_s_arg(ptr noalias nocapture noundef dereferenceable(24) %a)
+// CHECK: define void @f_int_double_int_s_arg(ptr noalias nocapture noundef align 8 dereferenceable(24) %a)
 #[no_mangle]
 pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {}
 
-// CHECK: define void @f_ret_int_double_int_s(ptr noalias nocapture noundef sret(%IntDoubleInt) dereferenceable(24) %0)
+// CHECK: define void @f_ret_int_double_int_s(ptr noalias nocapture noundef sret(%IntDoubleInt) align 8 dereferenceable(24) %_0)
 #[no_mangle]
 pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt {
     IntDoubleInt { a: 1, b: 2., c: 3 }
diff --git a/tests/codegen/mem-replace-simple-type.rs b/tests/codegen/mem-replace-simple-type.rs
index 174ac608e01..be3af989ef0 100644
--- a/tests/codegen/mem-replace-simple-type.rs
+++ b/tests/codegen/mem-replace-simple-type.rs
@@ -33,12 +33,21 @@ pub fn replace_ref_str<'a>(r: &mut &'a str, v: &'a str) -> &'a str {
 }
 
 #[no_mangle]
-// CHECK-LABEL: @replace_short_array(
-pub fn replace_short_array(r: &mut [u32; 3], v: [u32; 3]) -> [u32; 3] {
+// CHECK-LABEL: @replace_short_array_3(
+pub fn replace_short_array_3(r: &mut [u32; 3], v: [u32; 3]) -> [u32; 3] {
     // CHECK-NOT: alloca
-    // CHECK: %[[R:.+]] = load <3 x i32>, ptr %r, align 4
-    // CHECK: store <3 x i32> %[[R]], ptr %result
-    // CHECK: %[[V:.+]] = load <3 x i32>, ptr %v, align 4
-    // CHECK: store <3 x i32> %[[V]], ptr %r
+    // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %result, ptr align 4 %r, i64 12, i1 false)
+    // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %r, ptr align 4 %v, i64 12, i1 false)
+    std::mem::replace(r, v)
+}
+
+#[no_mangle]
+// CHECK-LABEL: @replace_short_array_4(
+pub fn replace_short_array_4(r: &mut [u32; 4], v: [u32; 4]) -> [u32; 4] {
+    // CHECK-NOT: alloca
+    // CHECK: %[[R:.+]] = load <4 x i32>, ptr %r, align 4
+    // CHECK: store <4 x i32> %[[R]], ptr %result
+    // CHECK: %[[V:.+]] = load <4 x i32>, ptr %v, align 4
+    // CHECK: store <4 x i32> %[[V]], ptr %r
     std::mem::replace(r, v)
 }
diff --git a/tests/codegen/move-before-nocapture-ref-arg.rs b/tests/codegen/move-before-nocapture-ref-arg.rs
new file mode 100644
index 00000000000..c7b400c8f8d
--- /dev/null
+++ b/tests/codegen/move-before-nocapture-ref-arg.rs
@@ -0,0 +1,22 @@
+// Verify that move before the call of the function with noalias, nocapture, readonly.
+// #107436
+// compile-flags: -O
+// min-llvm-version: 17
+
+#![crate_type = "lib"]
+
+#[repr(C)]
+pub struct ThreeSlices<'a>(&'a [u32], &'a [u32], &'a [u32]);
+
+#[no_mangle]
+pub fn sum_slices(val: ThreeSlices) -> u32 {
+    // CHECK-NOT: memcpy
+    let val = val;
+    sum(&val)
+}
+
+#[no_mangle]
+#[inline(never)]
+pub fn sum(val: &ThreeSlices) -> u32 {
+    val.0.iter().sum::<u32>() + val.1.iter().sum::<u32>() + val.2.iter().sum::<u32>()
+}
diff --git a/tests/codegen/repr/transparent.rs b/tests/codegen/repr/transparent.rs
index b140fc719da..c5974248bb3 100644
--- a/tests/codegen/repr/transparent.rs
+++ b/tests/codegen/repr/transparent.rs
@@ -43,7 +43,6 @@ pub extern "C" fn test_WithZst(_: WithZst) -> WithZst { loop {} }
 #[repr(transparent)]
 pub struct WithZeroSizedArray(*const f32, [i8; 0]);
 
-// Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever.
 // CHECK: define{{.*}}ptr @test_WithZeroSizedArray(ptr noundef %_1)
 #[no_mangle]
 pub extern "C" fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} }
diff --git a/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs b/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs
new file mode 100644
index 00000000000..a70ef7751b6
--- /dev/null
+++ b/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs
@@ -0,0 +1,43 @@
+// Verifies that AddressSanitizer symbols show up as expected in LLVM IR with `-Zsanitizer`.
+// This is a regression test for https://github.com/rust-lang/rust/issues/113404
+//
+// Notes about the `compile-flags` below:
+//
+// * The original issue only reproed with LTO - this is why this angle has
+//   extra test coverage via different `revisions`
+// * To observe the failure/repro at LLVM-IR level we need to use `staticlib`
+//   which necessitates `-C prefer-dynamic=false` - without the latter flag,
+//   we would have run into "cannot prefer dynamic linking when performing LTO".
+//
+// The test is restricted to `only-linux`, because the sanitizer-related instrumentation is target
+// specific.  In particular, `___asan_globals_registered` is only used in the
+// `InstrumentGlobalsELF` and `InstrumentGlobalsMachO` code paths.  The `only-linux` filter is
+// narrower than really needed (i.e. narrower than ELF-or-MachO), but this seems ok - having a
+// linux-only regression test should be sufficient here.
+//
+// needs-sanitizer-address
+// only-linux
+//
+// revisions:ASAN ASAN-FAT-LTO
+//[ASAN]          compile-flags: -Zsanitizer=address
+//[ASAN-FAT-LTO]  compile-flags: -Zsanitizer=address -Cprefer-dynamic=false -Clto=fat
+
+#![crate_type="staticlib"]
+
+// The test below mimics `CACHED_POW10` from `library/core/src/num/flt2dec/strategy/grisu.rs` which
+// (because of incorrect handling of `___asan_globals_registered` during LTO) was incorrectly
+// reported as an ODR violation in https://crbug.com/1459233#c1.  Before this bug was fixed,
+// `___asan_globals_registered` would show up as `internal global i64` rather than `common hidden
+// global i64`.  (The test expectations ignore the exact type because on `arm-android` the type
+// is `i32` rather than `i64`.)
+//
+// CHECK: @___asan_globals_registered = common hidden global
+// CHECK: @__start_asan_globals = extern_weak hidden global
+// CHECK: @__stop_asan_globals = extern_weak hidden global
+#[no_mangle]
+pub static CACHED_POW10: [(u64, i16, i16); 4] = [
+    (0xe61acf033d1a45df, -1087, -308),
+    (0xab70fe17c79ac6ca, -1060, -300),
+    (0xff77b1fcbebcdc4f, -1034, -292),
+    (0xbe5691ef416bd60c, -1007, -284),
+];
diff --git a/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs b/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs
index da608e180c5..2d8b13e2080 100644
--- a/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs
+++ b/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs
@@ -500,12 +500,12 @@ pub fn foo149(_: Type14<Bar>, _: Type14<Bar>, _: Type14<Bar>) { }
 // 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: ![[TYPE48]] = !{i64 0, !"_ZTSFvfE"}
+// CHECK: ![[TYPE49]] = !{i64 0, !"_ZTSFvffE"}
+// CHECK: ![[TYPE50]] = !{i64 0, !"_ZTSFvfffE"}
+// CHECK: ![[TYPE51]] = !{i64 0, !"_ZTSFvdE"}
+// CHECK: ![[TYPE52]] = !{i64 0, !"_ZTSFvddE"}
+// CHECK: ![[TYPE53]] = !{i64 0, !"_ZTSFvdddE"}
 // CHECK: ![[TYPE54]] = !{i64 0, !"_ZTSFvu4charE"}
 // CHECK: ![[TYPE55]] = !{i64 0, !"_ZTSFvu4charS_E"}
 // CHECK: ![[TYPE56]] = !{i64 0, !"_ZTSFvu4charS_S_E"}
diff --git a/tests/codegen/slice-as_chunks.rs b/tests/codegen/slice-as_chunks.rs
index 48e3f73fc86..efac9f3d68d 100644
--- a/tests/codegen/slice-as_chunks.rs
+++ b/tests/codegen/slice-as_chunks.rs
@@ -22,9 +22,9 @@ pub fn chunks4(x: &[u8]) -> &[[u8; 4]] {
 // CHECK-LABEL: @chunks4_with_remainder
 #[no_mangle]
 pub fn chunks4_with_remainder(x: &[u8]) -> (&[[u8; 4]], &[u8]) {
-    // CHECK: and i64 %x.1, -4
-    // CHECK: and i64 %x.1, 3
-    // CHECK: lshr exact
+    // CHECK-DAG: and i64 %x.1, -4
+    // CHECK-DAG: and i64 %x.1, 3
+    // CHECK-DAG: lshr
     // CHECK-NOT: mul
     // CHECK-NOT: udiv
     // CHECK-NOT: urem
diff --git a/tests/codegen/slice-iter-nonnull.rs b/tests/codegen/slice-iter-nonnull.rs
index f7d164bc856..8749226d401 100644
--- a/tests/codegen/slice-iter-nonnull.rs
+++ b/tests/codegen/slice-iter-nonnull.rs
@@ -100,13 +100,13 @@ pub fn slice_iter_is_empty(it: &std::slice::Iter<'_, u32>) -> bool {
 // CHECK-LABEL: @slice_iter_len
 #[no_mangle]
 pub fn slice_iter_len(it: &std::slice::Iter<'_, u32>) -> usize {
-    // CHECK: %[[START:.+]] = load ptr, ptr %it,
-    // CHECK-SAME: !nonnull
-    // CHECK-SAME: !noundef
     // CHECK: %[[ENDP:.+]] = getelementptr{{.+}}ptr %it,{{.+}} 1
     // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]]
     // CHECK-SAME: !nonnull
     // CHECK-SAME: !noundef
+    // CHECK: %[[START:.+]] = load ptr, ptr %it,
+    // CHECK-SAME: !nonnull
+    // CHECK-SAME: !noundef
 
     // CHECK: ptrtoint
     // CHECK: ptrtoint
diff --git a/tests/codegen/sroa-fragment-debuginfo.rs b/tests/codegen/sroa-fragment-debuginfo.rs
new file mode 100644
index 00000000000..fb10f63beaf
--- /dev/null
+++ b/tests/codegen/sroa-fragment-debuginfo.rs
@@ -0,0 +1,46 @@
+// compile-flags: -g -Zmir-opt-level=0 -Zmir-enable-passes=+ScalarReplacementOfAggregates
+// compile-flags: -Cno-prepopulate-passes
+//
+// Tested offsets are only correct for x86_64.
+// only-x86_64
+
+#![crate_type = "lib"]
+
+pub struct ExtraSlice<'input> {
+    slice: &'input [u8],
+    extra: u32,
+}
+
+#[no_mangle]
+pub fn extra(s: &[u8]) {
+// CHECK: void @extra(
+// CHECK: %slice.dbg.spill1 = alloca i32,
+// CHECK: %slice.dbg.spill = alloca { ptr, i64 },
+// CHECK: %s.dbg.spill = alloca { ptr, i64 },
+// CHECK: call void @llvm.dbg.declare(metadata ptr %s.dbg.spill, metadata ![[S_EXTRA:.*]], metadata !DIExpression()),
+// CHECK: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill, metadata ![[SLICE_EXTRA:.*]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 128)),
+// CHECK: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill1, metadata ![[SLICE_EXTRA]], metadata !DIExpression(DW_OP_LLVM_fragment, 128, 32)),
+    let slice = ExtraSlice { slice: s, extra: s.len() as u32 };
+}
+
+struct Zst;
+
+pub struct ZstSlice<'input> {
+    slice: &'input [u8],
+    extra: Zst,
+}
+
+#[no_mangle]
+pub fn zst(s: &[u8]) {
+    // The field `extra` is a ZST. The fragment for the field `slice` encompasses the whole
+    // variable, so is not a fragment. In that case, the variable must have no fragment.
+
+// CHECK: void @zst(
+// CHECK-NOT: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill, metadata !{}, metadata !DIExpression(DW_OP_LLVM_fragment,
+// CHECK: call void @llvm.dbg.declare(metadata ptr %{{.*}}, metadata ![[SLICE_ZST:.*]], metadata !DIExpression()),
+// CHECK-NOT: call void @llvm.dbg.declare(metadata ptr %{{.*}}, metadata ![[SLICE_ZST]],
+    let slice = ZstSlice { slice: s, extra: Zst };
+}
+
+// CHECK: ![[S_EXTRA]] = !DILocalVariable(name: "s",
+// CHECK: ![[SLICE_EXTRA]] = !DILocalVariable(name: "slice",
diff --git a/tests/codegen/swap-small-types.rs b/tests/codegen/swap-small-types.rs
index 419645a3fc6..27bc00bc3ab 100644
--- a/tests/codegen/swap-small-types.rs
+++ b/tests/codegen/swap-small-types.rs
@@ -11,11 +11,12 @@ type RGB48 = [u16; 3];
 // CHECK-LABEL: @swap_rgb48_manually(
 #[no_mangle]
 pub fn swap_rgb48_manually(x: &mut RGB48, y: &mut RGB48) {
-    // CHECK-NOT: alloca
-    // CHECK: %[[TEMP0:.+]] = load <3 x i16>, ptr %x, align 2
-    // CHECK: %[[TEMP1:.+]] = load <3 x i16>, ptr %y, align 2
-    // CHECK: store <3 x i16> %[[TEMP1]], ptr %x, align 2
-    // CHECK: store <3 x i16> %[[TEMP0]], ptr %y, align 2
+    // FIXME: See #115212 for why this has an alloca again
+
+    // CHECK: alloca [3 x i16], align 2
+    // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
+    // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
+    // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
 
     let temp = *x;
     *x = *y;
@@ -25,11 +26,25 @@ pub fn swap_rgb48_manually(x: &mut RGB48, y: &mut RGB48) {
 // CHECK-LABEL: @swap_rgb48
 #[no_mangle]
 pub fn swap_rgb48(x: &mut RGB48, y: &mut RGB48) {
+    // FIXME: See #115212 for why this has an alloca again
+
+    // CHECK: alloca [3 x i16], align 2
+    // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
+    // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
+    // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
+    swap(x, y)
+}
+
+type RGBA64 = [u16; 4];
+
+// CHECK-LABEL: @swap_rgba64
+#[no_mangle]
+pub fn swap_rgba64(x: &mut RGBA64, y: &mut RGBA64) {
     // CHECK-NOT: alloca
-    // CHECK: load <3 x i16>
-    // CHECK: load <3 x i16>
-    // CHECK: store <3 x i16>
-    // CHECK: store <3 x i16>
+    // CHECK-DAG: %[[XVAL:.+]] = load <4 x i16>, ptr %x, align 2
+    // CHECK-DAG: %[[YVAL:.+]] = load <4 x i16>, ptr %y, align 2
+    // CHECK-DAG: store <4 x i16> %[[YVAL]], ptr %x, align 2
+    // CHECK-DAG: store <4 x i16> %[[XVAL]], ptr %y, align 2
     swap(x, y)
 }
 
diff --git a/tests/codegen/tuple-layout-opt.rs b/tests/codegen/tuple-layout-opt.rs
index 309fe1d5ec9..7cc67a9b51c 100644
--- a/tests/codegen/tuple-layout-opt.rs
+++ b/tests/codegen/tuple-layout-opt.rs
@@ -1,4 +1,3 @@
-// ignore-emscripten
 // compile-flags: -C no-prepopulate-passes -Copt-level=0
 
 // Test that tuples get optimized layout, in particular with a ZST in the last field (#63244)