Skip to content

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

Description

@adamperlin

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    <l:$1c3, c:$1c2>
//                                                                    /--*  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 <l:$1c1, c:$181>
//                                                                    /--*  t26    ref    
//        N013 (  2,  2) [000027] ---X-O-----                         *  NULLCHECK byte   <l:$1c8, c:$1c7>
// read:  N015 (  1,  1) [000029] -----------                   t29 =    LCL_VAR   ref    V03 tmp1         u:2 (last use) <l:$1c1, c:$181>
//                                                                    /--*  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    <l:$1cf, c:$1ce>
//                                                                    /--*  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 <l:$1cd, c:$184>
//                                                                    /--*  t39    ref    
//        N025 (  2,  2) [000040] ---X-O-----                         *  NULLCHECK byte   <l:$1d3, c:$1d2>
//        N027 (  1,  1) [000042] -----------                   t42 =    LCL_VAR   ref    V03 tmp1         u:3 (last use) <l:$1cd, c:$184>
//        N028 (  1,  2) [000043] -----------                   t43 =    CNS_INT   int    12 Fseq[F8] $43
//                                                                    /--*  t42    ref    
//                                                                    +--*  t43    int    
//        N029 (  3,  4) [000044] -----O-----                   t44 = *  ADD       byref  <l:$247, c:$248>
//                                                                    /--*  t44    byref  
//        N031 (  9,  9) [000048] DA-XGO-----                         *  STORE_LCL_VAR byref  V04 tmp2         d:2 <l:$1d7, c:$1d5>
//        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) <l:$247, c:$248>
//        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 <l:$1cc, c:$1ca>
//                       [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

Metadata

Metadata

Assignees

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions