在最近升级到.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,但给出的示例是我可以重现到我们实际生产场景的最接近的行。
答案 0 :(得分:27)
感谢您使用隔离的repro程序,我可以确认这确实是优化器中的RyuJIT错误,该错误因内联而暴露出来。我已经修复了编译器并计算了推出的细节。不要将SO转变为错误跟踪器,以及更快的周转时间:ryujit@microsoft.com。