about summary refs log tree commit diff
path: root/tests/codegen
diff options
context:
space:
mode:
authorLaurențiu Nicola <lnicola@dend.ro>2024-12-11 11:49:08 +0200
committerLaurențiu Nicola <lnicola@dend.ro>2024-12-11 11:49:08 +0200
commit5db2aa865cdc4bf0634fdcbdd8d201253938f02a (patch)
tree6ba3b87d4ac3b10b67159211a493f785c76ee0fa /tests/codegen
parent1649eb6dd74507bbd9513464609fcd5a9bcc655b (diff)
parent5a6036a1802262f8cf02192b02026688d396f1d7 (diff)
downloadrust-5db2aa865cdc4bf0634fdcbdd8d201253938f02a.tar.gz
rust-5db2aa865cdc4bf0634fdcbdd8d201253938f02a.zip
Merge from rust-lang/rust
Diffstat (limited to 'tests/codegen')
-rw-r--r--tests/codegen/asm/avr-clobbers.rs43
-rw-r--r--tests/codegen/asm/powerpc-clobbers.rs13
-rw-r--r--tests/codegen/async-closure-debug.rs2
-rw-r--r--tests/codegen/avr/avr-func-addrspace.rs2
-rw-r--r--tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs4
-rw-r--r--tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs2
-rw-r--r--tests/codegen/emcripten-catch-unwind.rs2
-rw-r--r--tests/codegen/issues/issue-118306.rs2
-rw-r--r--tests/codegen/issues/issue-122805.rs14
-rw-r--r--tests/codegen/issues/issue-13018.rs5
-rw-r--r--tests/codegen/issues/issue-98678-async.rs25
-rw-r--r--tests/codegen/issues/issue-98678-closure-coroutine.rs22
-rw-r--r--tests/codegen/issues/issue-98678-enum.rs40
-rw-r--r--tests/codegen/issues/issue-98678-struct-union.rs25
-rw-r--r--tests/codegen/pattern_type_symbols.rs3
-rw-r--r--tests/codegen/reg-struct-return.rs206
-rw-r--r--tests/codegen/slice-iter-nonnull.rs12
17 files changed, 395 insertions, 27 deletions
diff --git a/tests/codegen/asm/avr-clobbers.rs b/tests/codegen/asm/avr-clobbers.rs
new file mode 100644
index 00000000000..6e0c75368e2
--- /dev/null
+++ b/tests/codegen/asm/avr-clobbers.rs
@@ -0,0 +1,43 @@
+//@ assembly-output: emit-asm
+//@ compile-flags: --target avr-unknown-gnu-atmega328
+//@ needs-llvm-components: avr
+
+#![crate_type = "rlib"]
+#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+
+// CHECK-LABEL: @sreg_is_clobbered
+// CHECK: void asm sideeffect "", "~{sreg}"()
+#[no_mangle]
+pub unsafe fn sreg_is_clobbered() {
+    asm!("", options(nostack, nomem));
+}
+
+// CHECK-LABEL: @sreg_is_not_clobbered_if_preserve_flags_is_used
+// CHECK: void asm sideeffect "", ""()
+#[no_mangle]
+pub unsafe fn sreg_is_not_clobbered_if_preserve_flags_is_used() {
+    asm!("", options(nostack, nomem, preserves_flags));
+}
+
+// CHECK-LABEL: @clobber_abi
+// CHECK: asm sideeffect "", "={r18},={r19},={r20},={r21},={r22},={r23},={r24},={r25},={r26},={r27},={r30},={r31},~{sreg}"()
+#[no_mangle]
+pub unsafe fn clobber_abi() {
+    asm!("", clobber_abi("C"), options(nostack, nomem));
+}
+
+// CHECK-LABEL: @clobber_abi_with_preserved_flags
+// CHECK: asm sideeffect "", "={r18},={r19},={r20},={r21},={r22},={r23},={r24},={r25},={r26},={r27},={r30},={r31}"()
+#[no_mangle]
+pub unsafe fn clobber_abi_with_preserved_flags() {
+    asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
+}
diff --git a/tests/codegen/asm/powerpc-clobbers.rs b/tests/codegen/asm/powerpc-clobbers.rs
index e97e8300ca7..2832377cef0 100644
--- a/tests/codegen/asm/powerpc-clobbers.rs
+++ b/tests/codegen/asm/powerpc-clobbers.rs
@@ -7,6 +7,7 @@
 //@[powerpc64le] needs-llvm-components: powerpc
 //@[aix64] compile-flags: --target powerpc64-ibm-aix
 //@[aix64] needs-llvm-components: powerpc
+// ignore-tidy-linelength
 
 #![crate_type = "rlib"]
 #![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
@@ -48,15 +49,23 @@ pub unsafe fn xer_clobber() {
     asm!("", out("xer") _, options(nostack, nomem, preserves_flags));
 }
 
+// Output format depends on the availability of altivec.
 // CHECK-LABEL: @v0_clobber
-// CHECK: call void asm sideeffect "", "~{v0}"()
+// powerpc: call void asm sideeffect "", "~{v0}"()
+// powerpc64: call <4 x i32> asm sideeffect "", "=&{v0}"()
+// powerpc64le: call <4 x i32> asm sideeffect "", "=&{v0}"()
+// aix64: call <4 x i32> asm sideeffect "", "=&{v0}"()
 #[no_mangle]
 pub unsafe fn v0_clobber() {
     asm!("", out("v0") _, options(nostack, nomem, preserves_flags));
 }
 
+// Output format depends on the availability of altivec.
 // CHECK-LABEL: @clobber_abi
-// CHECK: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
+// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
+// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
+// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
+// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
 #[no_mangle]
 pub unsafe fn clobber_abi() {
     asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
diff --git a/tests/codegen/async-closure-debug.rs b/tests/codegen/async-closure-debug.rs
index 9cb1e623295..644df169a36 100644
--- a/tests/codegen/async-closure-debug.rs
+++ b/tests/codegen/async-closure-debug.rs
@@ -9,7 +9,7 @@
 
 #![feature(async_closure)]
 
-fn async_closure_test(upvar: &str) -> impl async Fn() + '_ {
+fn async_closure_test(upvar: &str) -> impl AsyncFn() + '_ {
     async move || {
         let hello = String::from("hello");
         println!("{hello}, {upvar}");
diff --git a/tests/codegen/avr/avr-func-addrspace.rs b/tests/codegen/avr/avr-func-addrspace.rs
index a2dcb1c0924..7a36490fe93 100644
--- a/tests/codegen/avr/avr-func-addrspace.rs
+++ b/tests/codegen/avr/avr-func-addrspace.rs
@@ -86,7 +86,7 @@ pub extern "C" fn test() {
 
     // A call through the Fn trait must use address space 1.
     //
-    // CHECK: call{{.+}}addrspace(1) void @call_through_fn_trait()
+    // CHECK: call{{.+}}addrspace(1) void @call_through_fn_trait({{.*}})
     call_through_fn_trait(&mut update_bar_value);
 
     // A call through a global variable must use address space 1.
diff --git a/tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs b/tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs
index 159ecfd0974..c0691b23275 100644
--- a/tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs
+++ b/tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs
@@ -1,7 +1,3 @@
-//@ force-host
-//@ no-prefer-dynamic
-#![crate_type = "proc-macro"]
-
 extern crate proc_macro;
 use proc_macro::*;
 
diff --git a/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs b/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs
index c3858044c0c..0f6e99f9b1e 100644
--- a/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs
+++ b/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs
@@ -3,7 +3,7 @@
 // MSVC is different because of the individual allocas.
 //@ ignore-msvc
 
-//@ aux-build:macro_def.rs
+//@ proc-macro: macro_def.rs
 
 // Find the variable.
 // CHECK-DAG: ![[#var_dbg:]] = !DILocalVariable(name: "n",{{( arg: 1,)?}} scope: ![[#var_scope:]]
diff --git a/tests/codegen/emcripten-catch-unwind.rs b/tests/codegen/emcripten-catch-unwind.rs
index 35444db9558..b15fb40b68f 100644
--- a/tests/codegen/emcripten-catch-unwind.rs
+++ b/tests/codegen/emcripten-catch-unwind.rs
@@ -57,7 +57,7 @@ pub unsafe fn test_catch_unwind(
     // CHECK: [[IS_RUST_EXN_I8:%.*]] = zext i1 [[IS_RUST_EXN]] to i8
 
     // CHECK: store ptr [[EXCEPTION]], ptr [[ALLOCA]]
-    // CHECK: [[IS_RUST_SLOT:%.*]] = getelementptr inbounds i8, ptr [[ALLOCA]], [[PTR_SIZE]]
+    // CHECK: [[IS_RUST_SLOT:%.*]] = getelementptr inbounds{{( nuw)?}} i8, ptr [[ALLOCA]], [[PTR_SIZE]]
     // CHECK: store i8 [[IS_RUST_EXN_I8]], ptr [[IS_RUST_SLOT]]
 
     // CHECK: call void %catch_fn(ptr %data, ptr nonnull [[ALLOCA]])
diff --git a/tests/codegen/issues/issue-118306.rs b/tests/codegen/issues/issue-118306.rs
index 8af1c6a971c..0778ab3fde9 100644
--- a/tests/codegen/issues/issue-118306.rs
+++ b/tests/codegen/issues/issue-118306.rs
@@ -12,7 +12,7 @@ pub fn branchy(input: u64) -> u64 {
     // CHECK-LABEL: @branchy(
     // CHECK-NEXT:  start:
     // CHECK-NEXT:    [[_2:%.*]] = and i64 [[INPUT:%.*]], 3
-    // CHECK-NEXT:    [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i64], ptr @switch.table.branchy, i64 0, i64 [[_2]]
+    // CHECK-NEXT:    [[SWITCH_GEP:%.*]] = getelementptr inbounds{{( nuw)?}} [4 x i64], ptr @switch.table.branchy, i64 0, i64 [[_2]]
     // CHECK-NEXT:    [[SWITCH_LOAD:%.*]] = load i64, ptr [[SWITCH_GEP]]
     // CHECK-NEXT:    ret i64 [[SWITCH_LOAD]]
     match input % 4 {
diff --git a/tests/codegen/issues/issue-122805.rs b/tests/codegen/issues/issue-122805.rs
index 8e03c6c8884..16dae801ee4 100644
--- a/tests/codegen/issues/issue-122805.rs
+++ b/tests/codegen/issues/issue-122805.rs
@@ -17,19 +17,19 @@
 // CHECK-LABEL: define{{.*}}void @convert(
 // CHECK-NOT: shufflevector
 // OPT2: store i16
-// OPT2-NEXT: getelementptr inbounds i8, {{.+}} 2
+// OPT2-NEXT: getelementptr inbounds{{( nuw)?}} i8, {{.+}} 2
 // OPT2-NEXT: store i16
-// OPT2-NEXT: getelementptr inbounds i8, {{.+}} 4
+// OPT2-NEXT: getelementptr inbounds{{( nuw)?}} i8, {{.+}} 4
 // OPT2-NEXT: store i16
-// OPT2-NEXT: getelementptr inbounds i8, {{.+}} 6
+// OPT2-NEXT: getelementptr inbounds{{( nuw)?}} i8, {{.+}} 6
 // OPT2-NEXT: store i16
-// OPT2-NEXT: getelementptr inbounds i8, {{.+}} 8
+// OPT2-NEXT: getelementptr inbounds{{( nuw)?}} i8, {{.+}} 8
 // OPT2-NEXT: store i16
-// OPT2-NEXT: getelementptr inbounds i8, {{.+}} 10
+// OPT2-NEXT: getelementptr inbounds{{( nuw)?}} i8, {{.+}} 10
 // OPT2-NEXT: store i16
-// OPT2-NEXT: getelementptr inbounds i8, {{.+}} 12
+// OPT2-NEXT: getelementptr inbounds{{( nuw)?}} i8, {{.+}} 12
 // OPT2-NEXT: store i16
-// OPT2-NEXT: getelementptr inbounds i8, {{.+}} 14
+// OPT2-NEXT: getelementptr inbounds{{( nuw)?}} i8, {{.+}} 14
 // OPT2-NEXT: store i16
 // OPT3LINX64: load <8 x i16>
 // OPT3LINX64-NEXT: call <8 x i16> @llvm.bswap
diff --git a/tests/codegen/issues/issue-13018.rs b/tests/codegen/issues/issue-13018.rs
index 66282dc4274..a29452436d2 100644
--- a/tests/codegen/issues/issue-13018.rs
+++ b/tests/codegen/issues/issue-13018.rs
@@ -2,7 +2,10 @@
 
 // A drop([...].clone()) sequence on an Rc should be a no-op
 // In particular, no call to __rust_dealloc should be emitted
-#![crate_type = "lib"]
+//
+// We use a cdylib since it's a leaf unit for Rust purposes, so doesn't codegen -Zshare-generics
+// code.
+#![crate_type = "cdylib"]
 use std::rc::Rc;
 
 pub fn foo(t: &Rc<Vec<usize>>) {
diff --git a/tests/codegen/issues/issue-98678-async.rs b/tests/codegen/issues/issue-98678-async.rs
new file mode 100644
index 00000000000..75f5d82eee5
--- /dev/null
+++ b/tests/codegen/issues/issue-98678-async.rs
@@ -0,0 +1,25 @@
+// This test verifies the accuracy of emitted file and line debuginfo metadata for async blocks and
+// async functions.
+//
+//@ edition:2021
+//@ compile-flags: --crate-type=lib -Copt-level=0 -Cdebuginfo=2 -Zdebug-info-type-line-numbers=true
+
+// ignore-tidy-linelength
+
+// NONMSVC-DAG: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*[/\\]}}issue-98678-async.rs{{".*}})
+// MSVC: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*}}\\issue-98678-async.rs{{".*}})
+
+// NONMSVC-DAG: !DISubprogram(name: "foo",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]],
+// MSVC-DAG: !DISubprogram(name: "foo",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+pub async fn foo() -> u8 {
+    5
+}
+
+pub fn bar() -> impl std::future::Future<Output = u8> {
+    // NONMSVC: !DICompositeType({{.*"}}{async_block_env#0}{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]],
+    // MSVC-DAG: !DICompositeType({{.*"}}enum2$<issue_98678_async::bar::async_block_env$0>{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+    async {
+        let x: u8 = foo().await;
+        x + 5
+    }
+}
diff --git a/tests/codegen/issues/issue-98678-closure-coroutine.rs b/tests/codegen/issues/issue-98678-closure-coroutine.rs
new file mode 100644
index 00000000000..0730e56bf31
--- /dev/null
+++ b/tests/codegen/issues/issue-98678-closure-coroutine.rs
@@ -0,0 +1,22 @@
+// This test verifies the accuracy of emitted file and line debuginfo metadata for closures and
+// coroutines.
+//
+//@ compile-flags: --crate-type=lib -Copt-level=0 -Cdebuginfo=2 -Zdebug-info-type-line-numbers=true
+#![feature(coroutines, stmt_expr_attributes)]
+
+// ignore-tidy-linelength
+
+// NONMSVC-DAG: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*[/\\]}}issue-98678-closure-coroutine.rs{{".*}})
+// MSVC-DAG: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*}}\\issue-98678-closure-coroutine.rs{{".*}})
+
+pub fn foo() {
+    // NONMSVC-DAG: !DICompositeType({{.*"}}{closure_env#0}{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]],
+    // MSVC-DAG: !DICompositeType({{.*"}}closure_env$0{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+    let closure = |x| x;
+    closure(0);
+
+    // NONMSVC-DAG: !DICompositeType({{.*"[{]}}coroutine_env#1{{[}]".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 3]],
+    // MSVC-DAG: !DICompositeType({{.*".*foo::}}coroutine_env$1>{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]],
+    let _coroutine = #[coroutine]
+    || yield 1;
+}
diff --git a/tests/codegen/issues/issue-98678-enum.rs b/tests/codegen/issues/issue-98678-enum.rs
new file mode 100644
index 00000000000..62c6cded866
--- /dev/null
+++ b/tests/codegen/issues/issue-98678-enum.rs
@@ -0,0 +1,40 @@
+// This test verifies the accuracy of emitted file and line debuginfo metadata enums.
+//
+//@ compile-flags: --crate-type=lib -Copt-level=0 -Cdebuginfo=2 -Zdebug-info-type-line-numbers=true
+
+// ignore-tidy-linelength
+
+// NONMSVC: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*[/\\]}}issue-98678-enum.rs{{".*}})
+// MSVC: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*}}\\issue-98678-enum.rs{{".*}})
+
+// NONMSVC: !DICompositeType({{.*"}}SingleCase{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]],
+// MSVC: !DICompositeType({{.*"}}enum2$<issue_98678_enum::SingleCase>{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+pub enum SingleCase {
+    // NONMSVC: !DIDerivedType(tag: DW_TAG_member, name: "One",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]],
+    // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "One",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+    One,
+}
+
+// NONMSVC: !DICompositeType({{.*"}}MultipleDataCases{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]],
+// MSVC: !DICompositeType({{.*"}}enum2$<issue_98678_enum::MultipleDataCases>{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+pub enum MultipleDataCases {
+    // NONMSVC: !DIDerivedType(tag: DW_TAG_member, name: "Case1",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]],
+    // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Case1",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+    Case1(u32),
+    // NONMSVC: !DIDerivedType(tag: DW_TAG_member, name: "Case2",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]],
+    // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Case2",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+    Case2(i64),
+}
+
+// NONMSVC: !DICompositeType({{.*"}}NicheLayout{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]],
+// MSVC: !DICompositeType({{.*"}}enum2$<issue_98678_enum::NicheLayout>{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+pub enum NicheLayout {
+    // NONMSVC: !DIDerivedType(tag: DW_TAG_member, name: "Something",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]],
+    // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Something",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+    Something(&'static u32),
+    // NONMSVC: !DIDerivedType(tag: DW_TAG_member, name: "Nothing",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 2]],
+    // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Nothing",{{.*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+    Nothing,
+}
+
+pub fn foo(_: SingleCase, _: MultipleDataCases, _: NicheLayout) {}
diff --git a/tests/codegen/issues/issue-98678-struct-union.rs b/tests/codegen/issues/issue-98678-struct-union.rs
new file mode 100644
index 00000000000..bf2d6e731aa
--- /dev/null
+++ b/tests/codegen/issues/issue-98678-struct-union.rs
@@ -0,0 +1,25 @@
+// This test verifies the accuracy of emitted file and line debuginfo metadata for structs and
+// unions.
+//
+//@ compile-flags: --crate-type=lib -Copt-level=0 -Cdebuginfo=2 -Zdebug-info-type-line-numbers=true
+
+// ignore-tidy-linelength
+
+// NONMSVC: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*[/\\]}}issue-98678-struct-union.rs{{".*}})
+// MSVC: ![[#FILE:]] = !DIFile({{.*}}filename:{{.*}}\\issue-98678-struct-union.rs{{".*}})
+
+// CHECK: !DICompositeType({{.*"}}MyType{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+pub struct MyType {
+    // CHECK: !DIDerivedType({{.*"}}i{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+    i: i32,
+}
+
+// CHECK: !DICompositeType({{.*"}}MyUnion{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+pub union MyUnion {
+    // CHECK: !DIDerivedType({{.*"}}i{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+    i: i32,
+    // CHECK: !DIDerivedType({{.*"}}f{{".*}}file: ![[#FILE]]{{.*}}line: [[# @LINE + 1]],
+    f: f32,
+}
+
+pub fn foo(_: MyType, _: MyUnion) {}
diff --git a/tests/codegen/pattern_type_symbols.rs b/tests/codegen/pattern_type_symbols.rs
index a99b3efca41..b504a3508f9 100644
--- a/tests/codegen/pattern_type_symbols.rs
+++ b/tests/codegen/pattern_type_symbols.rs
@@ -4,8 +4,7 @@
 //@ compile-flags: -Csymbol-mangling-version=v0 -Copt-level=0 --crate-type=lib
 
 #![feature(pattern_types)]
-#![feature(core_pattern_types)]
-#![feature(core_pattern_type)]
+#![feature(pattern_type_macro)]
 
 use std::pat::pattern_type;
 
diff --git a/tests/codegen/reg-struct-return.rs b/tests/codegen/reg-struct-return.rs
new file mode 100644
index 00000000000..73816745ea8
--- /dev/null
+++ b/tests/codegen/reg-struct-return.rs
@@ -0,0 +1,206 @@
+// Checks how `reg-struct-return` flag works with different calling conventions:
+// Return struct with 8/16/32/64 bit size will be converted into i8/i16/i32/i64
+// (like abi_return_struct_as_int target spec).
+// x86 only.
+
+//@ revisions: ENABLED DISABLED
+//@ add-core-stubs
+//@ compile-flags: --target i686-unknown-linux-gnu -O -C no-prepopulate-passes
+//@ [ENABLED] compile-flags: -Zreg-struct-return
+//@ needs-llvm-components: x86
+
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+#![feature(no_core, lang_items)]
+
+extern crate minicore;
+use minicore::*;
+
+#[repr(C)]
+pub struct Foo {
+    x: u32,
+    y: u32,
+}
+
+#[repr(C)]
+pub struct Foo1 {
+    x: u32,
+}
+
+#[repr(C)]
+pub struct Foo2 {
+    x: bool,
+    y: bool,
+    z: i16,
+}
+
+#[repr(C)]
+pub struct Foo3 {
+    x: i16,
+    y: bool,
+    z: bool,
+}
+
+#[repr(C)]
+pub struct Foo4 {
+    x: char,
+    y: bool,
+    z: u8,
+}
+
+#[repr(C)]
+pub struct Foo5 {
+    x: u32,
+    y: u16,
+    z: u8,
+    a: bool,
+}
+
+#[repr(C)]
+pub struct FooOversize1 {
+    x: u32,
+    y: u32,
+    z: u32,
+}
+
+#[repr(C)]
+pub struct FooOversize2 {
+    f0: u16,
+    f1: u16,
+    f2: u16,
+    f3: u16,
+    f4: u16,
+}
+
+#[repr(C)]
+pub struct FooFloat1 {
+    x: f32,
+    y: f32,
+}
+
+#[repr(C)]
+pub struct FooFloat2 {
+    x: f64,
+}
+
+#[repr(C)]
+pub struct FooFloat3 {
+    x: f32,
+}
+
+pub mod tests {
+    use {
+        Foo, Foo1, Foo2, Foo3, Foo4, Foo5, FooFloat1, FooFloat2, FooFloat3, FooOversize1,
+        FooOversize2,
+    };
+
+    // ENABLED: i64 @f1()
+    // DISABLED: void @f1(ptr {{.*}}sret
+    #[no_mangle]
+    pub extern "fastcall" fn f1() -> Foo {
+        Foo { x: 1, y: 2 }
+    }
+
+    // CHECK: { i32, i32 } @f2()
+    #[no_mangle]
+    pub extern "Rust" fn f2() -> Foo {
+        Foo { x: 1, y: 2 }
+    }
+
+    // ENABLED: i64 @f3()
+    // DISABLED: void @f3(ptr {{.*}}sret
+    #[no_mangle]
+    pub extern "C" fn f3() -> Foo {
+        Foo { x: 1, y: 2 }
+    }
+
+    // ENABLED: i64 @f4()
+    // DISABLED: void @f4(ptr {{.*}}sret
+    #[no_mangle]
+    pub extern "cdecl" fn f4() -> Foo {
+        Foo { x: 1, y: 2 }
+    }
+
+    // ENABLED: i64 @f5()
+    // DISABLED: void @f5(ptr {{.*}}sret
+    #[no_mangle]
+    pub extern "stdcall" fn f5() -> Foo {
+        Foo { x: 1, y: 2 }
+    }
+
+    // ENABLED: i64 @f6()
+    // DISABLED: void @f6(ptr {{.*}}sret
+    #[no_mangle]
+    pub extern "thiscall" fn f6() -> Foo {
+        Foo { x: 1, y: 2 }
+    }
+
+    // ENABLED: i32 @f7()
+    // DISABLED: void @f7(ptr {{.*}}sret
+    #[no_mangle]
+    pub extern "C" fn f7() -> Foo1 {
+        Foo1 { x: 1 }
+    }
+
+    // ENABLED: i32 @f8()
+    // DISABLED: void @f8(ptr {{.*}}sret
+    #[no_mangle]
+    pub extern "C" fn f8() -> Foo2 {
+        Foo2 { x: true, y: false, z: 5 }
+    }
+
+    // ENABLED: i32 @f9()
+    // DISABLED: void @f9(ptr {{.*}}sret
+    #[no_mangle]
+    pub extern "C" fn f9() -> Foo3 {
+        Foo3 { x: 5, y: false, z: true }
+    }
+
+    // ENABLED: i64 @f10()
+    // DISABLED: void @f10(ptr {{.*}}sret
+    #[no_mangle]
+    pub extern "C" fn f10() -> Foo4 {
+        Foo4 { x: 'x', y: true, z: 170 }
+    }
+
+    // ENABLED: i64 @f11()
+    // DISABLED: void @f11(ptr {{.*}}sret
+    #[no_mangle]
+    pub extern "C" fn f11() -> Foo5 {
+        Foo5 { x: 1, y: 2, z: 3, a: true }
+    }
+
+    // CHECK: void @f12(ptr {{.*}}sret
+    #[no_mangle]
+    pub extern "C" fn f12() -> FooOversize1 {
+        FooOversize1 { x: 1, y: 2, z: 3 }
+    }
+
+    // CHECK: void @f13(ptr {{.*}}sret
+    #[no_mangle]
+    pub extern "C" fn f13() -> FooOversize2 {
+        FooOversize2 { f0: 1, f1: 2, f2: 3, f3: 4, f4: 5 }
+    }
+
+    // ENABLED: i64 @f14()
+    // DISABLED: void @f14(ptr {{.*}}sret
+    #[no_mangle]
+    pub extern "C" fn f14() -> FooFloat1 {
+        FooFloat1 { x: 1.0, y: 1.0 }
+    }
+
+    // ENABLED: double @f15()
+    // DISABLED: void @f15(ptr {{.*}}sret
+    #[no_mangle]
+    pub extern "C" fn f15() -> FooFloat2 {
+        FooFloat2 { x: 1.0 }
+    }
+
+    // ENABLED: float @f16()
+    // DISABLED: void @f16(ptr {{.*}}sret
+    #[no_mangle]
+    pub extern "C" fn f16() -> FooFloat3 {
+        FooFloat3 { x: 1.0 }
+    }
+}
diff --git a/tests/codegen/slice-iter-nonnull.rs b/tests/codegen/slice-iter-nonnull.rs
index eda807d3682..307020b42c0 100644
--- a/tests/codegen/slice-iter-nonnull.rs
+++ b/tests/codegen/slice-iter-nonnull.rs
@@ -14,7 +14,7 @@
 // CHECK-LABEL: @slice_iter_next(
 #[no_mangle]
 pub fn slice_iter_next<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32> {
-    // CHECK: %[[ENDP:.+]] = getelementptr inbounds i8, ptr %it, {{i32 4|i64 8}}
+    // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}}
     // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]]
     // CHECK-SAME: !nonnull
     // CHECK-SAME: !noundef
@@ -31,7 +31,7 @@ pub fn slice_iter_next<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32
 // CHECK-LABEL: @slice_iter_next_back(
 #[no_mangle]
 pub fn slice_iter_next_back<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32> {
-    // CHECK: %[[ENDP:.+]] = getelementptr inbounds i8, ptr %it, {{i32 4|i64 8}}
+    // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}}
     // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]]
     // CHECK-SAME: !nonnull
     // CHECK-SAME: !noundef
@@ -55,7 +55,7 @@ pub fn slice_iter_next_back<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'
 #[no_mangle]
 pub fn slice_iter_new(slice: &[u32]) -> std::slice::Iter<'_, u32> {
     // CHECK-NOT: slice
-    // CHECK: %[[END:.+]] = getelementptr inbounds i32{{.+}} %slice.0{{.+}} %slice.1
+    // CHECK: %[[END:.+]] = getelementptr inbounds{{( nuw)?}} i32{{.+}} %slice.0{{.+}} %slice.1
     // CHECK-NOT: slice
     // CHECK: insertvalue {{.+}} ptr %slice.0, 0
     // CHECK-NOT: slice
@@ -70,7 +70,7 @@ pub fn slice_iter_new(slice: &[u32]) -> std::slice::Iter<'_, u32> {
 #[no_mangle]
 pub fn slice_iter_mut_new(slice: &mut [u32]) -> std::slice::IterMut<'_, u32> {
     // CHECK-NOT: slice
-    // CHECK: %[[END:.+]] = getelementptr inbounds i32{{.+}} %slice.0{{.+}} %slice.1
+    // CHECK: %[[END:.+]] = getelementptr inbounds{{( nuw)?}} i32{{.+}} %slice.0{{.+}} %slice.1
     // CHECK-NOT: slice
     // CHECK: insertvalue {{.+}} ptr %slice.0, 0
     // CHECK-NOT: slice
@@ -83,7 +83,7 @@ pub fn slice_iter_mut_new(slice: &mut [u32]) -> std::slice::IterMut<'_, u32> {
 // CHECK-LABEL: @slice_iter_is_empty
 #[no_mangle]
 pub fn slice_iter_is_empty(it: &std::slice::Iter<'_, u32>) -> bool {
-    // CHECK: %[[ENDP:.+]] = getelementptr inbounds i8, ptr %it, {{i32 4|i64 8}}
+    // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}}
     // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]]
     // CHECK-SAME: !nonnull
     // CHECK-SAME: !noundef
@@ -99,7 +99,7 @@ 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: %[[ENDP:.+]] = getelementptr inbounds i8, ptr %it, {{i32 4|i64 8}}
+    // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}}
     // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]]
     // CHECK-SAME: !nonnull
     // CHECK-SAME: !noundef