Skip to content
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

make sure ScalarPair enums have ScalarPair variants; add some layout sanity checks #96872

Merged
merged 3 commits into from
May 10, 2022

Conversation

RalfJung
Copy link
Member

@RalfJung RalfJung commented May 9, 2022

@eddyb suggested that it might be reasonable for ScalarPair enums to simply adjust the ABI of their variants accordingly, such that the layout invariant Miri expects actually holds. This PR implements that. I should note though that I don't know much about this layout computation code and what non-Miri consumers expect from it, so tread with caution!

I also added a function to sanity-check that computed layouts are internally consistent. This helped a lot in figuring out the final shape of this PR, though I am also not 100% sure that these sanity checks are the right ones.

Cc @oli-obk
Fixes #96221

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label May 9, 2022
@rust-highfive
Copy link
Collaborator

r? @nagisa

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 9, 2022
// Would result in ICE see the issue #92464 for more info
if tag.size(dl) == size || variants.iter().all(|layout| layout.is_empty()) {
if layout_variants.iter().all(|v| v.abi.is_uninhabited()) {
abi = Abi::Uninhabited;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reordered this a bit so it better fits the pattern of these three branches here computing the abi.

Rewriting this without mutable variables would be cleaner but that is an undertaking for someone else. ;)

Copy link
Member

@eddyb eddyb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=me with the immediately actionable comments resolved

assert!(layout.abi.is_uninhabited());
}

if cfg!(debug_assertions) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should at some point measure the cost of having this on by default.

compiler/rustc_middle/src/ty/layout.rs Outdated Show resolved Hide resolved
Union {
value: Int(
I8,
false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this makes me wish there was an enum Signedness { Unsigned, Signed } instead of a bool, heh.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... and also nicer debug-printing of Scalar layouts. Another time.^^

compiler/rustc_middle/src/ty/layout.rs Outdated Show resolved Hide resolved
Comment on lines 251 to 259
Abi::ScalarPair(scalar1, scalar2) => {
// Sanity-check scalar pair size.
let field2_offset = scalar1.size(&tcx).align_to(scalar2.align(&tcx).abi);
let total = field2_offset + scalar2.size(&tcx);
assert!(
layout.size() >= total,
"size mismatch between ABI and layout in {layout:#?}"
);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, shouldn't this also have an alignment check?

Honestly, reusing LayoutCx::scalar_pair would probably make this really straight-forward (and maybe some miri/codegen code as well, tho in that case it should be a Layout constructor rather than on LayoutCx) - except for the fact that it allocates two Vecs (if only they were SmallVec<[_; 2]>... - more things that aren't immediately actionable sigh)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure what the alignment check would be, so this felt like better than nothing. 🤷

I don't see how this could reuse scalar_pair; things with ScalarPair ABI can have any number of fields since there can be newtypes around the underlying pair.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, the fields would need to be ignored wrt validation (but e.g. codegen could use the offset of the second field to avoid computing a_size.align_to(b_align) itself).

Anyway, not that viable today with the allocations.

@RalfJung
Copy link
Member Author

RalfJung commented May 9, 2022

That codegen test failure is odd. For some reason "Enum4::A" is not in the LLVM IR at all any more?

@eddyb
Copy link
Member

eddyb commented May 9, 2022

That codegen test failure is odd. For some reason "Enum4::A" is not in the LLVM IR at all any more?

That would make sense, I think, IIRC only Abi::Aggregate results in LLVM types with specific names.

@RalfJung
Copy link
Member Author

RalfJung commented May 9, 2022

@eddyb I think I took care of all your comments, but it might be good for you to have another look. :)

@rust-log-analyzer

This comment has been minimized.

@eddyb
Copy link
Member

eddyb commented May 9, 2022

r=me once fixing the vector check, just noticed that's failing (there's a vector_align method somewhere, I think, that's supposed to give you the alignment that you then have to apply to your multiplication result).

IIUC, this is what causes the weirdness where, say, 3 (or 5-7) element vectors end up with the same size as vectors of 4 (or 8) elements (on some targets, for some element types).

@RalfJung
Copy link
Member Author

RalfJung commented May 9, 2022

@bors r=eddyb

@bors
Copy link
Contributor

bors commented May 9, 2022

📌 Commit 02eca34 has been approved by eddyb

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 9, 2022
bors added a commit to rust-lang-ci/rust that referenced this pull request May 10, 2022
Rollup of 5 pull requests

Successful merges:

 - rust-lang#93661 (Add missing rustc arg docs)
 - rust-lang#96674 (docs: add link explaining variance to NonNull docs)
 - rust-lang#96812 (Do not lint on explicit outlives requirements from external macros.)
 - rust-lang#96823 (Properly fix rust-lang#96638)
 - rust-lang#96872 (make sure ScalarPair enums have ScalarPair variants; add some layout sanity checks)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit ec53c37 into rust-lang:master May 10, 2022
@rustbot rustbot added this to the 1.62.0 milestone May 10, 2022
@RalfJung RalfJung deleted the layout-sanity branch May 12, 2022 07:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

For enums with ScalarPair ABI, some variants have Aggregate ABI
7 participants