forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
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 rust-lang#103830 - pcwalton:pointee-align, r=oli-obk
rustc_target: Add alignment to indirectly-passed by-value types, correcting the alignment of `byval` on x86 in the process. Commit 88e4d2c from five years ago removed support for alignment on indirectly-passed arguments because of problems with the `i686-pc-windows-msvc` target. Unfortunately, the `memcpy` optimizations I recently added to LLVM 16 depend on this to forward `memcpy`s. This commit attempts to fix the problems with `byval` parameters on that target and now correctly adds the `align` attribute. The problem is summarized in [this comment] by `@eddyb.` Briefly, 32-bit x86 has special alignment rules for `byval` parameters: for the most part, their alignment is forced to 4. This is not well-documented anywhere but in the Clang source. I looked at the logic in Clang `TargetInfo.cpp` and tried to replicate it here. The relevant methods in that file are `X86_32ABIInfo::getIndirectResult()` and `X86_32ABIInfo::getTypeStackAlignInBytes()`. The `align` parameter attribute for `byval` parameters in LLVM must match the platform ABI, or miscompilations will occur. Note that this doesn't use the approach suggested by eddyb, because I felt it was overkill to store the alignment in `on_stack` when special handling is really only needed for 32-bit x86. As a side effect, this should fix rust-lang#80127, because it will make the `align` parameter attribute for `byval` parameters match the platform ABI on LLVM x86-64. [this comment]: rust-lang#80822 (comment)
- Loading branch information
Showing
11 changed files
with
208 additions
and
17 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
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,56 @@ | ||
// ignore-x86 | ||
// ignore-aarch64 | ||
// ignore-aarch64_be | ||
// ignore-arm | ||
// ignore-armeb | ||
// ignore-avr | ||
// ignore-bpfel | ||
// ignore-bpfeb | ||
// ignore-hexagon | ||
// ignore-mips | ||
// ignore-mips64 | ||
// ignore-msp430 | ||
// ignore-powerpc64 | ||
// ignore-powerpc64le | ||
// ignore-powerpc | ||
// ignore-r600 | ||
// ignore-amdgcn | ||
// ignore-sparc | ||
// ignore-sparcv9 | ||
// ignore-sparcel | ||
// ignore-s390x | ||
// ignore-tce | ||
// ignore-thumb | ||
// ignore-thumbeb | ||
// ignore-xcore | ||
// ignore-nvptx | ||
// ignore-nvptx64 | ||
// ignore-le32 | ||
// ignore-le64 | ||
// ignore-amdil | ||
// ignore-amdil64 | ||
// ignore-hsail | ||
// ignore-hsail64 | ||
// ignore-spir | ||
// ignore-spir64 | ||
// ignore-kalimba | ||
// ignore-shave | ||
// | ||
// Tests that `byval` alignment is properly specified (#80127). | ||
// The only targets that use `byval` are m68k, wasm, x86-64, and x86. Note that | ||
// x86 has special rules (see #103830), and it's therefore ignored here. | ||
|
||
#[repr(C)] | ||
#[repr(align(16))] | ||
struct Foo { | ||
a: [i32; 16], | ||
} | ||
|
||
extern "C" { | ||
// CHECK: declare void @f({{.*}}byval(%Foo) align 16{{.*}}) | ||
fn f(foo: Foo); | ||
} | ||
|
||
pub fn main() { | ||
unsafe { f(Foo { a: [1; 16] }) } | ||
} |
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,5 @@ | ||
include ../tools.mk | ||
|
||
all: $(call NATIVE_STATICLIB,test) | ||
$(RUSTC) test.rs | ||
$(call RUN,test) || exit 1 |
35 changes: 35 additions & 0 deletions
35
src/test/run-make-fulldeps/extern-fn-explicit-align/test.c
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,35 @@ | ||
#include <assert.h> | ||
#include <stdbool.h> | ||
#include <stdint.h> | ||
#include <string.h> | ||
|
||
struct TwoU64s | ||
{ | ||
uint64_t a; | ||
uint64_t b; | ||
} __attribute__((aligned(16))); | ||
|
||
struct BoolAndU32 | ||
{ | ||
bool a; | ||
uint32_t b; | ||
}; | ||
|
||
int32_t many_args( | ||
void *a, | ||
void *b, | ||
const char *c, | ||
uint64_t d, | ||
bool e, | ||
struct BoolAndU32 f, | ||
void *g, | ||
struct TwoU64s h, | ||
void *i, | ||
void *j, | ||
void *k, | ||
void *l, | ||
const char *m) | ||
{ | ||
assert(strcmp(m, "Hello world") == 0); | ||
return 0; | ||
} |
61 changes: 61 additions & 0 deletions
61
src/test/run-make-fulldeps/extern-fn-explicit-align/test.rs
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,61 @@ | ||
// Issue #80127: Passing structs via FFI should work with explicit alignment. | ||
|
||
use std::ffi::CString; | ||
use std::ptr::null_mut; | ||
|
||
#[derive(Clone, Copy, Debug, PartialEq)] | ||
#[repr(C)] | ||
#[repr(align(16))] | ||
pub struct TwoU64s { | ||
pub a: u64, | ||
pub b: u64, | ||
} | ||
|
||
#[repr(C)] | ||
#[derive(Debug, Copy, Clone)] | ||
pub struct BoolAndU32 { | ||
pub a: bool, | ||
pub b: u32, | ||
} | ||
|
||
#[link(name = "test", kind = "static")] | ||
extern "C" { | ||
fn many_args( | ||
a: *mut (), | ||
b: *mut (), | ||
c: *const i8, | ||
d: u64, | ||
e: bool, | ||
f: BoolAndU32, | ||
g: *mut (), | ||
h: TwoU64s, | ||
i: *mut (), | ||
j: *mut (), | ||
k: *mut (), | ||
l: *mut (), | ||
m: *const i8, | ||
) -> i32; | ||
} | ||
|
||
fn main() { | ||
let two_u64s = TwoU64s { a: 1, b: 2 }; | ||
let bool_and_u32 = BoolAndU32 { a: true, b: 3 }; | ||
let string = CString::new("Hello world").unwrap(); | ||
unsafe { | ||
many_args( | ||
null_mut(), | ||
null_mut(), | ||
null_mut(), | ||
4, | ||
true, | ||
bool_and_u32, | ||
null_mut(), | ||
two_u64s, | ||
null_mut(), | ||
null_mut(), | ||
null_mut(), | ||
null_mut(), | ||
string.as_ptr(), | ||
); | ||
} | ||
} |