Skip to content

Side-effects of precise static constructors not respected by optimizations #121066

@jkotas

Description

@jkotas

Description

From #120688 (comment)

Failures are related to Inline Opt, CSE opt and RedundantBranch Opt. Is it known issue? And I just tested by giving mutatesHeaps property to INITCLASS helper. It seems work. I don't know why INITCLASS helper has isPure and doesn't have mutatesHeaps property?

Reproduction Steps

class Test
{
    public static int preciseInitCctorsRun = 0;

    class MyPreciseInitClass<T>
    {
        static MyPreciseInitClass()
        {
            preciseInitCctorsRun++;
        }

        public static void TriggerCctorClass()
        {
        }

        public static void TriggerCctorMethod<U>()
        { }
    }

    class MyClass<T>
    {
        static Type staticVarType = typeof(MyClass<T>);
        public Type GetTypeOf()
        {
            return typeof(MyClass<T>);
        }
        public static Type GetTypeOfStatic()
        {
            return typeof(MyClass<T>);
        }

        public static Type GetTypeThroughStaticVar()
        {
            return staticVarType;
        }
    }

    public static bool TestPreciseInitCctors()
    {
        if (preciseInitCctorsRun != 0)
        {
            Console.WriteLine("preciseInitCctorsRun should be 0, but is {0}", preciseInitCctorsRun);
            return false;
        }
        MyPreciseInitClass<int>.TriggerCctorClass();
        if (preciseInitCctorsRun != 1)
        {
            Console.WriteLine("preciseInitCctorsRun should be 1, but is {0}", preciseInitCctorsRun);
            return false;
        }
        MyPreciseInitClass<short>.TriggerCctorMethod<int>();
        if (preciseInitCctorsRun != 2)
        {
            Console.WriteLine("TriggerCctorClass should return 2, but is {0}", preciseInitCctorsRun);
            return false;
        }

        object o = new MyPreciseInitClass<double>();
        if (preciseInitCctorsRun != 3)
        {
            Console.WriteLine("TriggerCctorClass should return 3, but is {0}", preciseInitCctorsRun);
            return false;
        }

        MyPreciseInitClass<object>.TriggerCctorClass();
        if (preciseInitCctorsRun != 4)
        {
            Console.WriteLine("preciseInitCctorsRun should be 4 but is {0}", preciseInitCctorsRun);
            return false;
        }
        MyPreciseInitClass<string>.TriggerCctorMethod<object>();
        if (preciseInitCctorsRun != 5)
        {
            Console.WriteLine("TriggerCctorClass should return 5, but is {0}", preciseInitCctorsRun);
            return false;
        }

        o = new MyPreciseInitClass<Type>();
        if (preciseInitCctorsRun != 6)
        {
            Console.WriteLine("TriggerCctorClass should return 6,  but is {0}", preciseInitCctorsRun);
            return false;
        }

        return true;
    }

    static void Main()
    {
        Console.WriteLine(TestPreciseInitCctors());
    }
}

Expected behavior

True

Actual behavior

C:\repro\bin\release\net10.0>set DOTNET_TieredCompilation=0

C:\repro\bin\release\net10.0>repro.exe
preciseInitCctorsRun should be 1, but is 0
False

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

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

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions