Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Conversation

@erozenfeld
Copy link
Member

fgRemoveDeadStore has special logic for removing dead assignments
whose rhs was of type TYP_STRUCT:

coreclr/src/jit/liveness.cpp

Lines 2264 to 2274 in 311b5e2

if (rhsNode->TypeGet() == TYP_STRUCT)
{
// This is a block assignment. An indirection of the rhs is not considered to
// happen until the assignment, so we will extract the side effects from only
// the address.
if (rhsNode->OperIsIndir())
{
assert(rhsNode->OperGet() != GT_NULLCHECK);
rhsNode = rhsNode->AsIndir()->Addr();
}
}

That logic was applied to "normal"
assignments (i.e., direct children of GT_STMT) but not to "internal"
assignments (e.g., children of GT_COMMA).
The test case has an internal assignment and, because this logic wasn't
applied, we ended up with a standalone GT_IND of type TYP_STRUCT
that the register allocator can't handle.

This change apples the missing logic to "internal" assignments.

The second commit cleans up fgRemoveDeadStore.

Fixes #24253.

`fgRemoveDeadStore` has special logic for removing dead assignments
whose rhs was of type `TYP_STRUCT`:

https://github.com/dotnet/coreclr/blob/311b5e2fe413c6c74a2a3680ab54d8a978651472/src/jit/liveness.cpp#L2264-L2274

That logic was applied to "normal"
assignments (i.e., direct children of `GT_STMT`) but not to "internal"
assignments (e.g., children of `GT_COMMA`).
The test case has an internal assignment and, because this logic wasn't
applied, we ended up with a standalone `GT_IND` of type `TYP_STRUCT`
that the register allocator can't handle.

This change apples the missing logic to "internal" assignments.

Fixes #24253.
@erozenfeld
Copy link
Member Author

No x64 pmi diffs in frameworks and benchmarks.
I will try to check SPMI diffs as well.

@erozenfeld
Copy link
Member Author

@dotnet/jit-contrib @sandreenko @CarolEidt PTAL
It's probably easier to review the two commits individually: the first one is the actual fix and the second one is the cleanup of confusing surrounding code.

Copy link

@CarolEidt CarolEidt left a comment

Choose a reason for hiding this comment

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

LGTM - much cleaner!

GenTree* sideEffList = nullptr;
if (rhsNode->gtFlags & GTF_SIDE_EFFECT)
{
// Extract the side effects

Choose a reason for hiding this comment

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

I would suggest moving this comment below the DEBUG code - or you could add a CLANG_FORMAT_COMMENT_ANCHOR;

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.


/* Replace the assignment statement with the list of side effects */
noway_assert(sideEffList->gtOper != GT_STMT);
/* Replace the assignment statement with the list of side effects */

Choose a reason for hiding this comment

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

While you're here you could make these C++ style comments.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

}
else
{
NO_SIDE_EFFECTS:

Choose a reason for hiding this comment

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

I love getting rid of gotos!!

// the address.
if (rhsNode->OperIsIndir())
{
assert(rhsNode->OperGet() != GT_NULLCHECK);

Choose a reason for hiding this comment

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

Why should not it be a nullcheck?

Copy link
Member Author

Choose a reason for hiding this comment

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

We never create GT_NULLCHECK as a rhs of an assignment. I guess this assert just makes sure we don't accidentally remove a null check.

/* Check for side effects */

if (rhsNode->gtFlags & GTF_SIDE_EFFECT)
if (sideEffList)

Choose a reason for hiding this comment

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

if (sideEffList != nullptr)

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

noway_assert(sideEffList->gtOper != GT_STMT);

*pTree = compCurStmt->gtStmtExpr = sideEffList;
*pTree = compCurStmt->gtStmtExpr = sideEffList;

Choose a reason for hiding this comment

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

Is it possible that pTree != &compCurStmt->gtStmtExpr?

Copy link
Member Author

Choose a reason for hiding this comment

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

pTree is an address of a local GenTree* variable in the caller, (e.g., address of tree in fgComputeLife.

Copy link

@sandreenko sandreenko left a comment

Choose a reason for hiding this comment

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

The fix looks good, thanks for the cleaning.

Remove duplication and a couple of goto's from `fgRemoveDeadStore`.

This part was very confusing:

`
                /* If this is GT_CATCH_ARG saved to a local var don't bother */

                JITDUMP("removing stmt with no side effects\n");

                if (asgNode->gtFlags & GTF_ORDER_SIDEEFF)
                {
                    if (rhsNode->gtOper == GT_CATCH_ARG)
                    {
                        goto EXTRACT_SIDE_EFFECTS;
                    }
                }
`

The `goto` was to the preceding `if` and was useless since the call
to `gtExtractSideEffList(rhsNode, &sideEffList);` couldn't possibly find
side effects because we already checked that
`rhsNode->gtFlags & GTF_SIDE_EFFECT == 0`.
@erozenfeld
Copy link
Member Author

No desktop SPMI diffs.

@erozenfeld
Copy link
Member Author

CoreFX test failed with
System.Net.Security.Tests.SslStreamCredentialCacheTest.SslStream_SameCertUsedForClientAndServer_Ok [FAIL]
System.TimeoutException : Task timed out after 15000ms

@erozenfeld
Copy link
Member Author

@dotnet-bot test Windows_NT x64 Checked CoreFX Tests

2 similar comments
@erozenfeld
Copy link
Member Author

@dotnet-bot test Windows_NT x64 Checked CoreFX Tests

@erozenfeld
Copy link
Member Author

@dotnet-bot test Windows_NT x64 Checked CoreFX Tests

Copy link

@briansull briansull left a comment

Choose a reason for hiding this comment

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

Looks Good

@sandreenko
Copy link

@dotnet-bot test Windows_NT x64 Checked CoreFX Tests (the broken machine is disabled now).

@erozenfeld erozenfeld merged commit 78f53be into dotnet:master Apr 29, 2019
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Register allocator assert: "Expected empty defList at end of block"

4 participants