Visual Studio 2015更新3-C ++编译器错误?

Codeguard:

我们观察到一个奇怪的情况,在VS2015 Update3中,编译器会无缘无故地省略部分代码。

我们发现

  • 这在VS2015 Update3中发生(“帮助|关于说14.0.25431.01 Update 3,cl.exe版本19.00.24215.1”)
  • 在VS2015 Update2中不会发生这种情况(“帮助|关于”说14.0.25123.00 Update 2,cl.exe版本19.00.23918)
  • 仅当启用优化时才会发生这种情况(例如,在默认的Release配置中)
  • 发生在x86和x64中
  • 将代码段插入全新的“ Win32控制台应用程序”时发生(我的意思是,不需要花哨的命令行选项)

我们设法将此代码段的元凶代码最小化:

#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>

int _tmain(int, _TCHAR*[])
{
    volatile int someVar = 1;

    const int indexOffset = someVar ? 0 : 1;    // Loop omitted
    // const int indexOffset = !someVar;        // Loop omitted
    // const int indexOffset = 0;               // Good
    // const int indexOffset = 1;               // Good
    // const int indexOffset = someVar;         // Good
    // const int indexOffset = someVar + 1;     // Good

    for (int i = 1 - indexOffset; i < 2 - indexOffset; ++i)
    {
        printf("Test passed\n");
    }

    return 0;
}

对于说“省略循环”的行,编译器将省略整个循环体。为什么?据我所知,没有涉及未定义的行为。


拆卸第一个“省略的循环”:

int _tmain(int, _TCHAR*[])
{
01151010  push        ebp  
01151011  mov         ebp,esp  
01151013  push        ecx  
    volatile int someVar = 1;
01151014  mov         dword ptr [ebp-4],1  

    const int indexOffset = someVar ? 0 : 1;    // Loop omitted
0115101B  mov         eax,dword ptr [someVar]  
    // const int indexOffset = !someVar;        // Loop omitted
    // const int indexOffset = 0;               // Good
    // const int indexOffset = 1;               // Good
    // const int indexOffset = someVar;         // Good
    // const int indexOffset = someVar + 1;     // Good

    for (int i = 1 - indexOffset; i < 2 - indexOffset; ++i)
    {
        printf("Test passed\n");
    }

    system("pause");
0115101E  push        offset string "pause" (011520F8h)  
01151023  call        dword ptr [__imp__system (0115205Ch)]  
01151029  add         esp,4  
    return 0;
0115102C  xor         eax,eax  
}
0115102E  mov         esp,ebp  
01151030  pop         ebp  
01151031  ret

测试项目:http//dropmefiles.com/S7mwT


在线尝试!


错误报告:https : //developercommunity.visualstudio.com/content/problem/71906/compiler-optimization-code-generation-bug.html

凯西

是的,这是一个错误。具体来说,这是VS2015 Update 3中引入的新SSA优化器中的一个错误。未记录的命令行选项-d2SSAOptimizer-告诉编译器后端改用旧的优化器,这导致该错误不明显

仅供参考,您可以最大程度地减少以下方面的重复性:

int main()
{
    volatile int someVar = 1;

    const int indexOffset = someVar ? 0 : 1;

    for (int i = 1 - indexOffset; i < 2 - indexOffset; ++i)
    {
        return 0;
    }
    return 1;
}

这将有助于编译器开发人员更快地定位问题。


从另外的CodeGuard(我决定,凯西的答案应该是答案):我收到的回复来自微软(格拉提安Lup中,博客文章的作者介绍一个新的,先进的Visual C ++代码优化):

是的,这确实是SSA Optimizer本身的错误-通常,报告为新优化器中的大多数错误都存在于其他部分,有时在20年后就会暴露出来。

这是一个小选择。如果没有溢出,则尝试删除看起来像(a-Const1)CMP(a-Const2)的比较。问题是您的代码具有(1-indexOffset)CMP(2-indexOffset),并且减法当然不是可交换的-但是优化程序代码忽略了这一点,并像(indexOffset-1)一样处理(1-indexOffset)。

VS2017的下一个较大更新中将发布此问题的修复程序。在此之前,禁用SSA Optimizer将是一个不错的解决方法。如果禁用此功能的优化不会使速度变慢,则可能是更好的方法。可以使用#pragmaoptimize(“”,off)完成:https : //msdn.microsoft.com/en-us/library/chh3fb0k.aspx

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

也许是Visual Studio 2015中的C#编译器错误

是否可以将Visual C ++ v120编译器工具集添加到Visual Studio 2015?

Visual Studio 2013和2015中的C ++编译器错误C2280“试图引用已删除的函数”

Visual Studio 2015更新1,c错误

如何在Visual Studio 2015中使用roslyn C#编译器?

Visual Studio C ++编译器怪异行为

Visual Studio 2015更新1中C ++的内部编译器错误

Visual Studio 2015-编译器警告(等级2)C4146

更改完全不相关的代码时,Visual Studio C ++编译器生成慢3倍的代码

如何解决“ Build:Unknown编译器选项'listemittedfiles'。” 在Visual Studio 2015 Update 3上?

Python 3,如何设置Visual Studio C ++ 2015编译器?

Visual Studio 2013中可能的C / C ++编译器错误

使用Visual Studio编译器分析内联的C ++函数

自Visual Studio 15.6.2编译器更新标准以来,是否存在新的C ++ 17 [[nodiscard]]警告?

Visual Studio 2015 C ++编译器可能提供代码内指令集标记

编译器错误CS1061 Visual Studio

仅在发行版中的Visual Studio 2019“ C1001内部编译器错误”

这是Visual Studio 2010编译器中的错误吗?

C ++:使用Visual Studio编译器时的const指针

拆解Visual Studio Intel编译器C ++代码

什么是 ?和@符号表明此编译器错误?-Visual Studio 2013编译器

可能的Visual Studio 2015 C ++编译器和IntelliSense错误

Visual Studio 2015中的编译器是什么

哪些编译器选项用于在Visual Studio中编译C ++ STL类/函数?

Visual Studio 2015-缺少64位编译器

Visual Studio 可能是错误的编译器错误

Visual Studio 2015 的 r 工具中的 Rcpp 编译器错误

Visual Studio C++ 编译器尝试编译 CUDA C/C++ 文件

如何使用 Visual Studio 编译器在 Windows 上编译 cython 编译的 c 代码