Skip to content

Commit

Permalink
Set attrs.pointee_align when constructing function ABI
Browse files Browse the repository at this point in the history
Fixes rust-lang#80127

This will require additional testing to see if the old FIXME still
applies
  • Loading branch information
Aaron1011 committed Jan 8, 2021
1 parent ddf2cc7 commit 0bb51f8
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 7 deletions.
4 changes: 1 addition & 3 deletions compiler/rustc_target/src/abi/call/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,9 +449,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
// program-invisible so can't possibly capture
attrs.set(ArgAttribute::NoAlias).set(ArgAttribute::NoCapture).set(ArgAttribute::NonNull);
attrs.pointee_size = self.layout.size;
// FIXME(eddyb) We should be doing this, but at least on
// i686-pc-windows-msvc, it results in wrong stack offsets.
// attrs.pointee_align = Some(self.layout.align.abi);
attrs.pointee_align = Some(self.layout.align.abi);

let extra_attrs = self.layout.is_unsized().then_some(ArgAttributes::new());

Expand Down
4 changes: 2 additions & 2 deletions src/test/codegen/function-arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub fn mutable_unsafe_borrow(_: &mut UnsafeInner) {
pub fn mutable_borrow(_: &mut i32) {
}

// CHECK: @indirect_struct(%S* noalias nocapture dereferenceable(32) %_1)
// CHECK: @indirect_struct(%S* noalias nocapture align 4 dereferenceable(32) %_1)
#[no_mangle]
pub fn indirect_struct(_: S) {
}
Expand All @@ -73,7 +73,7 @@ pub fn _box(x: Box<i32>) -> Box<i32> {
x
}

// CHECK: @struct_return(%S* noalias nocapture sret dereferenceable(32){{( %0)?}})
// CHECK: @struct_return(%S* noalias nocapture sret align 4 dereferenceable(32){{( %0)?}})
#[no_mangle]
pub fn struct_return() -> S {
S {
Expand Down
63 changes: 63 additions & 0 deletions src/test/codegen/issue-80127-arg-align.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// ignore-tidy-linelength
// only-x86_64

// Regression test for issue 80127
// Tests that we properly propagate apply a `#[repr(align)]` attribute on a struct
// to external function definitions involving parameters with that struct type

#[repr(C)]
#[repr(align(16))]
#[derive(Debug, Copy, Clone)]
pub struct bar {
pub a: ::std::os::raw::c_ulong,
pub b: ::std::os::raw::c_ulong,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct baz {
pub a: bool,
pub b: ::std::os::raw::c_uint,
}

extern "C" {
// CHECK: declare i32 @foo_func(i8*, i8*, i8*, i64, i1 zeroext, i64, i8*, %bar* noalias nocapture byval(%bar) align 16 dereferenceable(16), i8*, i8*, i8*, i8*, i8*)
pub fn foo_func(
a: *mut ::std::os::raw::c_void,
b: *mut ::std::os::raw::c_void,
c: *const ::std::os::raw::c_char,
d: ::std::os::raw::c_ulong,
e: bool,
f: baz,
g: *mut ::std::os::raw::c_void,
h: bar,
i: *mut ::std::os::raw::c_void,
j: *mut ::std::os::raw::c_void,
k: *mut ::std::os::raw::c_void,
l: *mut ::std::os::raw::c_void,
m: *const ::std::os::raw::c_char,
) -> ::std::os::raw::c_int;
}

fn main() {
let f = baz { a: true, b: 67 };
let h = bar { a: 0, b: 99 };
let m = std::ffi::CString::new("Hello, world").unwrap();
unsafe {
foo_func(
std::ptr::null_mut(),
std::ptr::null_mut(),
std::ptr::null_mut(),
12,
true,
f,
std::ptr::null_mut(),
h,
std::ptr::null_mut(),
std::ptr::null_mut(),
std::ptr::null_mut(),
std::ptr::null_mut(),
m.as_ptr(),
)
};
}
4 changes: 2 additions & 2 deletions src/test/codegen/packed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub struct BigPacked2 {
#[no_mangle]
pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
// CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]])
// CHECK: call void %{{.*}}(%Array* noalias nocapture sret align 4 dereferenceable(32) [[ALLOCA]])
// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 %{{.*}}, i8* align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
// check that calls whose destination is a field of a packed struct
// go through an alloca rather than calling the function with an
Expand All @@ -64,7 +64,7 @@ pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
#[no_mangle]
pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 {
// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
// CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]])
// CHECK: call void %{{.*}}(%Array* noalias nocapture sret align 4 dereferenceable(32) [[ALLOCA]])
// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 2 %{{.*}}, i8* align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
// check that calls whose destination is a field of a packed struct
// go through an alloca rather than calling the function with an
Expand Down

0 comments on commit 0bb51f8

Please sign in to comment.