-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
repr(simd) is unsound in C FFI #53346
Comments
How do we expect linker to know about ABI? Target features or vector-ness is not encoded into symbols at all. |
No idea, maybe this isn't possible at all. Another issue here is how does the programmer know which ABI to use when writing a |
@gnzlbg the problems here look spot on, thanks for writing this up! I'm personally at a loss of how to solve it :( |
Probably, the poorest possible solution to this problem would be to only enable the architecture specific vector types on C FFI, specify their ABI to be a single register, and only allow them when they are guaranteed to work. That is, the above example would look like this: extern "C" {
#[cfg(target_feature = "avx")]
fn foo(x: __m256) -> _m256; // OK
#[cfg(target_feature = "sse")]
fn bar(x: __m128) -> __m128; // OK
fn baz(x: __m256); // ERROR IFF cfg!(target_feature="avx") is false
} AFAICT this is guaranteed to work because the Since the purpose of the C FFI is first and foremost to interface with C, and the architecture specific vector types are the SIMD types that most C libraries use on their APIs this would be enough to cover that use case. If we ever figure out how to handle "portable packed vectors" (e.g. Right now the architecture-specific vector types are just normal packed vector types. This might mean that we would need to make them "special". |
I want to submit an RFC to fix this, I'd like feedback on the general approach (@parched @gankro @alexcrichton @rkruppe ): Some unknowns:
pre-RFC:
|
@gnzlbg requiring the correct FWIW allowing |
I've submitted an RFC: rust-lang/rfcs#2574 |
@rust-lang/wg-triage This is a soundness issue, I believe it should have the appropriate label added. |
That RFC was merged, is this issue fixed? |
@DemiMarie The RFC hasn't been implemented yet, see #63068. gnzlbg and I tried to implement but PRs weren't merged (I haven't had enough time to debug it and address review comments :( ). |
Unfortunately SIMD types are not FFI safe, see rust-lang/rust#53346
This is fixed by #116558, I think -- for now just a warning, but it will become a hard error. |
This supersedes #44367 - after #47743 the unsoundness has been restricted to C FFI. The Rust ABI for vector types currently passes all types by memory.
There are sadly many C libraries that use vector types in their ABIs, some of which are pretty much "fundamental" like some of the short-vector math libraries:
libmvec
, SVML, etc.As a summary of the previous issue, currently, the behavior of calling
bar
, `the following snippet of Rust code is sometimes undefined:When both the Rust program and the C library exposing foo are compiled with the same set of target-features such that their ABIs match, then the program above will work as expected.
When the C library is compiled with say AVX2, but the Rust program is compiled with SSE4.2, then Rust will try to pass the F32x8 in two 128-bit wide vector registers to C, while the C code only expects a single 256-bit wide vector. A similar problem occurs in the opposite case.
cc @rkruppe @parched @alexcrichton @eddyb - did I correctly represent the problem ?
A potential solution discussed in #44367 would be to completely forbid vector types in FFI functions that do not specify their vector ABI:
If the C library linked does not expose the specified ABIs for
foo
andbar
, the program would fail to link, preventing undefined behavior.The text was updated successfully, but these errors were encountered: