-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of #122212 - erikdesjardins:byval-align2, r=wesleywiser
Copy byval argument to alloca if alignment is insufficient Fixes #122211 "Ignore whitespace" recommended.
- Loading branch information
Showing
4 changed files
with
221 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |