Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forward substitution for relops can create new data races #62048

Closed
SingleAccretion opened this issue Nov 25, 2021 · 3 comments · Fixed by #62224
Closed

Forward substitution for relops can create new data races #62048

SingleAccretion opened this issue Nov 25, 2021 · 3 comments · Fixed by #62224
Assignees
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI bug
Milestone

Comments

@SingleAccretion
Copy link
Contributor

SingleAccretion commented Nov 25, 2021

Reproduction:

public class Program
{
    private static int _intStatic;

    private static void Main()
    {
        for (int i = 0; i < Environment.ProcessorCount; i++)
        {
            new Thread(() =>
            {
                while (true)
                {
                    Volatile.Write(ref _intStatic, 0);
                    Volatile.Write(ref _intStatic, 1);
                }
            }).Start();
        }

        while (true)
        {
            Problem(ref _intStatic);
        }
    }
    
    [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
    private static void Problem(ref int a)
    {
        var b = Volatile.Read(ref a) == 0;
        var c = b;
        if (b)
        {
            Assert(c);
        }
    }
    
    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void Assert(bool b)
    {
        if (!b)
        {
            throw new Exception("!!!");
        }
    }
}

Eventually this program will throw an exception, even as one would think it never should.

The cause is that in the branch forward substitution optimization, we copy the indirection and end up with two indirections (that can, naturally, disagree).

It is unclear to me whether this new behavior can be considered correct or not.

@dotnet/jit-contrib

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Nov 25, 2021
@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@SingleAccretion SingleAccretion added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Nov 25, 2021
@ghost
Copy link

ghost commented Nov 25, 2021

Tagging subscribers to this area: @JulieLeeMSFT
See info in area-owners.md if you want to be subscribed.

Issue Details

Reproduction:

public class Program
{
    private static int _intStatic;

    private static void Main()
    {
        for (int i = 0; i < Environment.ProcessorCount; i++)
        {
            new Thread(() =>
            {
                while (true)
                {
                    Volatile.Write(ref _intStatic, 0);
                    Volatile.Write(ref _intStatic, 1);
                }
            }).Start();
        }

        while (true)
        {
            Problem(ref _intStatic);
        }
    }
    
    [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
    private static void Problem(ref int a)
    {
        var b = Volatile.Read(ref a) == 0;
        var c = b;
        if (b)
        {
            Assert(c);
        }
    }
    
    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void Assert(bool b)
    {
        if (!b)
        {
            throw new Exception("!!!");
        }
    }
}

Eventually this program will throw an exception, even as one would think it never should.

This cause is that in the branch forward substitution optimization, we copy the indirection and end up with two indirections (that can, naturally, disagree).

It is unclear to me whether this new behavior can be considered correct or not.

@dotnet/jit-contrib

Author: SingleAccretion
Assignees: -
Labels:

area-CodeGen-coreclr, untriaged

Milestone: -

@jkotas jkotas added the bug label Nov 25, 2021
@JulieLeeMSFT JulieLeeMSFT added this to the .NET 7.0 milestone Nov 29, 2021
@JulieLeeMSFT JulieLeeMSFT removed the untriaged New issue has not been triaged by the area owner label Nov 29, 2021
@karelz karelz modified the milestones: .NET 7.0, 7.0.0 Nov 30, 2021
@AndyAyersMS
Copy link
Member

Thanks for pointing this out. We should be more careful here.

@AndyAyersMS AndyAyersMS self-assigned this Nov 30, 2021
AndyAyersMS added a commit to AndyAyersMS/runtime that referenced this issue Dec 1, 2021
The copy may not get the same value as the original.

Closes dotnet#62048.
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Dec 1, 2021
AndyAyersMS added a commit that referenced this issue Dec 2, 2021
The copy may not get the same value as the original.
Detect this by looking for `GTF_ORDER_SIDEEFF`.

Closes #62048.
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Dec 2, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Jan 1, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants