-
Notifications
You must be signed in to change notification settings - Fork 13.4k
repr(simd) is unsound in C FFI #53346
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
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. |
Uh oh!
There was an error while loading. Please reload this page.
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: