Skip to content

JIT: Stop sinking stores below commas in impStoreStruct #91586

@jakobbotsch

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.

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