Skip to content

JIT generate wrong code when enabling overflow compiler flag #7439

@tarekgh

Description

@tarekgh

When enabling the overflow/underflow compiler flag, there is a case when JIT generate wrong code. basically we have a method

        internal unsafe void AdjustBytes(int count)
        {
            _bytes += count;
        }

in the file
https://github.com/dotnet/corefx/blob/10733b7bb84d6132f4ac6fd83f3405f3ebd689a6/src/System.Text.Encoding.CodePages/src/System/Text/EncodingCharBuffer.cs#L91

When compiling with overflow flag on, the jit will produce the following

00007FFF46E67D50  push        rbp  
00007FFF46E67D51  push        rdi  
00007FFF46E67D52  push        rsi  
00007FFF46E67D53  sub         rsp,30h  
00007FFF46E67D57  mov         rbp,rsp  
00007FFF46E67D5A  xor         eax,eax  
00007FFF46E67D5C  mov         qword ptr [rbp+28h],rax  
00007FFF46E67D60  mov         qword ptr [rbp+50h],rcx  
00007FFF46E67D64  mov         dword ptr [rbp+58h],edx  
00007FFF46E67D67  cmp         dword ptr [7FFF46DFB728h],0  
00007FFF46E67D6E  je          00007FFF46E67D75  
00007FFF46E67D70  call        00007FFFA65B0EB0  
00007FFF46E67D75  nop  
            _bytes += count;
00007FFF46E67D76  mov         rax,qword ptr [rbp+50h]  
00007FFF46E67D7A  mov         edx,dword ptr [rbp+58h]  
00007FFF46E67D7D  mov         edx,edx  
00007FFF46E67D7F  add         rdx,qword ptr [rax+48h]  
00007FFF46E67D83  jae         00007FFF46E67D8A  
00007FFF46E67D85  call        00007FFFA65AFBD0  
00007FFF46E67D8A  mov         rax,qword ptr [rbp+50h]  
00007FFF46E67D8E  mov         qword ptr [rax+48h],rdx  
        }
00007FFF46E67D92  nop  
00007FFF46E67D93  lea         rsp,[rbp+30h]  
00007FFF46E67D97  pop         rsi  
00007FFF46E67D98  pop         rdi  
00007FFF46E67D99  pop         rbp  
00007FFF46E67D9A  ret  

you can notice the operations neglect the sign. so if someone pass negative number to the method we'll end up with wrong result. if we compile with overflow flag off, JIT produce the following right code:


00007FFF46E877B0  push        rbp  
00007FFF46E877B1  push        rdi  
00007FFF46E877B2  push        rsi  
00007FFF46E877B3  sub         rsp,30h  
00007FFF46E877B7  mov         rbp,rsp  
00007FFF46E877BA  xor         eax,eax  
00007FFF46E877BC  mov         qword ptr [rbp+28h],rax  
00007FFF46E877C0  mov         qword ptr [rbp+50h],rcx  
00007FFF46E877C4  mov         dword ptr [rbp+58h],edx  
00007FFF46E877C7  cmp         dword ptr [7FFF46E1B728h],0  
00007FFF46E877CE  je          00007FFF46E877D5  
00007FFF46E877D0  call        00007FFFA65B0EB0  
00007FFF46E877D5  nop  
            _bytes += count;
00007FFF46E877D6  mov         eax,dword ptr [rbp+58h]  
00007FFF46E877D9  movsxd      rax,eax  
00007FFF46E877DC  mov         rdx,qword ptr [rbp+50h]  
00007FFF46E877E0  add         qword ptr [rdx+48h],rax  
        }
00007FFF46E877E4  nop  
00007FFF46E877E5  lea         rsp,[rbp+30h]  
00007FFF46E877E9  pop         rsi  
00007FFF46E877EA  pop         rdi  
00007FFF46E877EB  pop         rbp  
00007FFF46E877EC  ret  

to repro the issue, on corefx repo do the following:

you'll get one test failed because of the wrong code generated for the AdjustBytes method in the library System.Text.Encoding.CodePages

dotnet/corefx#16160

Metadata

Metadata

Assignees

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

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions