Skip to content

JIT incorrectly adds handles to integer constants #94332

@MichalStrehovsky

Description

@MichalStrehovsky

Regression from .NET 7.

Compile following program with native AOT:

unsafe partial class Program
{
    const int Width = 320;
    const int Height = 180;

    struct Pixels
    {
        public fixed byte Data[Width * Height];
    }

    static Pixels pixels;

    static void Main()
    {
        for (nint i = 0; i < Width; i++)
            pixels.Data[(Height - 1) * Width + i] = 36;
    }
}

This will crash with an IndexOutOfRangeException in JitInterface because RyuJIT is asking about a non-sensical handle.

I've root caused it to following code in Morph:

runtime/src/coreclr/jit/morph.cpp

Lines 11105 to 11125 in aea45f7

// Fold "((x + icon1) + (y + icon2))" to ((x + y) + (icon1 + icon2))".
// Be careful not to create a byref pointer that may point outside of the ref object.
// Only do this in global morph as we don't recompute the VN for "(x + y)", the new "op2".
if (op1->OperIs(GT_ADD) && op2->OperIs(GT_ADD) && !op1->gtOverflow() && !op2->gtOverflow() &&
op1->AsOp()->gtGetOp2()->IsCnsIntOrI() && op2->AsOp()->gtGetOp2()->IsCnsIntOrI() &&
!varTypeIsGC(op1->AsOp()->gtGetOp1()) && !varTypeIsGC(op2->AsOp()->gtGetOp1()) && fgGlobalMorph)
{
GenTreeOp* addOne = op1->AsOp();
GenTreeOp* addTwo = op2->AsOp();
GenTreeIntCon* constOne = addOne->gtGetOp2()->AsIntCon();
GenTreeIntCon* constTwo = addTwo->gtGetOp2()->AsIntCon();
addOne->gtOp2 = addTwo->gtGetOp1();
addOne->SetAllEffectsFlags(addOne->gtGetOp1(), addOne->gtGetOp2());
DEBUG_DESTROY_NODE(addTwo);
constOne->SetValueTruncating(constOne->IconValue() + constTwo->IconValue());
op2 = constOne;
add->gtOp2 = constOne;
DEBUG_DESTROY_NODE(constTwo);
}

One of these integer constants is actually a handle and doing an addition with it is not valid.

fgMorphTree BB02, STMT00020 (before)
               [000106] -A-XG------                         *  STOREIND  byte
               [000104] -----------                         +--*  ADD       long
               [000099] -----------                         |  +--*  FIELD_ADDR long   Program+Pixels+<Data>e__FixedBuffer:FixedElementField
               [000098] -----------                         |  |  \--*  FIELD_ADDR long   Program+Pixels:Data
               [000097] -----------                         |  |     \--*  ADD       long
               [000095] H----------                         |  |        +--*  CNS_INT(h) long   0x40000000004201c8 static
               [000096] -----------                         |  |        \--*  CNS_INT   long   0 Fseq[pixels]
               [000103] -----------                         |  \--*  ADD       long
               [000101] -----------                         |     +--*  CNS_INT   long   0xDFC0
               [000102] -----------                         |     \--*  LCL_VAR   long   V04 loc4
               [000105] -----------                         \--*  CNS_INT   int    36

Final value of Compiler::fgMorphFieldAddr after morphing:
               [000097] -----+-----                         *  ADD       long
               [000096] -----+-----                         +--*  CNS_INT   long   0 Fseq[pixels]
               [000095] H----+-----                         \--*  CNS_INT(h) long   0x40000000004201c8 static

Final value of Compiler::fgMorphFieldAddr after morphing:
               [000097] -----+-----                         *  ADD       long
               [000096] -----+-----                         +--*  CNS_INT   long   0 Fseq[pixels]
               [000095] H----+-----                         \--*  CNS_INT(h) long   0x40000000004201c8 static

fgMorphTree BB02, STMT00020 (after)
               [000106] -A-XG+-----                         *  STOREIND  byte
               [000104] -----+-----                         +--*  ADD       long
               [000097] -----+-----                         |  +--*  ADD       long
               [000096] -----+-----                         |  |  +--*  CNS_INT   long   0 Fseq[pixels]
               [000102] -----+-----                         |  |  \--*  LCL_VAR   long   V04 loc4
               [000095] H----+-----                         |  \--*  CNS_INT(h) long   0x400000000042e188 static
               [000105] -----+-----                         \--*  CNS_INT   int    36

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions