Skip to content

contained LCL_VAR_ADDR is generated wrong in RMW. #41073

@sandreenko

Description

@sandreenko

when we have a tree like:

N009 ( 15, 17) [000008] -A--G---R---              *  ASG       long   $VN.Void
N008 (  6,  7) [000007] *------N----              +--*  IND       long   <l:$241, c:$240>
N007 (  3,  5) [000001] ------------              |  \--*  LCL_VAR_ADDR   long V00 arg0          $100
N005 (  8,  9) [000006] ----G-------              \--*  ADD       long   <l:$241, c:$240>
N003 (  6,  7) [000004] *---G-------                 +--*  IND       long   <l:$180, c:$1c0>
N002 (  3,  5) [000003] ------------                 |  \--*  LCL_VAR _ADDR      long V00 arg0          $100
N004 (  1,  1) [000005] ------------                 \--*  CNS_INT   long   123 $200

jit recognizes it as RWM and mark LCL_VAR_ADDR as contained but then emitter::emitInsRMW calls emitHandleMemOp and it has no idea how to generate it right.

The current version fails with asserts added in cfd544a, the preview 5(release) and 3.1 generate code like:

Generating: N012 (  3,  4) [000000] Uc-----N----         t0 =    LCL_VAR_ADDR byref  V00 arg0          NA REG NA
                                                              /--*  t0     byref
                                                              +--*  t6     long
Generating: N014 (???,???) [000012] -A--G-------              *  STOREIND  long   REG NA
IN0001:        add      qword ptr [0000H], 123

that triggers a null-dereference exception.

It can be generated by code like this:

Unsafe.As<float, int>(ref a) = Unsafe.As<float, int>(ref a) + 123;

The full test source

I think it doesn't hit the bar for 5.0, so I set 6.0 milestone unless I find more ways to expose this.

P.S. it took me 4 hours to create an IL project for 3.1 and I ended up using ILGenerator to generate the method in csproj because ilproj did not want to work, does anybody know how to create and run ilproj using release dotnet? If not please upvote https://developercommunity.visualstudio.com/idea/540810/add-microsoftnetsdkil-aka-ilproj-support-in-visual.html

Note about non-optimal STORE_LCL_VAR/FLD when not enregistered

Note: it is interesting that we don't support RMW for STORE_LCL_VAR/STORE_LCL_FLD, so in a similar case we would generate worse code when working with fields, not their indirs:

Generating: N019 (  3,  4) [000013] ------------        t13 =    LCL_FLD   int    V01 loc0         u:3[+4] Fseq[b] rax REG rax $80
IN0006:        mov      eax, dword ptr [V01+0x4 rsp+04H]
Generating: N021 (  1,  1) [000014] -c----------        t14 =    CNS_INT   int    123 REG NA $42
                                                              /--*  t13    int
                                                              +--*  t14    int
Generating: N023 (  5,  6) [000015] ------------        t15 = *  ADD       int    REG rax $1c0
IN0007:        add      eax, 123
                                                              /--*  t15    int
Generating: N025 (  9, 11) [000017] UA----------              *  STORE_LCL_FLD int    V01 loc0         ud:3->0[+4] Fseq[b] NA REG NA
IN0008:        mov      dword ptr [V01+0x4 rsp+04H], eax

instead of

add      dword ptr [V01+0x4 rsp+04H], 123

but it is not very important because usually LCL_VAR/FLD are allocated on registers, so fixing it won't produce many diffs.

category:correctness
theme:codegen
skill-level:expert
cost:medium

Metadata

Metadata

Assignees

Labels

Priority:3Work that is nice to havearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIbug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions