-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Emit error when calling/declaring functions with vectors that require missing target feature #127731
base: master
Are you sure you want to change the base?
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @RalfJung (or someone else) some time within the next two weeks. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
These commits modify the If this was unintentional then you should revert the changes before this PR is merged. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also add some tests so that we can see this check in action.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
ef2609c
to
e8302b3
Compare
Looks good for the initial draft, let's see what crater says. :) @bors try |
Emit error when calling/declaring functions with unavailable vectors. On some architectures, vector types may have a different ABI when relevant target features are enabled. As discussed in rust-lang/lang-team#235, this turns out to very easily lead to unsound code. This commit makes it an error to declare or call functions using those vector types in a context in which the corresponding target features are disabled, if using an ABI for which the difference is relevant. r? RalfJung
☀️ Try build successful - checks-actions |
@craterbot check |
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
We talked about this this the lang-docs call today. It'd be good to look into how this change might be documented in the Reference. It has some bearing on: |
One impact it has on the reference/docs is that we can entirely remove this section -- one can no longer cause ABI incompatibility UB using target features. That's a great win in my book. :) |
Sorry for the delay! To my understanding, the reference changes for this PR should be minimal. I suspect a paragraph along these lines should be sufficient to describe the behaviour:
|
IIRC the ABI for |
It actually is, but how it is is subtle (and somewhat confusing). From confirmation on the x86_64-psabi mailing list:
The TL;DR is that the psabi is supposed to treat failing to pass an SSEUP eightbyte in part of an xmm register (which naturally includes the containing ymm and zmm registers) the same as it would treat failing to pass any other class of eightbyte in a register - pass the whole value on the stack. Another way to think about it is that each eightbyte of an {x,y,z}mm register is a "separate" register that is used to pass SSEUP eightbytes. When passing __m128, __m256, or __m512 (as the first parameter/return), it's passed in {xmm0[0..64], xmm0[64..128], ymm0[128..192], ymm0[192..256], ...} and if any of those "registers" don't exist or are unavailable (ie. avx or avx512f are disabled), then we stop trying to pass the value in registers and pass the whole thing on the stack or return it in memory. clang's behaviour is to decay the SSEUP eightbytes that can't be passed into SSE (thus passing in memory and returning in xmm0:xmm1 for __m256 values), which is incorrect (there is an llvm bug open to this effect, and its acknowledged as a bug). SSEUP eightbytes are replaced with SSE eightbytes when they aren't immediately preceeded by SSE or SSEUP. |
Am I correct in understanding that
? |
Yes. Specifically, if caller and callee differ in this target feature, then the call is UB.
Yes -- it is somewhat questionable that we even let you name the |
The lang team discussed this in our triage meeting today.
Hopefully that addresses everything you all wanted from the lang team's side; we definitely want to see this move forward. |
I changed the code to emit future-compat lints instead. However, during the rebase I found some unexpected changes in unrelated tests (perhaps due to some subtle changes in the cycle resolution order in collector.rs? Just guessing here):
Another question that is IMO still open is whether https://doc.rust-lang.org/stable/std/primitive.fn.html#requirements-concerning-target-features should still be removed when making the change a future-compat lint instead. @pnkfelix, I think the code should be ready for review at this point. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I think we can leave that out of this PR, to delay the discussion until later. |
This comment has been minimized.
This comment has been minimized.
On some architectures, vector types may have a different ABI when relevant target features are enabled. As discussed in rust-lang/lang-team#235, this turns out to very easily lead to unsound code. This commit makes it an error to declare or call functions using those vector types in a context in which the corresponding target features are disabled, if using an ABI for which the difference is relevant.
On some architectures, vector types may have a different ABI depending on whether the relevant target features are enabled. (The ABI when the feature is disabled is often not specified, but LLVM implements some de-facto ABI.)
As discussed in rust-lang/lang-team#235, this turns out to very easily lead to unsound code.
This commit makes it a post-monomorphization error to declare or call functions using those vector types in a context in which the corresponding target features are disabled, if using an ABI for which the difference is relevant. This ensures that these functions are always called with a consistent ABI.
See the nomination comment for more discussion.
r? RalfJung
Fixes #116558