Skip to content

Comments

[release/6.0] Fix loop cloning of array of struct with array field#67496

Merged
carlossanlop merged 1 commit intodotnet:release/6.0from
BruceForstall:PortFix66254
Apr 13, 2022
Merged

[release/6.0] Fix loop cloning of array of struct with array field#67496
carlossanlop merged 1 commit intodotnet:release/6.0from
BruceForstall:PortFix66254

Conversation

@BruceForstall
Copy link
Contributor

@BruceForstall BruceForstall commented Apr 3, 2022

Fixes Issue #66254

main PR #67130

Description

The JIT compiler "loop cloning" optimization was incorrectly treating an array-of-structs as an array-of-arrays if one of the fields of the struct was an array. E.g., for ValueTuple<int[], int>[], cloning was confusing the expression a[i].Item1[j] as a jagged array access a[i][j].

The fix prevents this by detecting if the array element type is not what is expected, when parsing each level of the array indexing expression.

Customer Impact

This is silent bad code generation, so the JIT generates incorrect code that likely leads to a crash.

Regression

Yes, this is a regression in .NET 6.

Testing

Multiple JIT stress runs; new regression test; manual testing.

Verified the failure in release/6.0 before the fix, and success after the fix.

Risk

Low; the fix prevents an optimization from occurring, but doesn't introduce any new optimizations.

Loop cloning needs to parse what morph creates from GT_INDEX nodes
to determine if there are array accesses with bounds checks that
could potentially be optimized. For jagged array access, this can
be a "comma chain" of bounds checks and array element address expressions.
For a case where an array of structs had a struct field, such as
`ValueTuple<int[], int>[]`, cloning was confusing the expression
`a[i].Item1[j]` for the jagged array access `a[i][j]`.

The fix here is to keep track of the type of the `GT_INDEX` node that is
being morphed, in the `GT_BOUNDS_CHECK` node that is created for it.
(This is the only thing cloning parses, to avoid the need to parse
the very complex trees morph can create.) This type is then checked
when parsing the "comma chain" trees. If a non-`TYP_REF` is found (such
as a `TYP_STRUCT` in the above example), no more levels of array indexing
are considered. (`TYP_REF` is what an array object would have, for a jagged
array.)

Fixes dotnet#66254.
@ghost ghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 3, 2022
@ghost ghost assigned BruceForstall Apr 3, 2022
@ghost
Copy link

ghost commented Apr 3, 2022

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

Issue Details

[Port #67130 to release/6.0]

Loop cloning needs to parse what morph creates from GT_INDEX nodes
to determine if there are array accesses with bounds checks that
could potentially be optimized. For jagged array access, this can
be a "comma chain" of bounds checks and array element address expressions.
For a case where an array of structs had a struct field, such as
ValueTuple<int[], int>[], cloning was confusing the expression
a[i].Item1[j] for the jagged array access a[i][j].

The fix here is to keep track of the type of the GT_INDEX node that is
being morphed, in the GT_BOUNDS_CHECK node that is created for it.
(This is the only thing cloning parses, to avoid the need to parse
the very complex trees morph can create.) This type is then checked
when parsing the "comma chain" trees. If a non-TYP_REF is found (such
as a TYP_STRUCT in the above example), no more levels of array indexing
are considered. (TYP_REF is what an array object would have, for a jagged
array.)

Fixes #66254.

Author: BruceForstall
Assignees: -
Labels:

area-CodeGen-coreclr

Milestone: -

@BruceForstall BruceForstall added this to the 6.0.x milestone Apr 3, 2022
@BruceForstall
Copy link
Contributor Author

/azp run runtime-coreclr outerloop, runtime-coreclr jitstress

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@teo-tsirpanis
Copy link
Contributor

@BruceForstall the PR's message might need to follow the Servicing Pull Request template.

@BruceForstall
Copy link
Contributor Author

The jitstress items are all known issues or infra (out of disk space).

Copy link
Member

@jeffschwMSFT jeffschwMSFT left a comment

Choose a reason for hiding this comment

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

Approved. We will take for consideration in 6.0.x

@jeffschwMSFT jeffschwMSFT added the Servicing-consider Issue for next servicing release review label Apr 5, 2022
@leecow leecow added Servicing-approved Approved for servicing release and removed Servicing-consider Issue for next servicing release review labels Apr 7, 2022
@leecow leecow modified the milestones: 6.0.x, 6.0.5 Apr 7, 2022
@carlossanlop carlossanlop merged commit 1978e2f into dotnet:release/6.0 Apr 13, 2022
@ghost ghost locked as resolved and limited conversation to collaborators May 13, 2022
@BruceForstall BruceForstall deleted the PortFix66254 branch December 28, 2022 01:22
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 Servicing-approved Approved for servicing release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants