RyuJit产生不正确的结果

时间:2015-07-22 17:53:47

标签: c# jit c#-6.0 .net-4.6 ryujit

在最近升级到.net 4.6之后,我们发现了RyuJit产生错误结果的错误,我们现在可以通过添加useLegacyJit enabled =" true"来解决这个问题。到app.config。

如何调试以下生成的机器代码?

我在VS 2015 RTM中创建了一个新的控制台项目,设置为Release,Any CPU,unchecked Prefer 32 bit,运行时带或不带调试器会产生相同的结果。

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();
            }
        }
    }
}

它应该产生: 假 假

但它产生: 真正 假

示例的关键部分是

result = true ? false : result;

哪个应该总是返回false,但是从输出中可以看出,它在第一次运行方法时返回True,第二次运行方法时返回不同的答案。从Calculate()方法中删除更多行将导致它始终返回True,但给出的示例是我可以重现到我们实际生产场景的最接近的行。

1 个答案:

答案 0 :(得分:27)

感谢您使用隔离的repro程序,我可以确认这确实是优化器中的RyuJIT错误,该错误因内联而暴露出来。我已经修复了编译器并计算了推出的细节。不要将SO转变为错误跟踪器,以及更快的周转时间:ryujit@microsoft.com。