Running the following example results in an assert:
using System;
using System.Runtime.CompilerServices;
class Program
{
uint i;
[MethodImpl(MethodImplOptions.NoInlining)]
ulong Test(uint h)
{
uint x = h + 4;
ulong f = checked((ulong)unchecked(x - i));
if (i > h)
return 0;
return f;
}
static void Main()
{
new Program().Test(42);
}
}
Assert failure(PID 9708 [0x000025ec], Thread: 9964 [0x26ec]): Assertion failed 'treeNodeCount == linearNodeCount' in 'Program:Test(int):long:this' (IL size 26)
File: d:\projects\coreclr\src\jit\flowgraph.cpp Line: 20861
Image: D:\Projects\coreclr\bin\Product\Windows_NT.x86.Debug\CoreRun.exe
The IR contains an embedded statement and GT_STORE_LCL_VAR decomposition attempts to insert a statement after the current one using fgInsertStmtAfter. But that results in the new statement being inserted between the current statement and its embedded statement.
Relevant IR:
***** BB01, stmt 1 (top level)
( 23, 21) [000010] ------------ * stmtExpr void (top level) (IL 0x000...0x00B)
N001 ( 1, 1) [000001] ------------ | /--* lclVar int V01 arg1 u:2 $c0
N002 ( 1, 1) [000002] ------------ | +--* const int 4 $43
N003 ( 3, 3) [000003] ------------ | /--* + int $140
( 8, 7) [000037] ------------ | | { * stmtExpr void (embedded) (IL 0x000... ???)
N004 ( 1, 1) [000004] ------------ | | { | /--* lclVar ref V00 this u:2 $80
N005 ( 1, 1) [000026] ------------ | | { | +--* const int 4 field offset Fseq[i] $43
N006 ( 2, 2) [000027] -------N---- | | { | /--* + byref $180
N007 ( 4, 4) [000005] ---XG------- | | { | /--* indir int <l:$142, c:$200>
N009 ( 8, 7) [000033] DA-XG------- | | { \--* st.lclVar int V03 cse0
N010 ( 3, 2) [000034] ------------ | +--* lclVar int V03 cse0 <l:$142, c:$200>
N012 ( 15, 13) [000006] -A-XG------- | /--* - int <l:$144, c:$143>
N013 ( 16, 15) [000007] -A-XG----U-- | /--* cast long <- ulong <- uint <l:$241, c:$240>
N015 ( 23, 21) [000009] DA-XG------- \--* st.lclVar long V02 loc0 d:3
Running the following example results in an assert:
The IR contains an embedded statement and
GT_STORE_LCL_VARdecomposition attempts to insert a statement after the current one usingfgInsertStmtAfter. But that results in the new statement being inserted between the current statement and its embedded statement.Relevant IR: