don't pass Complex<f16> in vector registers on i586 without SSE2 - #161814
folkertdev wants to merge 1 commit into
Conversation
|
|
| if let Some(Float::F16) = fn_abi.ret.layout.complex_float(cx) { | ||
| // `_Complex _Float16` is returned as `<2 x half>`. | ||
| if let Some(Float::F16) = fn_abi.ret.layout.complex_float(cx) | ||
| && cx.target_spec().rustc_abi == Some(RustcAbi::X86Sse2) |
There was a problem hiding this comment.
There was a problem hiding this comment.
Yes? We have a separate compiler/rustc_target/src/callconv/x86_64.rs file, but there SSE2 is assumed.
|
Not sure I agree with this change. Before this PR, we're emitting an error if you try to pass |
|
The bigger picture here is that those libcalls will be called by the So then alternatively, on edit: my suggestion here is to only inline the libcall when there are ABI issues, otherwise the libcalls save some binary size and might in the future be more performant. |
|
If we only need this ABI internally for our own libcalls, we could use the "Rust" ABI rather than a non-standard extension to the "C" ABI. My main concern is that we shouldn't let people write or call |
|
On tier 2
Seems like a good idea.
Surely having the libcall in |
As far as I am concerned, it has a standard soft-float ABI, it's whatever clang does. ;) But for this case, even clang thinks it's better to emit an error rather than invent a new ABI. I don't want us to even more reckless than clang when it comes to making up ad-hoc extensions of the "C" ABI. |
Fair enough. Upon further testing, on x86-64 Clang seems support soft-float passing and returning |
No the idea is that by default you'd fall back to the version supplied by your libc, and only use the rust version when your libc does not provide one. Hence the binary size reduction. That reduction seems pretty marginal though.
We'd already inline the fast path (at least that is what
|
|
I think I misunderstood the suggestion of using |
|
There's too much going on in that PR, but I see some |
No, we should trigger |
|
I think there's no reason to make up an ABI. The intended behavior of |
Clang and GCC reject By that argument we should be emitting an error on IMO types that fall into this category should do the same thing as
If anything, making some form of improper-ctypes deny-by-default seems preferable to a hard error. |
I don't think this is accurate, they all seem to be passed indirectly so we should do the same https://c.godbolt.org/z/rG5a9rfsT. That is the case for returning though
I can see the argument for consistency with |
|
Bit-packing is also consistent with the small integer types? But yeah not consistent with the plain struct (https://godbolt.org/z/zEPzj4vqv).
What do you mean by this? |
And this is our plan for stabilizing |
What would
Is it? Not sure I like that... but anyway that's a topic for #131819. |
If you're working with complex types in C on platforms that don't officially support it, the fallback is likely It's a bit different but that's part of the motivation for Clang/GCC's recent changes to
It's still useful when you need some degree of ABI stability, Rust-to-Rust calls when a library is distributed or so. It would feel rather weird to me if we warn but otherwise accept improper-ctypes for types that can be represented in C but are definitely incompatible (e.g. non- |
I think that would be repeating the mistake we did with
I would call that "not repeating past mistakes". |
|
People also use Additionally, how would you propose to impose this restriction when the parameter type is a generic? Post-mono errors? Bury our head in the sand and pretend it can't happen (an approach we've used for several similar restrictions in the past)? |
Yes, I would be arguing that. Using
Yes. That's what we already do for SIMD types when required target features are missing. IMO it makes sense to treat
Those are bugs (or best-effort lints), not "bury the head in the sand". |
I could tolerate rejecting everything
For the time being, I don't see any reason some form of the change here shouldn't merge. We have a codegen fix for a very specific type that is otherwise not rejected - I'd much rather if that not be blocked on developing new lang policy. |
|
The codegen change proposed here is inconsistent with what we do for SIMD types in the same situation. Is there any other situation where we go out of our way to invent a non-standard extension for the "C" ABI? I view this as precedent for moving in a direction that is IMO the wrong one, and that the relevant teams have not decided on. I can't see how this is a mere "fix", it is as much a policy decision as my proposal. In fact it is basically deciding to move away from my proposal, as IIUC the behavior without this PR is what I proposed (post-mono check to reject invalid use of this type in "C" ABI calls/definitions). I would say accepting such code needs lang input much more so than rejecting it. Lang was involved in the SIMD type error that |
|
Currently, unsafe extern "C" {
// This function is defined in a C library that was built for `i686-unknown-linux-gnu`.
safe fn returns_complex_f16() -> Complex<f16>;
}
// #[target_feature(enable = "sse")] should theoretically work but currently causes an LLVM error.
#[target_feature(enable = "sse2")]
unsafe fn i_checked_sse2_is_enabled() -> Complex<f16> {
returns_complex_f16()
}But won't work if we merge this PR, creating an ABI break. We could of course say "the C ABI on (The alternative here would be to declare that |
|
☔ The latest upstream changes (presumably #163583) made this pull request unmergeable. Please resolve the merge conflicts by rebasing. |

View all comments
Passing as an
i32is in line with how the other complex values are passed (e.g.Complex<f32>is passed asi64).Clang just errors out on the use of
_Float16, see https://godbolt.org/z/bd1vT6b9s.r? @tgross35 or @RalfJung
cc @beetrees
Tracking issue: #154023