about summary refs log tree commit diff
path: root/tests/codegen-llvm/repr
diff options
context:
space:
mode:
Diffstat (limited to 'tests/codegen-llvm/repr')
-rw-r--r--tests/codegen-llvm/repr/transparent-byval-struct-ptr.rs111
-rw-r--r--tests/codegen-llvm/repr/transparent-imm-array.rs116
-rw-r--r--tests/codegen-llvm/repr/transparent-mips64.rs103
-rw-r--r--tests/codegen-llvm/repr/transparent-opaque-ptr.rs109
-rw-r--r--tests/codegen-llvm/repr/transparent-sparc64.rs113
-rw-r--r--tests/codegen-llvm/repr/transparent-sysv64.rs49
-rw-r--r--tests/codegen-llvm/repr/transparent.rs221
7 files changed, 822 insertions, 0 deletions
diff --git a/tests/codegen-llvm/repr/transparent-byval-struct-ptr.rs b/tests/codegen-llvm/repr/transparent-byval-struct-ptr.rs
new file mode 100644
index 00000000000..0918884144f
--- /dev/null
+++ b/tests/codegen-llvm/repr/transparent-byval-struct-ptr.rs
@@ -0,0 +1,111 @@
+//@ add-core-stubs
+//@ revisions: i686-linux i686-freebsd x64-linux x64-apple
+//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
+
+//@[i686-linux] compile-flags: --target i686-unknown-linux-gnu
+//@[i686-linux] needs-llvm-components: x86
+//@[i686-freebsd] compile-flags: --target i686-unknown-freebsd
+//@[i686-freebsd] needs-llvm-components: x86
+//@[x64-linux] compile-flags: --target x86_64-unknown-linux-gnu
+//@[x64-linux] needs-llvm-components: x86
+//@[x64-apple] compile-flags: --target x86_64-apple-darwin
+//@[x64-apple] needs-llvm-components: x86
+
+// See ./transparent.rs
+// Some platforms pass large aggregates using immediate arrays in LLVMIR
+// Other platforms pass large aggregates using by-value struct pointer in LLVMIR
+// Yet more platforms pass large aggregates using opaque pointer in LLVMIR
+// This covers the "by-value struct pointer" case.
+
+#![feature(no_core, lang_items, transparent_unions)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+impl Copy for BigS {}
+impl Copy for BigU {}
+
+#[repr(C)]
+pub struct BigS([u32; 16]);
+
+#[repr(transparent)]
+pub struct TsBigS(BigS);
+
+#[repr(transparent)]
+pub union TuBigS {
+    field: BigS,
+}
+
+#[repr(transparent)]
+pub enum TeBigS {
+    Variant(BigS),
+}
+
+// CHECK: define{{.*}}void @test_BigS(ptr [[BIGS_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGS_RET_ATTRS2:.*]], ptr [[BIGS_ARG_ATTRS1:.*]] byval([64 x i8]) [[BIGS_ARG_ATTRS2:.*]])
+#[no_mangle]
+pub extern "C" fn test_BigS(_: BigS) -> BigS {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TsBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]] byval([64 x i8]) [[BIGS_ARG_ATTRS2:.*]])
+#[no_mangle]
+pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TuBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]] byval([64 x i8]) [[BIGS_ARG_ATTRS2:.*]])
+#[no_mangle]
+pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TeBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]] byval([64 x i8]) [[BIGS_ARG_ATTRS2]])
+#[no_mangle]
+pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS {
+    loop {}
+}
+
+#[repr(C)]
+pub union BigU {
+    foo: [u32; 16],
+}
+
+#[repr(transparent)]
+pub struct TsBigU(BigU);
+
+#[repr(transparent)]
+pub union TuBigU {
+    field: BigU,
+}
+
+#[repr(transparent)]
+pub enum TeBigU {
+    Variant(BigU),
+}
+
+// CHECK: define{{.*}}void @test_BigU(ptr [[BIGU_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1:.*]] byval([64 x i8]) [[BIGU_ARG_ATTRS2:.*]])
+#[no_mangle]
+pub extern "C" fn test_BigU(_: BigU) -> BigU {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TsBigU(ptr [[BIGU_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]] byval([64 x i8]) [[BIGU_ARG_ATTRS2]])
+#[no_mangle]
+pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TuBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]] byval([64 x i8]) [[BIGU_ARG_ATTRS2]])
+#[no_mangle]
+pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TeBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]] byval([64 x i8]) [[BIGU_ARG_ATTRS2]])
+#[no_mangle]
+pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU {
+    loop {}
+}
diff --git a/tests/codegen-llvm/repr/transparent-imm-array.rs b/tests/codegen-llvm/repr/transparent-imm-array.rs
new file mode 100644
index 00000000000..6dad0447784
--- /dev/null
+++ b/tests/codegen-llvm/repr/transparent-imm-array.rs
@@ -0,0 +1,116 @@
+//@ add-core-stubs
+//@ revisions: arm-linux arm-android armv7-linux armv7-android mips thumb sparc
+//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
+
+//@[arm-linux] compile-flags: --target arm-unknown-linux-gnueabi
+//@[arm-linux] needs-llvm-components: arm
+//@[arm-android] compile-flags: --target arm-linux-androideabi
+//@[arm-android] needs-llvm-components: arm
+//@[armv7-linux] compile-flags: --target armv7-unknown-linux-gnueabi
+//@[armv7-linux] needs-llvm-components: arm
+//@[armv7-android] compile-flags: --target armv7-linux-androideabi
+//@[armv7-android] needs-llvm-components: arm
+//@[mips] compile-flags: --target mips-unknown-linux-gnu
+//@[mips] needs-llvm-components: mips
+//@[thumb] compile-flags: --target thumbv7neon-linux-androideabi
+//@[thumb] needs-llvm-components: arm
+//@[sparc] compile-flags: --target sparc-unknown-linux-gnu
+//@[sparc] needs-llvm-components: sparc
+
+// See ./transparent.rs
+// Some platforms pass large aggregates using immediate arrays in LLVMIR
+// Other platforms pass large aggregates using by-value struct pointer in LLVMIR
+// Yet more platforms pass large aggregates using opaque pointer in LLVMIR
+// This covers the "immediate array" case.
+
+#![feature(no_core, lang_items, transparent_unions)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+impl Copy for BigS {}
+impl Copy for BigU {}
+
+#[repr(C)]
+pub struct BigS([u32; 16]);
+
+#[repr(transparent)]
+pub struct TsBigS(BigS);
+
+#[repr(transparent)]
+pub union TuBigS {
+    field: BigS,
+}
+
+#[repr(transparent)]
+pub enum TeBigS {
+    Variant(BigS),
+}
+
+// CHECK: define void @test_BigS(ptr [[BIGS_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGS_RET_ATTRS2:.*]], [16 x i32]
+#[no_mangle]
+pub extern "C" fn test_BigS(_: BigS) -> BigS {
+    loop {}
+}
+
+// CHECK: define void @test_TsBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], [16 x i32]
+#[no_mangle]
+pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS {
+    loop {}
+}
+
+// CHECK: define void @test_TuBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], [16 x i32]
+#[no_mangle]
+pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS {
+    loop {}
+}
+
+// CHECK: define void @test_TeBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], [16 x i32]
+#[no_mangle]
+pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS {
+    loop {}
+}
+
+#[repr(C)]
+pub union BigU {
+    foo: [u32; 16],
+}
+
+#[repr(transparent)]
+pub struct TsBigU(BigU);
+
+#[repr(transparent)]
+pub union TuBigU {
+    field: BigU,
+}
+
+#[repr(transparent)]
+pub enum TeBigU {
+    Variant(BigU),
+}
+
+// CHECK: define void @test_BigU(ptr [[BIGU_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], [16 x i32]
+#[no_mangle]
+pub extern "C" fn test_BigU(_: BigU) -> BigU {
+    loop {}
+}
+
+// CHECK: define void @test_TsBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2]], [16 x i32]
+#[no_mangle]
+pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU {
+    loop {}
+}
+
+// CHECK: define void @test_TuBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2]], [16 x i32]
+#[no_mangle]
+pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU {
+    loop {}
+}
+
+// CHECK: define void @test_TeBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2]], [16 x i32]
+#[no_mangle]
+pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU {
+    loop {}
+}
diff --git a/tests/codegen-llvm/repr/transparent-mips64.rs b/tests/codegen-llvm/repr/transparent-mips64.rs
new file mode 100644
index 00000000000..98901350154
--- /dev/null
+++ b/tests/codegen-llvm/repr/transparent-mips64.rs
@@ -0,0 +1,103 @@
+//@ add-core-stubs
+//@ revisions: mips64 mips64el
+//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
+
+//@[mips64] compile-flags: --target mips64-unknown-linux-gnuabi64
+//@[mips64] needs-llvm-components: mips
+//@[mips64el] compile-flags: --target mips64el-unknown-linux-gnuabi64
+//@[mips64el] needs-llvm-components: mips
+
+// See ./transparent.rs
+
+#![feature(no_core, lang_items, transparent_unions)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+impl Copy for BigS {}
+impl Copy for BigU {}
+
+#[repr(C)]
+pub struct BigS([u32; 16]);
+
+#[repr(transparent)]
+pub struct TsBigS(BigS);
+
+#[repr(transparent)]
+pub union TuBigS {
+    field: BigS,
+}
+
+#[repr(transparent)]
+pub enum TeBigS {
+    Variant(BigS),
+}
+
+// CHECK: define void @test_BigS(ptr [[BIGS_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGS_RET_ATTRS2:.*]], [8 x i64]
+#[no_mangle]
+pub extern "C" fn test_BigS(_: BigS) -> BigS {
+    loop {}
+}
+
+// CHECK: define void @test_TsBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], [8 x i64]
+#[no_mangle]
+pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS {
+    loop {}
+}
+
+// CHECK: define void @test_TuBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], [8 x i64]
+#[no_mangle]
+pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS {
+    loop {}
+}
+
+// CHECK: define void @test_TeBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], [8 x i64]
+#[no_mangle]
+pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS {
+    loop {}
+}
+
+#[repr(C)]
+pub union BigU {
+    foo: [u32; 16],
+}
+
+#[repr(transparent)]
+pub struct TsBigU(BigU);
+
+#[repr(transparent)]
+pub union TuBigU {
+    field: BigU,
+}
+
+#[repr(transparent)]
+pub enum TeBigU {
+    Variant(BigU),
+}
+
+// CHECK: define void @test_BigU(ptr [[BIGU_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], [8 x i64]
+#[no_mangle]
+pub extern "C" fn test_BigU(_: BigU) -> BigU {
+    loop {}
+}
+
+// CHECK: define void @test_TsBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2]], [8 x i64]
+#[no_mangle]
+pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU {
+    loop {}
+}
+
+// CHECK: define void @test_TuBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2]], [8 x i64]
+#[no_mangle]
+pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU {
+    loop {}
+}
+
+// CHECK: define void @test_TeBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2]], [8 x i64]
+#[no_mangle]
+pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU {
+    loop {}
+}
diff --git a/tests/codegen-llvm/repr/transparent-opaque-ptr.rs b/tests/codegen-llvm/repr/transparent-opaque-ptr.rs
new file mode 100644
index 00000000000..7911370c478
--- /dev/null
+++ b/tests/codegen-llvm/repr/transparent-opaque-ptr.rs
@@ -0,0 +1,109 @@
+//@ add-core-stubs
+//@ revisions: aarch64-linux aarch64-darwin wasm32-wasip1
+//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
+
+//@[aarch64-linux] compile-flags: --target aarch64-unknown-linux-gnu
+//@[aarch64-linux] needs-llvm-components: aarch64
+//@[aarch64-darwin] compile-flags: --target aarch64-apple-darwin
+//@[aarch64-darwin] needs-llvm-components: aarch64
+//@[wasm32-wasip1] compile-flags: --target wasm32-wasip1
+//@[wasm32-wasip1] needs-llvm-components: webassembly
+
+// See ./transparent.rs
+// Some platforms pass large aggregates using immediate arrays in LLVMIR
+// Other platforms pass large aggregates using by-value struct pointer in LLVMIR
+// Yet more platforms pass large aggregates using opaque pointer in LLVMIR
+// This covers the "opaque pointer" case.
+
+#![feature(no_core, lang_items, transparent_unions)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+impl Copy for BigS {}
+impl Copy for BigU {}
+
+#[repr(C)]
+pub struct BigS([u32; 16]);
+
+#[repr(transparent)]
+pub struct TsBigS(BigS);
+
+#[repr(transparent)]
+pub union TuBigS {
+    field: BigS,
+}
+
+#[repr(transparent)]
+pub enum TeBigS {
+    Variant(BigS),
+}
+
+// CHECK: define{{.*}}void @test_BigS(ptr [[BIGS_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGS_RET_ATTRS2:.*]], ptr [[BIGS_ARG_ATTRS1:.*]])
+#[no_mangle]
+pub extern "C" fn test_BigS(_: BigS) -> BigS {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TsBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]])
+#[no_mangle]
+pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TuBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]])
+#[no_mangle]
+pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TeBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]])
+#[no_mangle]
+pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS {
+    loop {}
+}
+
+#[repr(C)]
+pub union BigU {
+    foo: [u32; 16],
+}
+
+#[repr(transparent)]
+pub struct TsBigU(BigU);
+
+#[repr(transparent)]
+pub union TuBigU {
+    field: BigU,
+}
+
+#[repr(transparent)]
+pub enum TeBigU {
+    Variant(BigU),
+}
+
+// CHECK: define{{.*}}void @test_BigU(ptr [[BIGU_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1:.*]])
+#[no_mangle]
+pub extern "C" fn test_BigU(_: BigU) -> BigU {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TsBigU(ptr [[BIGU_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]])
+#[no_mangle]
+pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TuBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]])
+#[no_mangle]
+pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TeBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]])
+#[no_mangle]
+pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU {
+    loop {}
+}
diff --git a/tests/codegen-llvm/repr/transparent-sparc64.rs b/tests/codegen-llvm/repr/transparent-sparc64.rs
new file mode 100644
index 00000000000..62bfc8a5fce
--- /dev/null
+++ b/tests/codegen-llvm/repr/transparent-sparc64.rs
@@ -0,0 +1,113 @@
+//@ add-core-stubs
+//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes --target sparc64-unknown-linux-gnu
+//@ needs-llvm-components: sparc
+
+// See ./transparent.rs
+
+#![feature(no_core, lang_items, transparent_unions)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+impl Copy for BigS {}
+impl Copy for BigU {}
+
+#[repr(C)]
+pub struct BigS([u32; 16]);
+
+#[repr(transparent)]
+pub struct TsBigS(BigS);
+
+#[repr(transparent)]
+pub union TuBigS {
+    field: BigS,
+}
+
+#[repr(transparent)]
+pub enum TeBigS {
+    Variant(BigS),
+}
+
+// CHECK: define{{.*}}void @test_BigS(ptr [[BIGS_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGS_RET_ATTRS2:.*]], ptr
+// CHECK-NOT: byval
+// CHECK-SAME: %{{[0-9a-z_]+}})
+#[no_mangle]
+pub extern "C" fn test_BigS(_: BigS) -> BigS {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TsBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr
+// CHECK-NOT: byval
+// CHECK-SAME: %{{[0-9a-z_]+}})
+#[no_mangle]
+pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TuBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr
+// CHECK-NOT: byval
+// CHECK-SAME: %{{[0-9a-z_]+}})
+#[no_mangle]
+pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TeBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr
+// CHECK-NOT: byval
+// CHECK-SAME: %{{[0-9a-z_]+}})
+#[no_mangle]
+pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS {
+    loop {}
+}
+
+#[repr(C)]
+pub union BigU {
+    foo: [u32; 16],
+}
+
+#[repr(transparent)]
+pub struct TsBigU(BigU);
+
+#[repr(transparent)]
+pub union TuBigU {
+    field: BigU,
+}
+
+#[repr(transparent)]
+pub enum TeBigU {
+    Variant(BigU),
+}
+
+// CHECK: define{{.*}}void @test_BigU(ptr [[BIGU_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr
+// CHECK-NOT: byval
+// CHECK-SAME: %{{[0-9a-z_]+}})
+#[no_mangle]
+pub extern "C" fn test_BigU(_: BigU) -> BigU {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TsBigU(ptr [[BIGU_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr
+// CHECK-NOT: byval
+// CHECK-SAME: %{{[0-9a-z_]+}})
+#[no_mangle]
+pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TuBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr
+// CHECK-NOT: byval
+// CHECK-SAME: %{{[0-9a-z_]+}})
+#[no_mangle]
+pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TeBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr
+// CHECK-NOT: byval
+// CHECK-SAME: %{{[0-9a-z_]+}})
+#[no_mangle]
+pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU {
+    loop {}
+}
diff --git a/tests/codegen-llvm/repr/transparent-sysv64.rs b/tests/codegen-llvm/repr/transparent-sysv64.rs
new file mode 100644
index 00000000000..3efc3f7c391
--- /dev/null
+++ b/tests/codegen-llvm/repr/transparent-sysv64.rs
@@ -0,0 +1,49 @@
+//@ add-core-stubs
+//@ revisions: linux apple win
+//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
+
+//@[linux] compile-flags: --target x86_64-unknown-linux-gnu
+//@[linux] needs-llvm-components: x86
+//@[apple] compile-flags: --target x86_64-apple-darwin
+//@[apple] needs-llvm-components: x86
+//@[win] compile-flags: --target x86_64-pc-windows-msvc
+//@[win] needs-llvm-components: x86
+
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+#[repr(C)]
+pub struct Rgb8 {
+    r: u8,
+    g: u8,
+    b: u8,
+}
+
+#[repr(transparent)]
+pub struct Rgb8Wrap(Rgb8);
+
+// CHECK: i24 @test_Rgb8Wrap(i24{{( %0)?}})
+#[no_mangle]
+pub extern "sysv64" fn test_Rgb8Wrap(_: Rgb8Wrap) -> Rgb8Wrap {
+    loop {}
+}
+
+#[repr(C)]
+pub union FloatBits {
+    float: f32,
+    bits: u32,
+}
+
+#[repr(transparent)]
+pub struct SmallUnion(FloatBits);
+
+// CHECK: i32 @test_SmallUnion(i32{{( %0)?}})
+#[no_mangle]
+pub extern "sysv64" fn test_SmallUnion(_: SmallUnion) -> SmallUnion {
+    loop {}
+}
diff --git a/tests/codegen-llvm/repr/transparent.rs b/tests/codegen-llvm/repr/transparent.rs
new file mode 100644
index 00000000000..29b627462a4
--- /dev/null
+++ b/tests/codegen-llvm/repr/transparent.rs
@@ -0,0 +1,221 @@
+//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
+//@ ignore-riscv64 riscv64 has an i128 type used with test_Vector
+//@ ignore-s390x s390x with default march passes vector types per reference
+//@ ignore-loongarch64 see codegen/loongarch-abi for loongarch function call tests
+
+// This codegen test embeds assumptions about how certain "C" psABIs are handled
+// so it doesn't apply to all architectures or even all OS
+// For RISCV: see codegen/riscv-abi
+// For LoongArch: see codegen/loongarch-abi
+
+#![crate_type = "lib"]
+#![feature(repr_simd, transparent_unions, arm_target_feature, mips_target_feature)]
+
+use std::marker::PhantomData;
+
+#[derive(Copy, Clone)]
+pub struct Zst1;
+#[derive(Copy, Clone)]
+pub struct Zst2(());
+
+#[derive(Copy, Clone)]
+#[repr(transparent)]
+pub struct F32(f32);
+
+// CHECK: define{{.*}}float @test_F32(float noundef %_1)
+#[no_mangle]
+pub extern "C" fn test_F32(_: F32) -> F32 {
+    loop {}
+}
+
+#[repr(transparent)]
+pub struct Ptr(*mut u8);
+
+// CHECK: define{{.*}}ptr @test_Ptr(ptr noundef %_1)
+#[no_mangle]
+pub extern "C" fn test_Ptr(_: Ptr) -> Ptr {
+    loop {}
+}
+
+#[repr(transparent)]
+pub struct WithZst(u64, Zst1);
+
+// CHECK: define{{.*}}i64 @test_WithZst(i64 noundef %_1)
+#[no_mangle]
+pub extern "C" fn test_WithZst(_: WithZst) -> WithZst {
+    loop {}
+}
+
+#[repr(transparent)]
+pub struct WithZeroSizedArray(*const f32, [i8; 0]);
+
+// CHECK: define{{.*}}ptr @test_WithZeroSizedArray(ptr noundef %_1)
+#[no_mangle]
+pub extern "C" fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray {
+    loop {}
+}
+
+#[repr(transparent)]
+pub struct Generic<T>(T);
+
+// CHECK: define{{.*}}double @test_Generic(double noundef %_1)
+#[no_mangle]
+pub extern "C" fn test_Generic(_: Generic<f64>) -> Generic<f64> {
+    loop {}
+}
+
+#[repr(transparent)]
+pub struct GenericPlusZst<T>(T, Zst2);
+
+#[repr(u8)]
+pub enum Bool {
+    True,
+    False,
+    FileNotFound,
+}
+
+// CHECK: define{{( dso_local)?}} noundef{{( zeroext)?( range\(i8 0, 3\))?}} i8 @test_Gpz(i8 noundef{{( zeroext)?( range\(i8 0, 3\))?}} %_1)
+#[no_mangle]
+pub extern "C" fn test_Gpz(_: GenericPlusZst<Bool>) -> GenericPlusZst<Bool> {
+    loop {}
+}
+
+#[repr(transparent)]
+pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>);
+
+// CHECK: define{{.*}}ptr @test_LifetimePhantom(ptr noundef %_1)
+#[no_mangle]
+pub extern "C" fn test_LifetimePhantom(_: LifetimePhantom<i16>) -> LifetimePhantom<i16> {
+    loop {}
+}
+
+// This works despite current alignment resrictions because PhantomData is always align(1)
+#[repr(transparent)]
+pub struct UnitPhantom<T, U> {
+    val: T,
+    unit: PhantomData<U>,
+}
+
+pub struct Px;
+
+// CHECK: define{{.*}}float @test_UnitPhantom(float noundef %_1)
+#[no_mangle]
+pub extern "C" fn test_UnitPhantom(_: UnitPhantom<f32, Px>) -> UnitPhantom<f32, Px> {
+    loop {}
+}
+
+#[repr(transparent)]
+pub struct TwoZsts(Zst1, i8, Zst2);
+
+// CHECK: define{{( dso_local)?}} noundef{{( signext)?}} i8 @test_TwoZsts(i8 noundef{{( signext)?}} %_1)
+#[no_mangle]
+pub extern "C" fn test_TwoZsts(_: TwoZsts) -> TwoZsts {
+    loop {}
+}
+
+#[repr(transparent)]
+pub struct Nested1(Zst2, Generic<f64>);
+
+// CHECK: define{{.*}}double @test_Nested1(double noundef %_1)
+#[no_mangle]
+pub extern "C" fn test_Nested1(_: Nested1) -> Nested1 {
+    loop {}
+}
+
+#[repr(transparent)]
+pub struct Nested2(Nested1, Zst1);
+
+// CHECK: define{{.*}}double @test_Nested2(double noundef %_1)
+#[no_mangle]
+pub extern "C" fn test_Nested2(_: Nested2) -> Nested2 {
+    loop {}
+}
+
+#[repr(simd)]
+struct f32x4([f32; 4]);
+
+#[repr(transparent)]
+pub struct Vector(f32x4);
+
+// CHECK: define{{.*}}<4 x float> @test_Vector(<4 x float> %_1)
+#[no_mangle]
+#[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
+#[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
+#[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
+#[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
+pub extern "C" fn test_Vector(_: Vector) -> Vector {
+    loop {}
+}
+
+trait Mirror {
+    type It: ?Sized;
+}
+impl<T: ?Sized> Mirror for T {
+    type It = Self;
+}
+
+#[repr(transparent)]
+pub struct StructWithProjection(<f32 as Mirror>::It);
+
+// CHECK: define{{.*}}float @test_Projection(float noundef %_1)
+#[no_mangle]
+pub extern "C" fn test_Projection(_: StructWithProjection) -> StructWithProjection {
+    loop {}
+}
+
+#[repr(transparent)]
+pub enum EnumF32 {
+    Variant(F32),
+}
+
+// CHECK: define{{.*}}float @test_EnumF32(float noundef %_1)
+#[no_mangle]
+pub extern "C" fn test_EnumF32(_: EnumF32) -> EnumF32 {
+    loop {}
+}
+
+#[repr(transparent)]
+pub enum EnumF32WithZsts {
+    Variant(Zst1, F32, Zst2),
+}
+
+// CHECK: define{{.*}}float @test_EnumF32WithZsts(float noundef %_1)
+#[no_mangle]
+pub extern "C" fn test_EnumF32WithZsts(_: EnumF32WithZsts) -> EnumF32WithZsts {
+    loop {}
+}
+
+#[repr(transparent)]
+pub union UnionF32 {
+    field: F32,
+}
+
+// CHECK: define{{.*}} float @test_UnionF32(float %_1)
+#[no_mangle]
+pub extern "C" fn test_UnionF32(_: UnionF32) -> UnionF32 {
+    loop {}
+}
+
+#[repr(transparent)]
+pub union UnionF32WithZsts {
+    zst1: Zst1,
+    field: F32,
+    zst2: Zst2,
+}
+
+// CHECK: define{{.*}}float @test_UnionF32WithZsts(float %_1)
+#[no_mangle]
+pub extern "C" fn test_UnionF32WithZsts(_: UnionF32WithZsts) -> UnionF32WithZsts {
+    loop {}
+}
+
+// All that remains to be tested are aggregates. They are tested in separate files called
+// transparent-*.rs  with `only-*` or `ignore-*` directives, because the expected LLVM IR
+// function signatures vary so much that it's not reasonably possible to cover all of them with a
+// single CHECK line.
+//
+// You may be wondering why we don't just compare the return types and argument types for equality
+// with FileCheck regex captures. Well, rustc doesn't perform newtype unwrapping on newtypes
+// containing aggregates. This is OK on all ABIs we support, but because LLVM has not gotten rid of
+// pointee types yet, the IR function signature will be syntactically different (%Foo* vs
+// %FooWrapper*).