Skip to content

JIT: Stop sinking stores below commas in impStoreStruct #91586

Open

Description

@jakobbotsch

The following logic in the importer creates unnaturally/incorrectly typed COMMA nodes:

else if (src->OperIs(GT_COMMA))
{
if (pAfterStmt)
{
// Insert op1 after '*pAfterStmt'
Statement* newStmt = gtNewStmt(src->AsOp()->gtOp1, usedDI);
fgInsertStmtAfter(block, *pAfterStmt, newStmt);
*pAfterStmt = newStmt;
}
else if (impLastStmt != nullptr)
{
// Do the side-effect as a separate statement.
impAppendTree(src->AsOp()->gtOp1, curLevel, usedDI);
}
else
{
// In this case we have neither been given a statement to insert after, nor are we
// in the importer where we can append the side effect.
// Instead, we're going to sink the store below the COMMA.
store->Data() = src->AsOp()->gtOp2;
src->AsOp()->gtOp2 = impStoreStruct(store, curLevel, pAfterStmt, usedDI, block);
src->SetAllEffectsFlags(src->AsOp()->gtOp1, src->AsOp()->gtOp2);
gtUpdateNodeSideEffects(store);
return src;
}
// Evaluate the second thing using recursion.
store->Data() = src->AsOp()->gtOp2;
gtUpdateNodeSideEffects(store);
return impStoreStruct(store, curLevel, pAfterStmt, usedDI, block);
}

It changes for instance

               [000006] --CXG------                         ▌  COMMA     simd12
               [000005] H-CXG------                         ├──▌  CALL help int    CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE
               [000003] ----------- arg0                    │  ├──▌  CNS_INT   int    0x8A2B390
               [000004] ----------- arg1                    │  └──▌  CNS_INT   int    1
               [000001] I---G------                         └──▌  IND       simd12
               [000000] H----------                            └──▌  CNS_INT(h) int    0x8601620 static Fseq[s]

to

               [000006] -ACXG------                         ▌  COMMA     simd12
               [000005] H-CXG------                         ├──▌  CALL help int    CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE
               [000003] ----------- arg0                    │  ├──▌  CNS_INT   int    0x8A2B390
               [000004] ----------- arg1                    │  └──▌  CNS_INT   int    1
               [000087] DA--G------                         └──▌  STORE_LCL_VAR simd12<System.Numerics.Vector3> V02 tmp1         
               [000001] I---G------                            └──▌  IND       simd12
               [000000] H----------                               └──▌  CNS_INT(h) int    0x8601620 static Fseq[s]

We would usually expect [000006] to be TYP_VOID in the latter tree, as evidenced by gtExtractSideEffList. Morph also has code to compensate:

/* Special case: trees that don't produce a value */
if (op2->OperIsStore() || (op2->OperGet() == GT_COMMA && op2->TypeGet() == TYP_VOID) || fgIsThrow(op2))
{
typ = tree->gtType = TYP_VOID;
}

We should fix this; we can likely just avoid sinking these stores below the COMMAs -- this used to be necessary because block morphing did not handle the pattern, but it should be handled after #83590.

#91443 has an example bug because of this JIT IR oddity.

Activity

  1. ghost added
    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
    on Sep 5, 2023
  2. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Sep 5, 2023
  3. added this to the 9.0.0 milestone on Sep 5, 2023
  4. ghost removed
    untriagedNew issue has not been triaged by the area owner
    on Sep 5, 2023
  5. self-assigned this
    on Sep 5, 2023
  6. modified the milestones: 9.0.0, 10.0.0 on Jul 29, 2024
  7. jakobbotsch commented on Aug 14, 2024

    @jakobbotsch
    MemberAuthor

    #106380 is another example of a bug due to this issue.

    We should fix this; we can likely just avoid sinking these stores below the COMMAs -- this used to be necessary because block morphing did not handle the pattern, but it should be handled after #83590.

    Another thing is that, since LIR does not support TYP_STRUCT edges beyond some very restricted patterns, we should ensure that the handling for these struct operations properly handle interfering side effects.

  8. modified the milestones: 10.0.0, Future on Apr 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions