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

[x64][SysV] Classify empty structs for passing like padding #103799

Merged
merged 4 commits into from
Jun 28, 2024

Conversation

tomeksowi
Copy link
Contributor

The current implementation barred a struct containing empty struct fields from enregistration. This did not match the behavior of GCC & Clang on Linux and the System V ABI which says:

NO_CLASS This class is used as initializer in the algorithms. It will be used for padding and empty structures and unions.

Stems from #101796, part of #84834, cc @dotnet/samsung

The current implementation barred a struct containing empty struct fields from enregistration. This did not match the [System V ABI](https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf) which says "NO_CLASS This class is used as initializer in the algorithms. It will be used for padding and **empty structures** and unions". It also does not match the behavior of GCC & Clang on Linux.
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Jun 21, 2024
@jkotas
Copy link
Member

jkotas commented Jun 21, 2024

Could you please add some tests? src\tests\JIT\Directed\StructABI looks like a good place

@jkotas jkotas added area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI and removed area-crossgen2-coreclr labels Jun 21, 2024
Copy link
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

@jkotas
Copy link
Member

jkotas commented Jun 21, 2024

cc @dotnet/jit-contrib @jakobbotsch

// then the classification of this eightbyte might be NoClass. We can't hand a classification of NoClass to the JIT
// so set the class to Integer (as though the struct has a char[8] padding) if the class is NoClass.
//
// TODO: Fix JIT, NoClass eightbytes are valid and passing them is broken because of this.
Copy link
Member

Choose a reason for hiding this comment

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

Do you plan to fix this TODO in this PR?

Copy link
Contributor Author

@tomeksowi tomeksowi Jun 21, 2024

Choose a reason for hiding this comment

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

No. It would require going through the JIT like I did in #101796 for RISC-V and fix in many places. Right now my priority is on RISC-V but when I'm done with #101796 I can revisit it. By then @jakobbotsch's ongoing effort to centralize ABI passing infos will probably be more advanced, which will also facilitate fixing x64.

@tomeksowi
Copy link
Contributor Author

tomeksowi commented Jun 21, 2024

Could you please add some tests? src\tests\JIT\Directed\StructABI looks like a good place

Sure, I'll lift a couple from #101796.

EDIT: In fact, I think I can lift the entire test suite and disable Empty8Float tests on System V.
EDIT2: I added some dedicated tests for System V after all, RISC-V will be added in subsequent PRs.

@tomeksowi
Copy link
Contributor Author

I think the GC\Scenarios\RanCollect\rancollect\rancollect.cmd time-out on Windows x64 is not related to this change (which is System V only).

// then the classification of this eightbyte might be NoClass. We can't hand a classification of NoClass to the JIT
// so set the class to Integer (as though the struct has a char[8] padding) if the class is NoClass.
//
// TODO: Fix JIT, NoClass eightbytes are valid and passing them is broken because of this.
Copy link
Member

Choose a reason for hiding this comment

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

What does the difference between NoClass and something like char[8] end up being? For significant padding (structs with explicit layout) it seems like we have to consider them to be the same or things will end up odd/wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

char[8] is an INTEGER eightbyte which gets assigned an integer register for passing; a NO_CLASS eightbyte doesn't get any register. Passing on the stack is the same, though (NO_CLASS padding does take up space).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Opened #104098 as I'll need an URL for ActiveIssue in tests in future PRs.

Meanwhile this smaller fix is ready for review.

Copy link
Member

Choose a reason for hiding this comment

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

Does this fix handle the significant padding cases correctly (i.e. as before this change)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should, the NO_CLASS -> INTEGER eightbyte reclassification is still there. And I didn't see any CLR tests (prio1) go off on Checked build, assuming there are tests for significant padding by now.

@jakobbotsch
Copy link
Member

@MihuBot

@jakobbotsch
Copy link
Member

It looks like there's a bunch of asm diffs with this change, can you take a look at whether they are expected?

@tomeksowi
Copy link
Contributor Author

It looks like there's a bunch of asm diffs with this change, can you take a look at whether they are expected?

Thanks for running the bot. Diffs are to be expected, some arguments which used to be passed by reference are now enregistered but large amount of performance regressions are worrying. I'll look at it in spare time between RISC-V PRs.

@jakobbotsch
Copy link
Member

Diffs are to be expected, some arguments which used to be passed by reference are now enregistered but large amount of performance regressions are worrying

Note that they are size diffs only, and overall the size improves. I spot checked a few of the regressions and it's usually the result of some new register shuffling because of an empty struct now taking up a register, so I guess those diffs are overall expected. Some of these cases look like they could be switched to static abstracts to avoid the parameter entirely.

@jkotas I assume we are ok to take an ABI change like this one since the R2R format is already being bumped?

@jkotas
Copy link
Member

jkotas commented Jun 27, 2024

@jkotas I assume we are ok to take an ABI change like this one since the R2R format is already being bumped?

Yes. I do not see a problem with the ABI change here.

Copy link
Member

@jakobbotsch jakobbotsch left a comment

Choose a reason for hiding this comment

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

Thanks!

@jakobbotsch jakobbotsch merged commit 03b75f0 into dotnet:main Jun 28, 2024
93 of 95 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Jul 28, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants