dotnet / dotnet/runtime

JIT: (bug) Assert `varTypeIsIntegral(type) || varTypeIsGC(type)` in morph: comma-throw propagated into a struct-typed parent

Open
#133,862 1 comment 0 reactions 0 assignees View on GitHub
area-CodeGen-coreclr
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

`fgPropagateCommaThrow` calls `BashToZeroConst(genActualType(parent))` for any non-`void` parent. With a
struct-typed parent (here a `GT_BLK` from a struct array load) this asserts in a Checked JIT and builds
malformed struct-typed `CNS_INT` IR in Release.

### Minimal Repro

```csharp
using System;
using System.Runtime.CompilerServices;

struct S { public int a, b, c, d; }

class Program
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int Idx(long v) => checked((int)v);

[MethodImpl(MethodImplOptions.NoInlining)]
static S Test(S[] a) => a[Idx(long.MaxValue)];

static void Main()
{
try { Console.WriteLine(Test(new S[4]).a); }
catch (OverflowException) { Console.WriteLine("OverflowException"); }
}
}
```

Requires `DOTNET_TieredCompilation=0`; at tier-0 the folding does not happen.

### Expected

```
OverflowException
```

### Actual

```
Assert failure(PID 148588 [0x0002446c], Thread: 59900 [0xe9fc]): Assertion failed
'varTypeIsIntegral(type) || varTypeIsGC(type)' in 'Program:Test(S[]):S' during 'Morph - Global'
(IL size 21; hash 0xb183d2e0; FullOpts)

File: src\coreclr\jit\compiler.hpp:2191
```

Process exits with `0xC0000409`.

### Notes

After inlining, `gtFoldExprConst` turns the always-throwing checked cast into `COMMA(throw, 0)`, which
`fgPropagateCommaThrow` then propagates into the struct-typed parent; it should bail out (or use a different
"zero" representation) when the parent is not integral/GC-typed.
`Span` indexing and `S s = a[Idx(long.MaxValue)];` hit the same assert.
Release .NET 10.0.12 prints `OverflowException` — this is a Checked-assert / malformed-IR issue, not a known
silent bad-codegen bug.

Contributor guide

Open the contributing guide

Research direction

Start with fgPropagateCommaThrow and gtFoldExprConst in the JIT, then inspect the assertion in src/coreclr/jit/compiler.hpp. Run the supplied C# reproducer with DOTNET_TieredCompilation=0 and compare Checked and Release behavior; done means the struct-typed parent no longer triggers the assertion or malformed IR and the repro prints OverflowException.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.