We compile our project with x64 compiler of VS2005 and 2008. For both we have installed the available ServicePacks and some HotFixes. We have had a bug and an analysis shows us that the x64 compiler generates wrong code with compiler option /O2.
We tried to create a simple app to demonstrate the wrong compilation result. Here it is:
#include "stdio.h" // just an external function... // returns e.g. 4 int GetValue(); void main(int argc, char* argv[]) { int nb = GetValue(); for ( int i = 0; i < nb; i++) { int pos = i*2+1; if (!(pos >= 0)) printf( "You will never see this message!\n"); } }
I compile it with x64 cross compiler: cl /c /O2 test.cpp
This generates just the resulting object file. With dumpbin /DISASM test.objwe can have a look for assembly code.
0000000000000000: 48 89 5C 24 08 mov qword ptr [rsp+8],rbx 0000000000000005: 57 push rdi 0000000000000006: 48 83 EC 20 sub rsp,20h 000000000000000A: E8 00 00 00 00 call ?GetValue@@YAHXZ 000000000000000F: 33 DB xor ebx,ebx 0000000000000011: 8B F8 mov edi,eax 0000000000000013: 85 C0 test eax,eax 0000000000000015: 7E 17 jle 000000000000002E 0000000000000017: 83 FB 01 cmp ebx,1 000000000000001A: 7D 0C jge 0000000000000028 000000000000001C: 48 8D 0D 00 00 00 lea rcx,[??_C@_0CK@GKDIKOJA@You?5will?5never?5see?5this?5message?$CB@] 00 0000000000000023: E8 00 00 00 00 call printf 0000000000000028: FF C3 inc ebx 000000000000002A: 3B DF cmp ebx,edi 000000000000002C: 7C E9 jl 0000000000000017 000000000000002E: 33 C0 xor eax,eax 0000000000000030: 48 8B 5C 24 30 mov rbx,qword ptr [rsp+30h] 0000000000000035: 48 83 C4 20 add rsp,20h 0000000000000039: 5F pop rdi 000000000000003A: C3 ret
On line 0x17 there is a compare statement. It compares 0 with 1. Because 0 is never greater 1, the app will not jump to location 0x28. We will see the printf() message, but this should not happen, this makes no sense!
If we compile the same code without optimizer option then the app behaves as expected. If we compile with compiler of VS2012 everthing is fine with or without /O2.
Unfortunately, we cannot switch to VS2012 because we depend on third party products which are compiled with VS2005 or VS2008.
We can modify our code somehow and the generated code looks than fine. This is a workaround. This works just for a small piece of code which we know that it generates problems with optimizer. It is highly possible that more such kind of generated code exists in our product.
We are looking for a Hotfix. Is there anybody who has seen something similar? Any ideas?
Dominik.