Cod*_*ard 35 c++ compiler-errors compiler-optimization visual-studio-2015
我们观察到一个奇怪的情况,VS2015 Update3编译器会在没有明显原因的情况下省略部分代码.
我们发现了
我们设法将这个代码段的罪魁祸首最小化:
#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;
}
Run Code Online (Sandbox Code Playgroud)
对于说"循环省略"的行,编译器省略整个循环体.为什么?据我所知,没有涉及未定义的行为.
第一个"循环省略"的反汇编:
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
Run Code Online (Sandbox Code Playgroud)
测试项目:http://dropmefiles.com/S7mwT
在线尝试!
/O2对Additional compiler flagsRun executable after compilation错误报告:https://developercommunity.visualstudio.com/content/problem/71906/compiler-optimization-code-generation-bug.html
Cas*_*sey 24
是的,这是一个错误.具体来说,这是VS2015 Update 3中引入的新SSA优化器中的一个错误.未记录的命令行选项-d2SSAOptimizer-告诉编译器后端使用旧的优化器,这会导致错误无法显示.
仅供参考,您可以将您的repro最小化:
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;
}
Run Code Online (Sandbox Code Playgroud)
这将有助于编译器开发人员更快地本地化问题.
来自Codeguard的加法(我认为Casey的回答应该是答案):我收到了微软的回复(Gratian Lup,博客文章的作者介绍了一个新的,高级的Visual C++代码优化器):
是的,这确实是SSA优化器本身的一个错误 - 通常报告为新优化器中的大多数错误都在其他部分,有时在20年后暴露出来.
这是一个小选择.试图删除比较看起来像(a - Const1)CMP(a - Const2),如果没有溢出.问题是你的代码有(1 - indexOffset)CMP(2 - indexOffset)和减法当然不是可交换的 - 但是优化器代码忽略了它并处理(1 - indexOffset)就像它(indexOffset - 1)一样.
此问题的修复程序将在VS2017的下一个更大更新中发布.在此之前,禁用SSA优化器将是一个不错的解决方法.如果不太慢,那么仅对此函数禁用优化可能是更好的方法.这可以通过#pragma optimize("",off)完成:https: //msdn.microsoft.com/en-us/library/chh3fb0k.aspx
| 归档时间: |
|
| 查看次数: |
1816 次 |
| 最近记录: |