Skip to content

Conversation

@BruceForstall
Copy link
Contributor

@BruceForstall BruceForstall commented Feb 26, 2022

Change #64857 exposed an existing problem where when generating code
for a multi-reg GT_STORE_LCL_VAR, if the first register slot was not
enregistered, but the second or subsequent slots was, and those non-first
slots contained GC pointers, we wouldn't properly add those GC pointers
to the GC tracking sets. This led to cases where the register lifetimes
would be killed in the GC info before the actual lifetime was complete.

The primary fix is to make gtHasReg() handle the IsMultiRegLclVar()
case. As a side-effect, this fixes some LSRA dumps that weren't displaying
multiple registers properly.

There are about 50 SPMI asm diffs on win-arm64 where register lifetimes
get extended, fixing GC holes.

I also made GetMultiRegCount() handle the IsMultiRegLclVar() case.

I made a number of cleanup changes along the way:

  1. Fixed two cases of calling gcInfo.gcMarkRegSetNpt with regNumber, not regMaskTP
  2. Marked some functions const
  3. Improved some comments
  4. Changed "ith" to "i'th" in comments which still doesn't read great,
    but at least I'm not left trying to parse "ith" as an English word.
  5. Use OperIsScalarLocal() more broadly
  6. Renamed gtDispRegCount to gtDispMultiRegCount to make it clear
    it only applies to the multi-reg case.

Fixes #65476.

@ghost ghost assigned BruceForstall Feb 26, 2022
@ghost ghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Feb 26, 2022
@ghost
Copy link

ghost commented Feb 26, 2022

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

Issue Details

null

Author: BruceForstall
Assignees: BruceForstall
Labels:

area-CodeGen-coreclr

Milestone: -

Change dotnet#64857 exposed an existing problem where when generating code
for a multi-reg GT_STORE_LCL_VAR, if the first register slot was not
enregistered, but the second or subsequent slots was, and those non-first
slots contained GC pointers, we wouldn't properly add those GC pointers
to the GC tracking sets. This led to cases where the register lifetimes
would be killed in the GC info before the actual lifetime was complete.

The primary fix is to make `gtHasReg()` handle the `IsMultiRegLclVar()`
case. As a side-effect, this fixes some LSRA dumps that weren't displaying
multiple registers properly.

There are about 50 SPMI asm diffs on win-arm64 where register lifetimes
get extended, fixing GC holes.

I also made `GetMultiRegCount()` handle the `IsMultiRegLclVar()` case.

I made a number of cleanup changes along the way:
1. Fixed two cases of calling `gcInfo.gcMarkRegSetNpt` with regNumber, not regMaskTP
2. Marked some functions `const`
3. Improved some comments
4. Changed "ith" to "i'th" in comments which still doesn't read great,
but at least I'm not left trying to parse "ith" as an English word.
5. Use `OperIsScalarLocal()` more broadly
6. Renamed `gtDispRegCount` to `gtDispMultiRegCount` to make it clear
it only applies to the multi-reg case.

Fixes dotnet#65476.
@BruceForstall BruceForstall changed the title Fix multi-reg store GC hole Fix GC hole with multi-reg local var stores Feb 26, 2022
@BruceForstall BruceForstall marked this pull request as ready for review February 26, 2022 07:52
@kunalspathak
Copy link
Contributor

I will take a look on Monday.

@kunalspathak
Copy link
Contributor

/azp run runtime-coreclr superpmi-replay

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Contributor

@kunalspathak kunalspathak left a comment

Choose a reason for hiding this comment

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

Added a minor nit. I have kicked of superpmi replay to make sure we at least run the jitstressregs.

There are about 50 SPMI asm diffs on win-arm64 where register lifetimes
get extended, fixing GC holes.

Yes, so there are no code size or perfscore diffs, but just the register lifetimes differences? Wonder why asmdiffs (coredistools) is even thinking that there is code difference?

Copy link
Contributor

@kunalspathak kunalspathak left a comment

Choose a reason for hiding this comment

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

superpmi-replay is clean.

// having a reg if regs are allocated for all its
// In case of multi-reg call nodes, it is considered having a reg if regs are allocated for ALL its
// return values.
// REVIEW: why is this ALL and the other cases are ANY? Explain.
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you intend to keep this comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, because I don't know the answer :-)

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, okay

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Test failure System.IO.Compression.ZLibStreamUnitTests.ReadWrite_Success

3 participants