Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RyuJit producing incorrect results

After recently upgrading to .net 4.6 we discovered a bug where RyuJit produces incorrect results, we were able to work around the issue for now by adding useLegacyJit enabled="true" to the app.config.

How can I debug the machine code generated by the following?

I created a new console project in VS 2015 RTM, set to Release, Any CPU, unchecked Prefer 32 bit, running with and without debugger attached produces the same result.

using System;
using System.Runtime.CompilerServices;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Calculate());
            Console.WriteLine(Calculate());

            Console.ReadLine();
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static Value Calculate()
        {
            bool? _0 = (bool?)null;
            bool? _1 = (bool?)true;
            if (!Value.IsPresent<bool>(_1))
            {
                return default(Value);
            }

            bool? result = null;
            result = (_1.Value ? new bool?(false) : result);
            if (_0.HasValue && _0.Value)
            {
            }
            return new Value(result);
        }

        public struct Value
        {
            bool? _value;

            public Value(bool? value)
            {
                _value = value;
            }

            public static bool IsPresent<T>(bool? _)
            {
                return _.HasValue;
            }

            public override string ToString()
            {
                return _value.ToString();
            }
        }
    }
}

It should produce: False False

but instead it produces: True False

The key part of the example is

result = true ? false : result;

Which should always return false, but as you can see from the output, it returns True the first time the method is run, and a different answer the second time the method is run. Removing some more lines from the Calculate() method will cause it to return True always, but the example given is the closest I could reproduce to our actual production scenario.

like image 710
BrandonAGr Avatar asked Jul 22 '15 17:07

BrandonAGr


1 Answers

Thank you for the isolated repro program and I can confirm that this is indeed a RyuJIT bug in the optimizer which got exposed due to inlining. I've made a fix to the compiler and figuring the roll out details. Not to turn SO into a bug tracker, and for a quicker turnaround: [email protected].

like image 127
schellap Avatar answered Nov 05 '22 22:11

schellap