镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

[Release Mode] Conditional check against byte.MaxValue unexpectedly ignored in .NET 9 #118317

Description

@TheRangerr

Description

With this code by running dotnet net -c Release

var bytes = new List<byte>();
const int length = 9501;
for(int i = 0; i < length; i++)
    bytes.Add(byte.MaxValue);

for (var i = 0; i < length; i++)
{
    byte value = bytes[i];
    if (value == int.MaxValue) continue; // the bug happens because of this line (remove it and the code will work normally)
    if (value == byte.MaxValue) continue; // it gets skipped
    Console.WriteLine($"{value} == {byte.MaxValue} ? {(value == byte.MaxValue)}");
}

it prints "255 == 255 ? True" but 4 times, and 2 times if length is 9500
however in SharpLab or by running COMPlus_TC_QuickJit=0 dotnet run -c release, it prints "255 == 255 ? False" many times

and if we run this

var bytes = new List<byte>();
const int length = 9501;
for(int i = 0; i < length; i++)
    bytes.Add(byte.MaxValue);

for (int y = 0; y < 128; y++)
{
    for (int x = 0; x < 128; x++)
    {
    
    }   
}

for (var i = 0; i < length; i++)
{
    byte value = bytes[i];
    if (value == int.MaxValue) continue;
    if (value == byte.MaxValue) continue; // it gets skipped
    Console.WriteLine($"{value} == {byte.MaxValue} ? {(value == byte.MaxValue)}"); // Prints "255 == 255 ? False"
}

whether COMPlus_TC_QuickJit=0 is included or not, it will normally print "255 == 255 ? False"
however, if x and y loops to 96 instead of 128, with COMPlus_TC_QuickJit=0 it will print "255 == 255 ? False", and "255 == 255 ? True" without it

and if we run this

var bytes = new List<byte>();
const int length = 9501;
for(int i = 0; i < length; i++)
    bytes.Add(byte.MaxValue);

for (int i = 0; i < 128 * 128; i++) /
{

}
for (var i = 0; i < length; i++)
{
    byte value = bytes[i];
    if (value == int.MaxValue) continue;
    if (value == byte.MaxValue) continue; // gets skipped
    Console.WriteLine($"{value} == {byte.MaxValue} ? {(value == byte.MaxValue)}");
}

with COMPlus_TC_QuickJit=0 it prints "255 == 255 ? False" and "255 == 255 ? True" without it

if we run this

bool IsBugThere(byte u)  // u is byte.MaxValue
{ 
    byte value = u;
    if (value == UInt16.MaxValue) return false;
    if (value == byte.MaxValue) return false;
    Console.WriteLine($"{value} == {byte.MaxValue} ? {(value == byte.MaxValue)}");
    return true;
}

it simply returns false and it doesn't print, however with COMPlus_TC_QuickJit=0 it prints "255 == 255 ? False" and returns true

and if we run this

for(int i = 0; i < 5; i++)
{
    for(int j = 0; j < 1000; j++)
    {
        IsBugThere(255);
    }
    Thread.Sleep(100);
    Console.WriteLine(IsBugThere(byte.MaxValue));
}

it Prints False 4 times then True on the 5th time, however with COMPlus_TC_QuickJit=0 it will print False 5 times

but if we removed the Console.WriteLine from the IsBugThere method,
whether COMPlus_TC_QuickJit=0 is included or not, it returns False in both cases

Reproduction Steps

In the Description

Expected behavior

if (value == byte.MaxValue) continue; should be called if value is 255

Actual behavior

if (value == byte.MaxValue) continue; is being skipped

Regression?

Untested

Known Workarounds

No response

Configuration

.NET 9
Arch Linux
x64
Release Mode

Other information

This bug doesn't seem to exist on .Net 10 Preview from what I've been told

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

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

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions