We observe a strange case where in VS2015 Update3 compiler will omit part of the code for no obvious reason.
We found out that
We managed to minimize the culprit code to this snippet:
#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; }
For the lines that say "Loop omitted", the entire loop body is omitted by compiler. Why? To my knowledge, there is no undefined behavior involved.
Disassembly for the first "Loop omitted":
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
Test project: http://dropmefiles.com/S7mwT
Try it online!
/O2
to Additional compiler flags
Run executable after compilation
Bug report: https://developercommunity.visualstudio.com/content/problem/71906/compiler-optimization-code-generation-bug.html
Start the Visual Studio Installer, and verify that Help > About shows version 14.0. 25431 or greater. Examine the installed updates list in Control Panel, and verify that both Visual Studio 2015 update 3 (KB3022398) and the update for Microsoft Visual Studio 2015 (KB3165756) are present.
The Microsoft C/C++ compiler (MSVC) uses a basic rule to determine which language to use when it compiles your code. By default, the MSVC compiler treats all files that end in . c as C source code, and all files that end in .
In addition to the Microsoft Visual C++ compiler that many of you are likely familiar with, Visual Studio 2017 also supports Clang, GCC, and other compilers when targeting certain platforms.
Yes, it's a bug. Specifically, it's a bug in the new SSA optimizer introduced in VS2015 Update 3. The undocumented command line option -d2SSAOptimizer-
tells the compiler backend to use the old optimizer instead, which causes the bug to not manifest.
FYI, you can minimize your repro to:
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; }
which will help the compiler developers localize the problem more quickly.
Addition from Codeguard (I decided that Casey's answer should be THE answer): I have received reply from Microsoft (Gratian Lup, author of blog post Introducing a new, advanced Visual C++ code optimizer):
Yes, this is indeed a bug in the SSA Optimizer itself - usually most bugs reported as being in the new optimizer are in other parts, sometimes exposed now after 20 years.
It's in a small opt. that tries to remove a comparison looking like (a - Const1) CMP (a - Const2), if there is no overflow. The issue is that your code has (1 - indexOffset) CMP (2 - indexOffset) and subtraction is not commutative, of course - but the optimizer code disregards that and handles (1 - indexOffset) as if it's (indexOffset - 1).
A fix for this issue will be released in the next larger update for VS2017. Until then, disabling the SSA Optimizer would be a decent workaround. Disabling optimizations for only this function may be a better approach if it doesn't slow down things too much. This can be done with #pragma optimize("", off): https://msdn.microsoft.com/en-us/library/chh3fb0k.aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With