Skip to content

[RyuJIT] Expression a % 0 sometimes generates incorrect code. #7141

@mikedn

Description

@mikedn

The following example:

[MethodImpl(MethodImplOptions.NoInlining)]
static int Test(sbyte x)
{
    return x % 0;
}

generates

G_M55886_IG02:
       480FBEC1             movsx    rax, cl
G_M55886_IG03:
       C3                   ret

Of course, this doesn't generate a DivideByZeroException exception as it should.

This is partially caused by a recent change I did that transforms x % c into x - (x / c) * c if c is not a power of 2. 0 is not a power of 2 but the transform should not be done when c is 0. ARM64 appears to do the same transform unconditionally so probably it is also affected by this. I think we should simply transform x % 0 into x / 0.

However, the actual bug is somewhere else. The following IL code triggers it as well:

.method private hidebysig static int32 
        Test(int8 arg) cil managed noinlining
{
        .maxstack  8
        ldarg.0
        ldarg.0
        ldc.i4.0
        div
        ldc.i4.0
        mul
        sub
        ret
}

The C# compiler doesn't usually produce this kind of code, it drops x * 0. It's that multiplication that's probably mishandled by the JIT, it tries to drop it and sometimes it drops the division as well. When it works correctly the generated code looks like this:

G_M55886_IG02:
       480FBEC9             movsx    rcx, cl
       4533C0               xor      r8d, r8d
       8BC1                 mov      eax, ecx
       99                   cdq
       41F7F8               idiv     edx:eax, r8d
       8BC1                 mov      eax, ecx

I'll look into this.
category:correctness
theme:cse
skill-level:intermediate
cost:medium

Metadata

Metadata

Assignees

Labels

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

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions