-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Fix for a jit liveness bug. #24282
Fix for a jit liveness bug. #24282
Conversation
`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.
|
No x64 pmi diffs in frameworks and benchmarks. |
|
@dotnet/jit-contrib @sandreenko @CarolEidt PTAL |
CarolEidt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - much cleaner!
src/jit/liveness.cpp
Outdated
| GenTree* sideEffList = nullptr; | ||
| if (rhsNode->gtFlags & GTF_SIDE_EFFECT) | ||
| { | ||
| // Extract the side effects |
There was a problem hiding this comment.
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;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/jit/liveness.cpp
Outdated
|
|
||
| /* 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 */ |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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!!
src/jit/liveness.cpp
Outdated
| // the address. | ||
| if (rhsNode->OperIsIndir()) | ||
| { | ||
| assert(rhsNode->OperGet() != GT_NULLCHECK); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
src/jit/liveness.cpp
Outdated
| /* Check for side effects */ | ||
|
|
||
| if (rhsNode->gtFlags & GTF_SIDE_EFFECT) | ||
| if (sideEffList) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (sideEffList != nullptr)
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
sandreenko
left a comment
There was a problem hiding this 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`.
|
No desktop SPMI diffs. |
|
CoreFX test failed with |
|
@dotnet-bot test Windows_NT x64 Checked CoreFX Tests |
2 similar comments
|
@dotnet-bot test Windows_NT x64 Checked CoreFX Tests |
|
@dotnet-bot test Windows_NT x64 Checked CoreFX Tests |
briansull
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks Good
|
@dotnet-bot test Windows_NT x64 Checked CoreFX Tests (the broken machine is disabled now). |
Fix for a jit liveness bug. Commit migrated from dotnet/coreclr@78f53be
fgRemoveDeadStorehas special logic for removing dead assignmentswhose rhs was of type
TYP_STRUCT:coreclr/src/jit/liveness.cpp
Lines 2264 to 2274 in 311b5e2
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_INDof typeTYP_STRUCTthat the register allocator can't handle.
This change apples the missing logic to "internal" assignments.
The second commit cleans up
fgRemoveDeadStore.Fixes #24253.