Change:
The motivation behind the "just ignoring" approach for this PR was based on the fact that I was looking at this as two independent tasks. One of them is to ignore this test for aarch64 (inevitable) and the other is to add suitable tests for the same target. The former is immediate, the latter requires a bit more effort, and is something that should follow. But if we should proceed in a different way, that's fine too. Originally posted by in <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
assign
I started taking a look at this. Adding the tests should be straight forward, but I am also interested in finding out why the llvm bitcode is being generated the way it is for aarch64.
Triage: Are you still working on this?

Discussion:
<ins> //@ revisions: i686-linux i686-freebsd x64-linux x64-apple wasm32 //@ compile-flags: -O -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 //@[wasm32] compile-flags: --target wasm32-wasi //@[wasm32] 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 "by-value struct pointer" case. #![feature(no_core, lang_items, transparent_unions)] #![crate_type = "lib"] #![no_std] #![no_core] #[lang = "sized"] trait Sized {} #[lang = "freeze"] trait Freeze {} #[lang = "copy"] trait Copy {} impl Copy for [u32; 16] {} 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 {} } </ins>

// See ./transparent.rs // Some platforms pass large aggregates using immediate arrays in LLVMIR <del> // Other platforms pass large aggregates using struct pointer in LLVMIR </del> <ins> // Other platforms pass large aggregates using by-value struct pointer in LLVMIR // Yet more platforms pass large aggregates using opaque pointer in LLVMIR </ins> // This covers the "immediate array" case. #![feature(no_core, lang_items, transparent_unions)]

<ins> //@ revisions: aarch64-linux aarch64-darwin //@ compile-flags: -O -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 // 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] #[lang = "sized"] trait Sized {} #[lang = "freeze"] trait Freeze {} #[lang = "copy"] trait Copy {} impl Copy for [u32; 16] {} 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 {} } </ins>

<del> //@ revisions: i686-linux i686-freebsd x64-linux x64-apple wasm32 //@ compile-flags: -O -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 //@[wasm32] compile-flags: --target wasm32-wasi //@[wasm32] needs-llvm-components: webassembly // See ./transparent.rs // Some platforms pass large aggregates using immediate arrays in LLVMIR // Other platforms pass large aggregates using struct pointer in LLVMIR // This covers the "struct pointer" case. #![feature(no_core, lang_items, transparent_unions)] #![crate_type = "lib"] #![no_std] #![no_core] #[lang = "sized"] trait Sized {} #[lang = "freeze"] trait Freeze {} #[lang = "copy"] trait Copy {} impl Copy for [u32; 16] {} 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 {} } </del>