-
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
Ignore ZST offsets when deciding whether to use Scalar/ScalarPair layout #73453
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @petrochenkov (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
AFAIR, this restriction was introduced to be able to do DST coercions, but I'm not sure whether this applies to tuples. r? @RalfJung |
Yep, this PR miscompiles the following code :( #![feature(unsized_tuple_coercion)]
pub type Siz = (u8, [u32; 2]);
pub type Un = (u8, [u32]);
pub fn coercion(x: &Siz) -> &Un {
x
} LLVM IRdefine { { [0 x i8], i8, [3 x i8], [0 x i32] }*, i64 } @_ZN4test8coercion17h76ca7bfe6ae8dcf2E({ [0 x i32], [2 x i32], [0 x i8], i8, [3 x i8] }* noalias readonly align 4 dereferenceable(12) %x) unnamed_addr #0 {
start:
%0 = bitcast { [0 x i32], [2 x i32], [0 x i8], i8, [3 x i8] }* %x to { [0 x i8], i8, [3 x i8], [0 x i32] }*
%1 = insertvalue { { [0 x i8], i8, [3 x i8], [0 x i32] }*, i64 } undef, { [0 x i8], i8, [3 x i8], [0 x i32] }* %0, 0
%2 = insertvalue { { [0 x i8], i8, [3 x i8], [0 x i32] }*, i64 } %1, i64 2, 1
ret { { [0 x i8], i8, [3 x i8], [0 x i32] }*, i64 } %2
} Should I: limit this to types that don't implement |
This is way outside my league I'm afraid.^^ But AFAIK it is indeed impossible to reorder the last field due to unsizing coercions.
That would definitely be a good idea. I cannot give any advice on the other alternatives, sorry. Cc @eddyb (but they are very busy recently)... not sure whom else to ping? Cc @nikomatsakis |
r? @nikomatsakis -- I'll take a look and try to give intelligent feedback :) |
083d75a
to
1882bdb
Compare
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.
Changed to instead allow reordering of the last field of a MaybeUnsized struct iff it's a ZST, which I think is most likely to be viable (if anything is).
src/librustc_middle/ty/layout.rs
Outdated
// This will reorder the last field if it is a ZST, which is okay because | ||
// there's nothing in memory that could be accessed through an unsized type. |
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.
I'm not sure if this is actually okay.
1882bdb
to
7336e5f
Compare
Well, the logic makes some sense to me, at least, but I'd like to hear what @eddyb thinks, as they definitely know this code best (I'm not all that familiar with it, to be honest). I guess the "other way around" here would be not to reorder fields but to make the checks and code that are failing with the current ordering more capable? I guess in any case that the logic is that we can 'permute' the offset of ZST fields arbitrarily, since there is no memory to be accessed? The offset might be visible in other ways (e.g., computing raw pointers and converting them to integers), not sure if that's a concern. I guess the layout of tuples is largely undefined... Also, just as a point of "curiosity", I think that -- in general -- it's actually plausible for us to reorder DST fields even if they are not last, so long as we can recover not only the alignment of the field but also its size, but it would then require us to do the arithmetic at runtime to compute the offsets of all other fields, something we've traditionally avoided for its complexity. |
Yeah, it's possible that the following check could be removed instead: rust/src/librustc_middle/ty/layout.rs Lines 393 to 395 in b7856f6
The relevant parts of layout haven't changed significantly since eddyb's original #45225 so I eagerly await their comments :) |
@eddyb This is a triage bump. |
r? @eddyb Make it official we're waiting for their feedback here=) |
Ugh I'm really sorry, I only now got a triage PM about this, I don't recall seeing this PR before (I guess I haven't gotten around to checking the PRs assigned to me in the last 18 days - in general, feel free to PM me on Zulip). This looks fine, I guess, I'm only worried about the perf loss from sorting twice (which I'm not sure can be avoided). @bors try @rust-timer queue |
Awaiting bors try build completion |
⌛ Trying commit 7336e5f48c72e3606f8e496daa21890f9415d881 with merge 9ebc0face0731b2ce4ff7382be873c6f734a0c50... |
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.
Sorry about forgetting about Abi::Vector
until the last moment, but it's also important (it also has #[repr(transparent)]
support etc.).
You could/should also add tests for it but I'm not sure what type to use (maybe you can find a #[repr(transparent)]
test that also tests Abi::Vector
using #[repr(simd)]
or similar?).
@bors r- |
Also, I should say, this shouldn't cause more codegen than today, since any ZSTs that were reordered to the start, still are (that part of the code wasn't changed at all), so they will still get no offset applied. The new byte-based offset will pretty much only replace an identical offset being applied as a "struct field", but both should result in the same machine code (barring any LLVM optimizations but since this is about ZSTs, I'm not worried about that). |
This comment has been minimized.
This comment has been minimized.
7b7168b
to
24e0913
Compare
@eddyb this is ready for another round of review. @erikdesjardins please write a note in the PR when this is ready for review again; GitHub does not (reliably) send email notifications for force pushes. |
I messaged @eddyb on Zulip as they mentioned above, but yeah I should probably still comment so other people know what's going on. |
@rustbot modify labels: -S-waiting-on-author, +S-waiting-on-review |
I got the Zulip PM but then because of how Zulip forces you to always see messages when navigating, it marked it as read, I'm really sorry. I'm still generally months behind most things on GitHub (and even waiting-on-review PRs) but trying to help where I can (don't mind repeated PMs, it helps with various platforms being all over the place). @bors r+ |
📌 Commit 24e0913 has been approved by |
☀️ Test successful - checks-actions, checks-azure |
This is important because Scalar/ScalarPair layout previously would not be used if any ZST had nonzero offset.
For example, before this change, only
((), u128)
would be laid out likeu128
, not(u128, ())
.Fixes #63244