use [N x i8] for byval/sret types

This avoids depending on LLVM's struct types to determine the size of
the byval/sret slot.
This commit is contained in:
Erik Desjardins 2024-02-25 00:43:03 -05:00
parent 3c029725f5
commit 96a72676d1
10 changed files with 80 additions and 73 deletions

View File

@ -424,7 +424,10 @@ fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
PassMode::Indirect { attrs, meta_attrs: _, on_stack } => { PassMode::Indirect { attrs, meta_attrs: _, on_stack } => {
assert!(!on_stack); assert!(!on_stack);
let i = apply(attrs); let i = apply(attrs);
let sret = llvm::CreateStructRetAttr(cx.llcx, self.ret.layout.llvm_type(cx)); let sret = llvm::CreateStructRetAttr(
cx.llcx,
cx.type_array(cx.type_i8(), self.ret.layout.size.bytes()),
);
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[sret]); attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[sret]);
} }
PassMode::Cast { cast, pad_i32: _ } => { PassMode::Cast { cast, pad_i32: _ } => {
@ -437,7 +440,10 @@ fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
PassMode::Ignore => {} PassMode::Ignore => {}
PassMode::Indirect { attrs, meta_attrs: None, on_stack: true } => { PassMode::Indirect { attrs, meta_attrs: None, on_stack: true } => {
let i = apply(attrs); let i = apply(attrs);
let byval = llvm::CreateByValAttr(cx.llcx, arg.layout.llvm_type(cx)); let byval = llvm::CreateByValAttr(
cx.llcx,
cx.type_array(cx.type_i8(), arg.layout.size.bytes()),
);
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[byval]); attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[byval]);
} }
PassMode::Direct(attrs) PassMode::Direct(attrs)
@ -486,7 +492,10 @@ fn apply_attrs_callsite(&self, bx: &mut Builder<'_, 'll, 'tcx>, callsite: &'ll V
PassMode::Indirect { attrs, meta_attrs: _, on_stack } => { PassMode::Indirect { attrs, meta_attrs: _, on_stack } => {
assert!(!on_stack); assert!(!on_stack);
let i = apply(bx.cx, attrs); let i = apply(bx.cx, attrs);
let sret = llvm::CreateStructRetAttr(bx.cx.llcx, self.ret.layout.llvm_type(bx)); let sret = llvm::CreateStructRetAttr(
bx.cx.llcx,
bx.cx.type_array(bx.cx.type_i8(), self.ret.layout.size.bytes()),
);
attributes::apply_to_callsite(callsite, llvm::AttributePlace::Argument(i), &[sret]); attributes::apply_to_callsite(callsite, llvm::AttributePlace::Argument(i), &[sret]);
} }
PassMode::Cast { cast, pad_i32: _ } => { PassMode::Cast { cast, pad_i32: _ } => {
@ -513,7 +522,10 @@ fn apply_attrs_callsite(&self, bx: &mut Builder<'_, 'll, 'tcx>, callsite: &'ll V
PassMode::Ignore => {} PassMode::Ignore => {}
PassMode::Indirect { attrs, meta_attrs: None, on_stack: true } => { PassMode::Indirect { attrs, meta_attrs: None, on_stack: true } => {
let i = apply(bx.cx, attrs); let i = apply(bx.cx, attrs);
let byval = llvm::CreateByValAttr(bx.cx.llcx, arg.layout.llvm_type(bx)); let byval = llvm::CreateByValAttr(
bx.cx.llcx,
bx.cx.type_array(bx.cx.type_i8(), arg.layout.size.bytes()),
);
attributes::apply_to_callsite( attributes::apply_to_callsite(
callsite, callsite,
llvm::AttributePlace::Argument(i), llvm::AttributePlace::Argument(i),

View File

@ -37,12 +37,12 @@ pub struct DoubleFoo {
} }
extern "C" { extern "C" {
// x86-linux: declare void @f({{.*}}byval(%Foo) align 4{{.*}}) // x86-linux: declare void @f({{.*}}byval([32 x i8]) align 4{{.*}})
// x86-darwin: declare void @f({{.*}}byval(%Foo) align 16{{.*}}) // x86-darwin: declare void @f({{.*}}byval([32 x i8]) align 16{{.*}})
fn f(foo: Foo); fn f(foo: Foo);
// x86-linux: declare void @g({{.*}}byval(%DoubleFoo) align 4{{.*}}) // x86-linux: declare void @g({{.*}}byval([64 x i8]) align 4{{.*}})
// x86-darwin: declare void @g({{.*}}byval(%DoubleFoo) align 16{{.*}}) // x86-darwin: declare void @g({{.*}}byval([64 x i8]) align 16{{.*}})
fn g(foo: DoubleFoo); fn g(foo: DoubleFoo);
} }

View File

@ -107,20 +107,20 @@ pub unsafe fn call_na1(x: NaturalAlign1) {
// CHECK: start: // CHECK: start:
// m68k: [[ALLOCA:%[a-z0-9+]]] = alloca %NaturalAlign1, align 1 // m68k: [[ALLOCA:%[a-z0-9+]]] = alloca %NaturalAlign1, align 1
// m68k: call void @natural_align_1({{.*}}byval(%NaturalAlign1) align 1{{.*}} [[ALLOCA]]) // m68k: call void @natural_align_1({{.*}}byval([2 x i8]) align 1{{.*}} [[ALLOCA]])
// wasm: [[ALLOCA:%[a-z0-9+]]] = alloca %NaturalAlign1, align 1 // wasm: [[ALLOCA:%[a-z0-9+]]] = alloca %NaturalAlign1, align 1
// wasm: call void @natural_align_1({{.*}}byval(%NaturalAlign1) align 1{{.*}} [[ALLOCA]]) // wasm: call void @natural_align_1({{.*}}byval([2 x i8]) align 1{{.*}} [[ALLOCA]])
// x86_64-linux: call void @natural_align_1(i16 // x86_64-linux: call void @natural_align_1(i16
// x86_64-windows: call void @natural_align_1(i16 // x86_64-windows: call void @natural_align_1(i16
// i686-linux: [[ALLOCA:%[a-z0-9+]]] = alloca %NaturalAlign1, align 4 // i686-linux: [[ALLOCA:%[a-z0-9+]]] = alloca %NaturalAlign1, align 4
// i686-linux: call void @natural_align_1({{.*}}byval(%NaturalAlign1) align 4{{.*}} [[ALLOCA]]) // i686-linux: call void @natural_align_1({{.*}}byval([2 x i8]) align 4{{.*}} [[ALLOCA]])
// i686-windows: [[ALLOCA:%[a-z0-9+]]] = alloca %NaturalAlign1, align 4 // i686-windows: [[ALLOCA:%[a-z0-9+]]] = alloca %NaturalAlign1, align 4
// i686-windows: call void @natural_align_1({{.*}}byval(%NaturalAlign1) align 4{{.*}} [[ALLOCA]]) // i686-windows: call void @natural_align_1({{.*}}byval([2 x i8]) align 4{{.*}} [[ALLOCA]])
natural_align_1(x); natural_align_1(x);
} }
@ -135,10 +135,10 @@ pub unsafe fn call_na2(x: NaturalAlign2) {
// x86_64-windows-NEXT: call void @natural_align_2 // x86_64-windows-NEXT: call void @natural_align_2
// i686-linux: [[ALLOCA:%[0-9]+]] = alloca %NaturalAlign2, align 4 // i686-linux: [[ALLOCA:%[0-9]+]] = alloca %NaturalAlign2, align 4
// i686-linux: call void @natural_align_2({{.*}}byval(%NaturalAlign2) align 4{{.*}} [[ALLOCA]]) // i686-linux: call void @natural_align_2({{.*}}byval([34 x i8]) align 4{{.*}} [[ALLOCA]])
// i686-windows: [[ALLOCA:%[0-9]+]] = alloca %NaturalAlign2, align 4 // i686-windows: [[ALLOCA:%[0-9]+]] = alloca %NaturalAlign2, align 4
// i686-windows: call void @natural_align_2({{.*}}byval(%NaturalAlign2) align 4{{.*}} [[ALLOCA]]) // i686-windows: call void @natural_align_2({{.*}}byval([34 x i8]) align 4{{.*}} [[ALLOCA]])
natural_align_2(x); natural_align_2(x);
} }
@ -199,141 +199,141 @@ pub unsafe fn call_fa16(x: ForceAlign16) {
} }
extern "C" { extern "C" {
// m68k: declare void @natural_align_1({{.*}}byval(%NaturalAlign1) align 1{{.*}}) // m68k: declare void @natural_align_1({{.*}}byval([2 x i8]) align 1{{.*}})
// wasm: declare void @natural_align_1({{.*}}byval(%NaturalAlign1) align 1{{.*}}) // wasm: declare void @natural_align_1({{.*}}byval([2 x i8]) align 1{{.*}})
// x86_64-linux: declare void @natural_align_1(i16) // x86_64-linux: declare void @natural_align_1(i16)
// x86_64-windows: declare void @natural_align_1(i16) // x86_64-windows: declare void @natural_align_1(i16)
// i686-linux: declare void @natural_align_1({{.*}}byval(%NaturalAlign1) align 4{{.*}}) // i686-linux: declare void @natural_align_1({{.*}}byval([2 x i8]) align 4{{.*}})
// i686-windows: declare void @natural_align_1({{.*}}byval(%NaturalAlign1) align 4{{.*}}) // i686-windows: declare void @natural_align_1({{.*}}byval([2 x i8]) align 4{{.*}})
fn natural_align_1(x: NaturalAlign1); fn natural_align_1(x: NaturalAlign1);
// m68k: declare void @natural_align_2({{.*}}byval(%NaturalAlign2) align 2{{.*}}) // m68k: declare void @natural_align_2({{.*}}byval([34 x i8]) align 2{{.*}})
// wasm: declare void @natural_align_2({{.*}}byval(%NaturalAlign2) align 2{{.*}}) // wasm: declare void @natural_align_2({{.*}}byval([34 x i8]) align 2{{.*}})
// x86_64-linux: declare void @natural_align_2({{.*}}byval(%NaturalAlign2) align 2{{.*}}) // x86_64-linux: declare void @natural_align_2({{.*}}byval([34 x i8]) align 2{{.*}})
// x86_64-windows: declare void @natural_align_2( // x86_64-windows: declare void @natural_align_2(
// x86_64-windows-NOT: byval // x86_64-windows-NOT: byval
// x86_64-windows-SAME: align 2{{.*}}) // x86_64-windows-SAME: align 2{{.*}})
// i686-linux: declare void @natural_align_2({{.*}}byval(%NaturalAlign2) align 4{{.*}}) // i686-linux: declare void @natural_align_2({{.*}}byval([34 x i8]) align 4{{.*}})
// i686-windows: declare void @natural_align_2({{.*}}byval(%NaturalAlign2) align 4{{.*}}) // i686-windows: declare void @natural_align_2({{.*}}byval([34 x i8]) align 4{{.*}})
fn natural_align_2(x: NaturalAlign2); fn natural_align_2(x: NaturalAlign2);
// m68k: declare void @force_align_4({{.*}}byval(%ForceAlign4) align 4{{.*}}) // m68k: declare void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
// wasm: declare void @force_align_4({{.*}}byval(%ForceAlign4) align 4{{.*}}) // wasm: declare void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
// x86_64-linux: declare void @force_align_4({{.*}}byval(%ForceAlign4) align 4{{.*}}) // x86_64-linux: declare void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
// x86_64-windows: declare void @force_align_4( // x86_64-windows: declare void @force_align_4(
// x86_64-windows-NOT: byval // x86_64-windows-NOT: byval
// x86_64-windows-SAME: align 4{{.*}}) // x86_64-windows-SAME: align 4{{.*}})
// i686-linux: declare void @force_align_4({{.*}}byval(%ForceAlign4) align 4{{.*}}) // i686-linux: declare void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
// i686-windows: declare void @force_align_4({{.*}}byval(%ForceAlign4) align 4{{.*}}) // i686-windows: declare void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
fn force_align_4(x: ForceAlign4); fn force_align_4(x: ForceAlign4);
// m68k: declare void @natural_align_8({{.*}}byval(%NaturalAlign8) align 4{{.*}}) // m68k: declare void @natural_align_8({{.*}}byval([24 x i8]) align 4{{.*}})
// wasm: declare void @natural_align_8({{.*}}byval(%NaturalAlign8) align 8{{.*}}) // wasm: declare void @natural_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
// x86_64-linux: declare void @natural_align_8({{.*}}byval(%NaturalAlign8) align 8{{.*}}) // x86_64-linux: declare void @natural_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
// x86_64-windows: declare void @natural_align_8( // x86_64-windows: declare void @natural_align_8(
// x86_64-windows-NOT: byval // x86_64-windows-NOT: byval
// x86_64-windows-SAME: align 8{{.*}}) // x86_64-windows-SAME: align 8{{.*}})
// i686-linux: declare void @natural_align_8({{.*}}byval(%NaturalAlign8) align 4{{.*}}) // i686-linux: declare void @natural_align_8({{.*}}byval([24 x i8]) align 4{{.*}})
// i686-windows: declare void @natural_align_8({{.*}}byval(%NaturalAlign8) align 4{{.*}}) // i686-windows: declare void @natural_align_8({{.*}}byval([24 x i8]) align 4{{.*}})
fn natural_align_8(x: NaturalAlign8); fn natural_align_8(x: NaturalAlign8);
// m68k: declare void @force_align_8({{.*}}byval(%ForceAlign8) align 8{{.*}}) // m68k: declare void @force_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
// wasm: declare void @force_align_8({{.*}}byval(%ForceAlign8) align 8{{.*}}) // wasm: declare void @force_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
// x86_64-linux: declare void @force_align_8({{.*}}byval(%ForceAlign8) align 8{{.*}}) // x86_64-linux: declare void @force_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
// x86_64-windows: declare void @force_align_8( // x86_64-windows: declare void @force_align_8(
// x86_64-windows-NOT: byval // x86_64-windows-NOT: byval
// x86_64-windows-SAME: align 8{{.*}}) // x86_64-windows-SAME: align 8{{.*}})
// i686-linux: declare void @force_align_8({{.*}}byval(%ForceAlign8) align 4{{.*}}) // i686-linux: declare void @force_align_8({{.*}}byval([24 x i8]) align 4{{.*}})
// i686-windows: declare void @force_align_8( // i686-windows: declare void @force_align_8(
// i686-windows-NOT: byval // i686-windows-NOT: byval
// i686-windows-SAME: align 8{{.*}}) // i686-windows-SAME: align 8{{.*}})
fn force_align_8(x: ForceAlign8); fn force_align_8(x: ForceAlign8);
// m68k: declare void @lower_fa8({{.*}}byval(%LowerFA8) align 4{{.*}}) // m68k: declare void @lower_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
// wasm: declare void @lower_fa8({{.*}}byval(%LowerFA8) align 8{{.*}}) // wasm: declare void @lower_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
// x86_64-linux: declare void @lower_fa8({{.*}}byval(%LowerFA8) align 8{{.*}}) // x86_64-linux: declare void @lower_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
// x86_64-windows: declare void @lower_fa8( // x86_64-windows: declare void @lower_fa8(
// x86_64-windows-NOT: byval // x86_64-windows-NOT: byval
// x86_64-windows-SAME: align 8{{.*}}) // x86_64-windows-SAME: align 8{{.*}})
// i686-linux: declare void @lower_fa8({{.*}}byval(%LowerFA8) align 4{{.*}}) // i686-linux: declare void @lower_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
// i686-windows: declare void @lower_fa8({{.*}}byval(%LowerFA8) align 4{{.*}}) // i686-windows: declare void @lower_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
fn lower_fa8(x: LowerFA8); fn lower_fa8(x: LowerFA8);
// m68k: declare void @wrapped_fa8({{.*}}byval(%WrappedFA8) align 8{{.*}}) // m68k: declare void @wrapped_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
// wasm: declare void @wrapped_fa8({{.*}}byval(%WrappedFA8) align 8{{.*}}) // wasm: declare void @wrapped_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
// x86_64-linux: declare void @wrapped_fa8({{.*}}byval(%WrappedFA8) align 8{{.*}}) // x86_64-linux: declare void @wrapped_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
// x86_64-windows: declare void @wrapped_fa8( // x86_64-windows: declare void @wrapped_fa8(
// x86_64-windows-NOT: byval // x86_64-windows-NOT: byval
// x86_64-windows-SAME: align 8{{.*}}) // x86_64-windows-SAME: align 8{{.*}})
// i686-linux: declare void @wrapped_fa8({{.*}}byval(%WrappedFA8) align 4{{.*}}) // i686-linux: declare void @wrapped_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
// i686-windows: declare void @wrapped_fa8( // i686-windows: declare void @wrapped_fa8(
// i686-windows-NOT: byval // i686-windows-NOT: byval
// i686-windows-SAME: align 8{{.*}}) // i686-windows-SAME: align 8{{.*}})
fn wrapped_fa8(x: WrappedFA8); fn wrapped_fa8(x: WrappedFA8);
// m68k: declare void @transparent_fa8({{.*}}byval(%TransparentFA8) align 8{{.*}}) // m68k: declare void @transparent_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
// wasm: declare void @transparent_fa8({{.*}}byval(%TransparentFA8) align 8{{.*}}) // wasm: declare void @transparent_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
// x86_64-linux: declare void @transparent_fa8({{.*}}byval(%TransparentFA8) align 8{{.*}}) // x86_64-linux: declare void @transparent_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
// x86_64-windows: declare void @transparent_fa8( // x86_64-windows: declare void @transparent_fa8(
// x86_64-windows-NOT: byval // x86_64-windows-NOT: byval
// x86_64-windows-SAME: align 8{{.*}}) // x86_64-windows-SAME: align 8{{.*}})
// i686-linux: declare void @transparent_fa8({{.*}}byval(%TransparentFA8) align 4{{.*}}) // i686-linux: declare void @transparent_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
// i686-windows: declare void @transparent_fa8( // i686-windows: declare void @transparent_fa8(
// i686-windows-NOT: byval // i686-windows-NOT: byval
// i686-windows-SAME: align 8{{.*}}) // i686-windows-SAME: align 8{{.*}})
fn transparent_fa8(x: TransparentFA8); fn transparent_fa8(x: TransparentFA8);
// m68k: declare void @force_align_16({{.*}}byval(%ForceAlign16) align 16{{.*}}) // m68k: declare void @force_align_16({{.*}}byval([80 x i8]) align 16{{.*}})
// wasm: declare void @force_align_16({{.*}}byval(%ForceAlign16) align 16{{.*}}) // wasm: declare void @force_align_16({{.*}}byval([80 x i8]) align 16{{.*}})
// x86_64-linux: declare void @force_align_16({{.*}}byval(%ForceAlign16) align 16{{.*}}) // x86_64-linux: declare void @force_align_16({{.*}}byval([80 x i8]) align 16{{.*}})
// x86_64-windows: declare void @force_align_16( // x86_64-windows: declare void @force_align_16(
// x86_64-windows-NOT: byval // x86_64-windows-NOT: byval
// x86_64-windows-SAME: align 16{{.*}}) // x86_64-windows-SAME: align 16{{.*}})
// i686-linux: declare void @force_align_16({{.*}}byval(%ForceAlign16) align 4{{.*}}) // i686-linux: declare void @force_align_16({{.*}}byval([80 x i8]) align 4{{.*}})
// i686-windows: declare void @force_align_16( // i686-windows: declare void @force_align_16(
// i686-windows-NOT: byval // i686-windows-NOT: byval

View File

@ -8,7 +8,6 @@ pub enum Align64 {
A(u32), A(u32),
B(u32), B(u32),
} }
// CHECK: %Align64 = type { i32, [15 x i32] }
pub struct Nested64 { pub struct Nested64 {
a: u8, a: u8,

View File

@ -5,7 +5,6 @@
#[repr(align(64))] #[repr(align(64))]
pub struct Align64(i32); pub struct Align64(i32);
// CHECK: %Align64 = type { i32, [15 x i32] }
pub struct Nested64 { pub struct Nested64 {
a: Align64, a: Align64,
@ -13,19 +12,16 @@ pub struct Nested64 {
c: i32, c: i32,
d: i8, d: i8,
} }
// CHECK: %Nested64 = type { %Align64, i32, i32, i8, [55 x i8] }
pub enum Enum4 { pub enum Enum4 {
A(i32), A(i32),
B(i32), B(i32),
} }
// No Aggregate type, and hence nothing in LLVM IR.
pub enum Enum64 { pub enum Enum64 {
A(Align64), A(Align64),
B(i32), B(i32),
} }
// CHECK: %Enum64 = type { i32, [31 x i32] }
// CHECK-LABEL: @align64 // CHECK-LABEL: @align64
#[no_mangle] #[no_mangle]

View File

@ -42,7 +42,7 @@ pub fn borrow_call(x: &i32, f: fn(&i32) -> &i32) -> &i32 {
f(x) f(x)
} }
// CHECK: void @struct_(ptr sret(%S) align 4{{( %_0)?}}, ptr align 4 %x) // CHECK: void @struct_(ptr sret([32 x i8]) align 4{{( %_0)?}}, ptr align 4 %x)
#[no_mangle] #[no_mangle]
pub fn struct_(x: S) -> S { pub fn struct_(x: S) -> S {
x x
@ -51,7 +51,7 @@ pub fn struct_(x: S) -> S {
// CHECK-LABEL: @struct_call // CHECK-LABEL: @struct_call
#[no_mangle] #[no_mangle]
pub fn struct_call(x: S, f: fn(S) -> S) -> S { pub fn struct_call(x: S, f: fn(S) -> S) -> S {
// CHECK: call void %f(ptr sret(%S) align 4{{( %_0)?}}, ptr align 4 %{{.+}}) // CHECK: call void %f(ptr sret([32 x i8]) align 4{{( %_0)?}}, ptr align 4 %{{.+}})
f(x) f(x)
} }

View File

@ -188,7 +188,7 @@ pub fn notunpin_box(x: Box<NotUnpin>) -> Box<NotUnpin> {
x x
} }
// CHECK: @struct_return(ptr noalias nocapture noundef sret(%S) align 4 dereferenceable(32){{( %_0)?}}) // CHECK: @struct_return(ptr noalias nocapture noundef sret([32 x i8]) align 4 dereferenceable(32){{( %_0)?}})
#[no_mangle] #[no_mangle]
pub fn struct_return() -> S { pub fn struct_return() -> S {
S { S {

View File

@ -23,7 +23,7 @@ pub fn replace_big(dst: &mut Big, src: Big) -> Big {
// CHECK-NOT: call void @llvm.memcpy // CHECK-NOT: call void @llvm.memcpy
// For a large type, we expect exactly three `memcpy`s // For a large type, we expect exactly three `memcpy`s
// CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret(%Big) // CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret([56 x i8])
// CHECK-NOT: call void @llvm.memcpy // CHECK-NOT: call void @llvm.memcpy
// CHECK: call void @llvm.memcpy.{{.+}}(ptr align 8 %result, ptr align 8 %dest, i{{.*}} 56, i1 false) // CHECK: call void @llvm.memcpy.{{.+}}(ptr align 8 %result, ptr align 8 %dest, i{{.*}} 56, i1 false)
// CHECK-NOT: call void @llvm.memcpy // CHECK-NOT: call void @llvm.memcpy

View File

@ -34,19 +34,19 @@ pub enum TeBigS {
Variant(BigS), Variant(BigS),
} }
// CHECK: define{{.*}}void @test_BigS(ptr [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], ptr [[BIGS_ARG_ATTRS1:.*]] byval(%BigS) [[BIGS_ARG_ATTRS2:.*]]) // 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] #[no_mangle]
pub extern "C" fn test_BigS(_: BigS) -> BigS { loop {} } pub extern "C" fn test_BigS(_: BigS) -> BigS { loop {} }
// CHECK: define{{.*}}void @test_TsBigS(ptr [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]] byval(%TsBigS) [[BIGS_ARG_ATTRS2:.*]]) // 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] #[no_mangle]
pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} } pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
// CHECK: define{{.*}}void @test_TuBigS(ptr [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]] byval(%TuBigS) [[BIGS_ARG_ATTRS2:.*]]) // 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] #[no_mangle]
pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} } pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
// CHECK: define{{.*}}void @test_TeBigS(ptr [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]] byval(%"TeBigS::Variant") [[BIGS_ARG_ATTRS2]]) // 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] #[no_mangle]
pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} } pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
@ -70,18 +70,18 @@ pub enum TeBigU {
Variant(BigU), Variant(BigU),
} }
// CHECK: define{{.*}}void @test_BigU(ptr [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1:.*]] byval(%BigU) [[BIGU_ARG_ATTRS2:.*]]) // 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] #[no_mangle]
pub extern "C" fn test_BigU(_: BigU) -> BigU { loop {} } pub extern "C" fn test_BigU(_: BigU) -> BigU { loop {} }
// CHECK: define{{.*}}void @test_TsBigU(ptr [[BIGU_RET_ATTRS1:.*]] sret(%TsBigU) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]] byval(%TsBigU) [[BIGU_ARG_ATTRS2]]) // 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] #[no_mangle]
pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} } pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
// CHECK: define{{.*}}void @test_TuBigU(ptr [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]] byval(%TuBigU) [[BIGU_ARG_ATTRS2]]) // 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] #[no_mangle]
pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} } pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
// CHECK: define{{.*}}void @test_TeBigU(ptr [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]] byval(%"TeBigU::Variant") [[BIGU_ARG_ATTRS2]]) // 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] #[no_mangle]
pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} } pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }

View File

@ -3,7 +3,7 @@
// See #87254. // See #87254.
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(repr_simd)] #![feature(repr_simd, abi_unadjusted)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(simd)] #[repr(simd)]
@ -14,6 +14,6 @@
// CHECK: %int16x4x2_t = type { <4 x i16>, <4 x i16> } // CHECK: %int16x4x2_t = type { <4 x i16>, <4 x i16> }
#[no_mangle] #[no_mangle]
fn takes_int16x4x2_t(t: int16x4x2_t) -> int16x4x2_t { extern "unadjusted" fn takes_int16x4x2_t(t: int16x4x2_t) -> int16x4x2_t {
t t
} }