diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-03-14 20:00:18 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-14 20:00:18 +0100 |
| commit | 722514f46626bbc1af8525f8f31c9a089f5b4f0f (patch) | |
| tree | 0fbfa39a2b20c069bad231a8e83cfa3fcc002409 /tests/codegen | |
| parent | 4dff106433c3aa57c99b780232ffd3a52592d5de (diff) | |
| parent | 818f13095ac79db831078c7a2b3dede90eecf86f (diff) | |
| download | rust-722514f46626bbc1af8525f8f31c9a089f5b4f0f.tar.gz rust-722514f46626bbc1af8525f8f31c9a089f5b4f0f.zip | |
Rollup merge of #122212 - erikdesjardins:byval-align2, r=wesleywiser
Copy byval argument to alloca if alignment is insufficient Fixes #122211 "Ignore whitespace" recommended.
Diffstat (limited to 'tests/codegen')
| -rw-r--r-- | tests/codegen/align-byval-alignment-mismatch.rs | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/tests/codegen/align-byval-alignment-mismatch.rs b/tests/codegen/align-byval-alignment-mismatch.rs new file mode 100644 index 00000000000..306e3ce1358 --- /dev/null +++ b/tests/codegen/align-byval-alignment-mismatch.rs @@ -0,0 +1,126 @@ +// ignore-tidy-linelength +//@ revisions:i686-linux x86_64-linux + +//@[i686-linux] compile-flags: --target i686-unknown-linux-gnu +//@[i686-linux] needs-llvm-components: x86 +//@[x86_64-linux] compile-flags: --target x86_64-unknown-linux-gnu +//@[x86_64-linux] needs-llvm-components: x86 + +// Tests that we correctly copy arguments into allocas when the alignment of the byval argument +// is different from the alignment of the Rust type. + +// For the following test cases: +// All of the `*_decreases_alignment` functions should codegen to a direct call, since the +// alignment is already sufficient. +// All off the `*_increases_alignment` functions should copy the argument to an alloca +// on i686-unknown-linux-gnu, since the alignment needs to be increased, and should codegen +// to a direct call on x86_64-unknown-linux-gnu, where byval alignment matches Rust alignment. + +#![feature(no_core, lang_items)] +#![crate_type = "lib"] +#![no_std] +#![no_core] +#![allow(non_camel_case_types)] + +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} + +// This type has align 1 in Rust, but as a byval argument on i686-linux, it will have align 4. +#[repr(C)] +#[repr(packed)] +struct Align1 { + x: u128, + y: u128, + z: u128, +} + +// This type has align 16 in Rust, but as a byval argument on i686-linux, it will have align 4. +#[repr(C)] +#[repr(align(16))] +struct Align16 { + x: u128, + y: u128, + z: u128, +} + +extern "C" { + fn extern_c_align1(x: Align1); + fn extern_c_align16(x: Align16); +} + +// CHECK-LABEL: @rust_to_c_increases_alignment +#[no_mangle] +pub unsafe fn rust_to_c_increases_alignment(x: Align1) { + // i686-linux: start: + // i686-linux-NEXT: [[ALLOCA:%[0-9a-z]+]] = alloca %Align1, align 4 + // i686-linux-NEXT: call void @llvm.memcpy.{{.+}}(ptr {{.*}}align 4 {{.*}}[[ALLOCA]], ptr {{.*}}align 1 {{.*}}%x + // i686-linux-NEXT: call void @extern_c_align1({{.+}} [[ALLOCA]]) + + // x86_64-linux: start: + // x86_64-linux-NEXT: call void @extern_c_align1 + extern_c_align1(x); +} + +// CHECK-LABEL: @rust_to_c_decreases_alignment +#[no_mangle] +pub unsafe fn rust_to_c_decreases_alignment(x: Align16) { + // CHECK: start: + // CHECK-NEXT: call void @extern_c_align16 + extern_c_align16(x); +} + +extern "Rust" { + fn extern_rust_align1(x: Align1); + fn extern_rust_align16(x: Align16); +} + +// CHECK-LABEL: @c_to_rust_decreases_alignment +#[no_mangle] +pub unsafe extern "C" fn c_to_rust_decreases_alignment(x: Align1) { + // CHECK: start: + // CHECK-NEXT: call void @extern_rust_align1 + extern_rust_align1(x); +} + +// CHECK-LABEL: @c_to_rust_increases_alignment +#[no_mangle] +pub unsafe extern "C" fn c_to_rust_increases_alignment(x: Align16) { + // i686-linux: start: + // i686-linux-NEXT: [[ALLOCA:%[0-9a-z]+]] = alloca %Align16, align 16 + // i686-linux-NEXT: call void @llvm.memcpy.{{.+}}(ptr {{.*}}align 16 {{.*}}[[ALLOCA]], ptr {{.*}}align 4 {{.*}}%0 + // i686-linux-NEXT: call void @extern_rust_align16({{.+}} [[ALLOCA]]) + + // x86_64-linux: start: + // x86_64-linux-NEXT: call void @extern_rust_align16 + extern_rust_align16(x); +} + +extern "Rust" { + fn extern_rust_ref_align1(x: &Align1); + fn extern_rust_ref_align16(x: &Align16); +} + +// CHECK-LABEL: @c_to_rust_ref_decreases_alignment +#[no_mangle] +pub unsafe extern "C" fn c_to_rust_ref_decreases_alignment(x: Align1) { + // CHECK: start: + // CHECK-NEXT: call void @extern_rust_ref_align1 + extern_rust_ref_align1(&x); +} + +// CHECK-LABEL: @c_to_rust_ref_increases_alignment +#[no_mangle] +pub unsafe extern "C" fn c_to_rust_ref_increases_alignment(x: Align16) { + // i686-linux: start: + // i686-linux-NEXT: [[ALLOCA:%[0-9a-z]+]] = alloca %Align16, align 16 + // i686-linux-NEXT: call void @llvm.memcpy.{{.+}}(ptr {{.*}}align 16 {{.*}}[[ALLOCA]], ptr {{.*}}align 4 {{.*}}%0 + // i686-linux-NEXT: call void @extern_rust_ref_align16({{.+}} [[ALLOCA]]) + + // x86_64-linux: start: + // x86_64-linux-NEXT: call void @extern_rust_ref_align16 + extern_rust_ref_align16(&x); +} |
