I don't have a test case for this but the existing code is obviously wrong:
tree->gtNext = hiRhs;
hiRhs->gtPrev = tree;
hiRhs->gtNext = hiStore;
tree is actually loStore so this code basically takes the hiRhs node and moves it between loStore and hiStore. This fails whenever hiRhs is not a leaf. I suspect that this sometimes works due to the use of fgNewStmtFromTree, this function re-sequences the hiRhs tree and practically pulls it out from the old statement. But this doesn't happen in the case of embedded statements when fgMakeEmbeddedStmt is used instead.
I experimented with a workaround in dotnet/coreclr#4986 - reverse the store ordering so hiRhs doesn't need to move. However, I'm far from being convinced that this is the right approach.
We could use temporaries again but it feels odd to use temporaries when decomposing GT_STORE_LCL_VAR.
I don't have a test case for this but the existing code is obviously wrong:
treeis actuallyloStoreso this code basically takes thehiRhsnode and moves it betweenloStoreandhiStore. This fails wheneverhiRhsis not a leaf. I suspect that this sometimes works due to the use offgNewStmtFromTree, this function re-sequences thehiRhstree and practically pulls it out from the old statement. But this doesn't happen in the case of embedded statements whenfgMakeEmbeddedStmtis used instead.I experimented with a workaround in dotnet/coreclr#4986 - reverse the store ordering so
hiRhsdoesn't need to move. However, I'm far from being convinced that this is the right approach.We could use temporaries again but it feels odd to use temporaries when decomposing
GT_STORE_LCL_VAR.