dotnet / dotnet/runtime

[RyuJIT Wasm] Assert: `Write to unaliased local overlaps outstanding read`

Open
#132,987 3 comments 0 reactions 1 assignee Claimed by @adamperlin View on GitHub
arch-wasm area-CodeGen-coreclr
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

### Description

From Fuzzlyn, using a prototype Wasm execution server:
```
// Generated by Fuzzlyn v3.3 on 2026-08-31 22:24:14
// Run on X64 Windows
// Seed: 16430553567934793208-async
// Reduced from 179.6 KiB to 0.6 KiB in 00:10:27
// Exits with error:
// [Diff]
// crossgen2 failed with exit code -2147483645.
// stdout:
// N001 ( 1, 1) [000033] ----------- t33 = LCL_VAR int V00 SP u:1 $80
// N002 ( 1, 5) [000000] Hc--------- t0 = CNS_INT(h) int 0x420048 class $140
// /--* t0 int
// N003 ( 4, 7) [000001] #---------- t1 = * IND int $81
// N001 ( 1, 5) [000059] Hc--------- t59 = CNS_INT(h) int 0x4200A8 ftn
// /--* t59 int
// N002 ( 4, 7) [000060] n---G------ t60 = * IND int
// /--* t60 int
// [000061] DA--G------ * STORE_LCL_VAR int V06 rat0
// [000063] ----------- t63 = LCL_VAR int V06 rat0
// [000062] ----------- t62 = LCL_VAR int V06 rat0 (last use)
// /--* t62 int
// [000064] n---G------ t64 = * IND int
// /--* t33 int wasm sp $0
// +--* t1 int arg1 $1
// +--* t63 int wasm pep $2
// +--* t64 int control expr
// N004 ( 19, 12) [000002] --CXG------ t2 = * CALL help byref CORINFO_HELP_GET_GCSTATIC_BASE $240
// /--* t2 byref
// N005 ( 19, 12) [000050] DACXG------ * STORE_LCL_VAR byref V05 cse0 d:1 $1c4
// N006 ( 1, 1) [000051] ----------- t51 = LCL_VAR byref V05 cse0 u:1 $200
// /--* t51 byref
// N010 ( 23, 15) [000005] nACXGO----- t5 = * IND ref
// /--* t5 ref
// N011 ( 23, 15) [000025] DACXGO----- * STORE_LCL_VAR ref V03 tmp1 d:2 $1c4
// N012 ( 1, 1) [000026] ----------- t26 = LCL_VAR ref V03 tmp1 u:2
// /--* t26 ref
// N013 ( 2, 2) [000027] ---X-O----- * NULLCHECK byte
// read: N015 ( 1, 1) [000029] ----------- t29 = LCL_VAR ref V03 tmp1 u:2 (last use)
// /--* t29 ref
// user: N017 ( 3, 4) [000031] -c--------- t31 = * LEA(b+6) byref
// N019 ( 1, 1) [000053] ----------- t53 = LCL_VAR byref V05 cse0 u:1 (last use) $200
// /--* t53 byref
// N022 ( 4, 3) [000013] n---G------ t13 = * IND ref
// /--* t13 ref
// write: N023 ( 4, 3) [000038] DA--G------ * STORE_LCL_VAR ref V03 tmp1 d:3 $1c4
// N024 ( 1, 1) [000039] ----------- t39 = LCL_VAR ref V03 tmp1 u:3
// /--* t39 ref
// N025 ( 2, 2) [000040] ---X-O----- * NULLCHECK byte
// N027 ( 1, 1) [000042] ----------- t42 = LCL_VAR ref V03 tmp1 u:3 (last use)
// N028 ( 1, 2) [000043] ----------- t43 = CNS_INT int 12 Fseq[F8] $43
// /--* t42 ref
// +--* t43 int
// N029 ( 3, 4) [000044] -----O----- t44 = * ADD byref
// /--* t44 byref
// N031 ( 9, 9) [000048] DA-XGO----- * STORE_LCL_VAR byref V04 tmp2 d:2
// N032 ( 1, 1) [000037] ----------- t37 = LCL_VAR int V00 SP u:1 (last use) $80
// N033 ( 1, 1) [000049] ----------- t49 = LCL_VAR byref V04 tmp2 u:2 (last use)
// N001 ( 1, 5) [000065] Hc--------- t65 = CNS_INT(h) int 0x420088 ftn
// /--* t65 int
// N002 ( 4, 7) [000066] n---G------ t66 = * IND int
// /--* t66 int
// [000067] DA--G------ * STORE_LCL_VAR int V07 rat1
// [000069] ----------- t69 = LCL_VAR int V07 rat1
// [000068] ----------- t68 = LCL_VAR int V07 rat1 (last use)
// /--* t68 int
// [000070] n---G------ t70 = * IND int
// /--* t37 int wasm sp $0
// +--* t49 byref arg1 $1
// +--* t69 int wasm pep $2
// +--* t70 int control expr
// N034 ( 28, 16) [000015] -ACXGO----- t15 = * CALL r2r_ind long Program:M1(byref):ulong $2c0
// /--* t15 long
// N035 ( 30, 17) [000036] -ACXGO----- t36 = * CAST int <- long $300
// /--* t31 byref
// +--* t36 int
// N036 ( 61, 39) [000022] -ACXGO----- * STOREIND ushort
// [000058] ----------- IL_OFFSET void INLRT @ 0x024[E--]
// N001 ( 0, 0) [000023] -----+----- RETURN void $VN.Void
// C:\Users\adamperlin\dev\runtime\src\coreclr\jit\lir.cpp:1502
// Assertion failed '!"Write to unaliased local overlaps outstanding read"' in 'Program:M0()' during 'Lowering nodeinfo' (IL size 37; hash 0xaf50ff37; FullOpts)
//
//
public struct S0
{
public byte F6;
public ushort F8;
}

public struct S1
{
public S0 F0;
public S0 F1;
}

public class C0
{
public S1 F0;
public S1 F8;
}

public class Program
{
public static C0 s_1;
public static ulong[][] s_2;
public static void Main()
{
}

public static void M0()
{
s_1.F0.F0.F8 = (ushort)M1(ref s_1.F8);
}

public static ulong M1(ref S1 arg0)
{
byte var2 = s_1.F8.F1.F6;
return s_2[0][0];
}
}
```

### Reproduction Steps

The above example reproduces the issue exactly when compiled with `crossgen2`.

### Expected behavior

No assertion.

### Actual behavior

Assertion thrown.

### Regression?

_No response_

### Known Workarounds

_No response_

### Configuration

_No response_

### Other information

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.