IL sample:
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.
IL sample:
IR post decomposition:
x86 generated code:
ARM32 generated code:
There seem to be 2 distinct issues:
movsxnoruxtbmake sense in this context. Sign extending from I1 to I4 is the job of the load.conv.i1.unbut that does not exist. On x86movsxhides 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.