Skip to content

Broken conv.ovf.i8.un decomposition #10345

@mikedn

Description

@mikedn

IL sample:

ldind.i1
conv.ovf.i8.un

IR post decomposition:

N001 (  1,  1) [000002] -------------        t2 =    LCL_VAR   byref  V00 arg0         u:2 (last use) $80
                                                  /--*  t2     byref  
N002 (  4,  3) [000003] *--XG--------        t3 = *  IND       byte   <l:$140, c:$180>
                                                  /--*  t3     byte   
               [000012] ---XG----U---       t12 = *  CAST      int <- byte <- uint
               [000013] -------------       t13 =    CNS_INT   int    0
                                                  /--*  t12    int    
                                                  +--*  t13    int    
               [000014] ---XG--------       t14 = *  LONG      long  

x86 generated code:

       0FBE01       movsx    eax, byte  ptr [ecx]
       0FBEC0       movsx    eax, al
       8902         mov      dword ptr [edx], eax
       33C0         xor      eax, eax
       894204       mov      dword ptr [edx+4], eax

ARM32 generated code:

000006  F990 3000      ldrsb   r3, [r0]
00000A  B2DB           uxtb    r3, r3
00000C  460A           mov     r2, r1
00000E  6013           str     r3, [r2]
000010  2300           movs    r3, 0
000012  6053           str     r3, [r2+4]

There seem to be 2 distinct issues:

  • This is a zero extending cast from U4 to I8. Neither movsx nor uxtb make sense in this context. Sign extending from I1 to I4 is the job of the load.
  • For the same cast node x86 and ARM32 emit different instructions, one sign extends and the other zero extends. One of them is wrong but probably that's a side effect of the unusual cast - the IL equivalent of that cast would be conv.i1.un but that does not exist. On x86 movsx hides the issue since is sign extends again the byte previously loaded.

Found while adding tests for dotnet/coreclr#12676. Test coverage for casts seems to be lacking, I keep running into bugs (either existing or of my own doing) and existing tests fail to catch them so I generated some. This case failed on ARM32 but not on x86.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIbug

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions