Skip to content

JIT: (bug) Ordinary field load is hoisted out of a loop across a Volatile.Read #133579

Description

@EgorBo

Repro

using System;
using System.Runtime.CompilerServices;
using System.Threading;

internal sealed class Box
{
    public int Value;
    public int Ready;
}

internal static class Program
{
    [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
    private static int Reader(Box box)
    {
        int value = 0;
        int seen = 0;
        while (seen < 2)
        {
            value = box.Value;
            if (Volatile.Read(ref box.Ready) != 0)
            {
                seen++;
            }
        }
        return value;
    }

    private static void Main()
    {
        var box = new Box();
        var reader = new Thread(() => Console.WriteLine($"reader saw {Reader(box)}"));
        reader.Start();

        Thread.Sleep(50);
        box.Value = 42;
        Volatile.Write(ref box.Ready, 1);
        reader.Join();
    }
}

Run with DOTNET_TieredCompilation=0.

Expected

reader saw 42

The loop exits only after two iterations saw Ready != 0, so the returned box.Value load runs
after an acquire in an earlier iteration. DOTNET_JitDoLoopHoisting=0 and DOTNET_JITMinOpts=1
both print this, 5 of 5 runs each.

Actual

reader saw 0

Reproduced on 5 of 5 runs. The plain box.Value load is hoisted out of the loop even though it is
followed by a Volatile.Read acquire in the same loop body, so it is executed once before the
writer publishes and never re-read.

Platform

Windows x64, .NET 11 (dotnet/runtime main @ a0b86b1, Checked build). Requires
DOTNET_TieredCompilation=0; no special CPU features.

Activity

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

Metadata

Metadata

Assignees

Labels

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

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions