Skip to content

Optimization removes necessary code #103477

@shibaev

Description

@shibaev

Description

A NativeAOT version of our project fails at runtime while the related managed version works. There are not publishing warnings and static analysis warnings.

The root cause is that the publishing removes some required code. The code is simple without reflection or any similar dynamic techniques.

Reproduction Steps

Program.cs

namespace AotIssue
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string s = "12151";
            int i = 0;

            char? a = null;
            while (true)
            {
                string? res = get(s, ref i, ref a);
                if (res != null)
                {
                    Console.Write(res);
                    a = null; // !!! this line is removed from the published version

                    // Console.Write(a); // uncomment the line for the workaround
                    continue;
                }

                if (i >= s.Length)
                    break;

                a = '.';
            }
        }

        static string? get(string s, ref int index, ref char? a)
        {
            if (index >= s.Length)
                return null;

            if (a == '.')
                return ".";

            a ??= s[index++];
            return (a == '1') ? "1" : null;
        }
    }
}

AotIssue.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <PublishAot>true</PublishAot>
    <InvariantGlobalization>true</InvariantGlobalization>
    <IsAotCompatible>true</IsAotCompatible>
  </PropertyGroup>
</Project>

To publish the project, you can use the dotnet publish -r win-x64 -c Release command. Or similar publish profile:

<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
  <PropertyGroup>
    <Configuration>Release</Configuration>
    <Platform>Any CPU</Platform>
    <PublishDir>bin\Release\net8.0\publish\win-x64\</PublishDir>
    <PublishProtocol>FileSystem</PublishProtocol>
    <_TargetId>Folder</_TargetId>
    <TargetFramework>net8.0</TargetFramework>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    <SelfContained>true</SelfContained>
    <PublishSingleFile>false</PublishSingleFile>
    <PublishReadyToRun>false</PublishReadyToRun>
  </PropertyGroup>
</Project>

Expected behavior

The AOT version prints "1.1.1" like regular .NET version.

Actual behavior

The AOT version prints an infinite sequence of "1111111111111...". The loop never ends.

Regression?

No response

Known Workarounds

Uncomment the line Console.Write(a);. In this case, the code works as expected after publishing.

Configuration

I reproduced the issue in the .NET 8 project with win-x64 target platform on Windows 10.

Other information

The line a = null; is removed from the published version.

Metadata

Metadata

Assignees

Labels

Priority:2Work that is important, but not critical for the releasearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

Status

No status

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions