- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
the do-while loop in the following code segment won't terminate in release mode.
(Windows 7, Visual Studio 2013, ICL version 15.0.3.208 Build 20150407)
unsigned short arr[256]; signed char index = SCHAR_MIN; do { arr[(unsigned char)index] = (unsigned short)index; } while(index++ < SCHAR_MAX);
Compiled in release mode with:
/GS /W3 /Gy /Zc:wchar_t /Zi /O2 /Ob2 /Fd"x64\Release\vc120.pdb" /Quse-intel-optimized-headers /D "_HAS_EXCEPTIONS=0" /D "_WIN64" /D "NDEBUG" /D "_CONSOLE" /D "_LIB" /D "_UNICODE" /D "UNICODE" /Qipo /Zc:forScope /arch:AVX /Oi /MD /Fa"x64\Release\" /EHsc /nologo /Fo"x64\Release\" /Qprof-dir "x64\Release\" /Fp"x64\Release\testing.pch"
In debug mode everything goes fine. Debug mode compiler arguments:
/GS /W3 /Zc:wchar_t /Zi /Od /Fd"x64\Debug\vc120.pdb" /D "_HAS_EXCEPTIONS=0" /D "_WIN64" /D "_DEBUG" /D "_CONSOLE" /D "_LIB" /D "_UNICODE" /D "UNICODE" /Zc:forScope /RTC1 /arch:AVX /MDd /Fa"x64\Debug\" /EHsc /nologo /Fo"x64\Debug\" /Qprof-dir "x64\Debug\" /Fp"x64\Debug\testing.pch"
When inserting a print statement after the array access the issue is gone.
Thank you.
-------------------------
ASM Code:
Release:
signed char index = SCHAR_MIN; 000000013F481049 xor eax,eax do { arr[(unsigned char)index] = (unsigned char)index; 000000013F48104B vpshufd xmm0,xmm0,0 000000013F481050 vpaddb xmm5,xmm1,xmm0 000000013F481054 vpaddb xmm8,xmm5,xmm0 000000013F481058 vpaddb xmm11,xmm8,xmm0 unsigned short arr[256]; signed char index = SCHAR_MIN; 000000013F48105C add eax,0FFFFFF80h do { arr[(unsigned char)index] = (unsigned char)index; 000000013F48105F vpaddb xmm14,xmm11,xmm0 000000013F481063 vpaddb xmm2,xmm14,xmm0 000000013F481067 vpaddb xmm5,xmm2,xmm0 000000013F48106B vpaddb xmm8,xmm5,xmm0 000000013F48106F vpaddb xmm1,xmm8,xmm0 000000013F481073 jmp main+50h (013F481050h)
Release with print statement:
signed char index = SCHAR_MIN; 000000013F8D106E mov ebx,0FFFFFF80h do { arr[(unsigned char)index] = (unsigned char)index; std::cout << index << std::endl; 000000013F8D1073 mov edx,ebx 000000013F8D1075 mov rcx,qword ptr [__imp_std::cout (013F8DF0A0h)] 000000013F8D107C call std::operator<< (013F8D2B30h) 000000013F8D1081 mov rcx,rax 000000013F8D1084 lea rdx,[std::endl (013F8D6850h)] 000000013F8D108B call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (013F8DF150h)] } while(index++ < SCHAR_MAX); 000000013F8D1091 movsx rax,bl 000000013F8D1095 inc ebx 000000013F8D1097 cmp eax,7Fh 000000013F8D109A jl main+73h (013F8D1073h)
Debug:
signed char index = SCHAR_MIN; 000000013FCF2B0D mov byte ptr [rbp],80h do { arr[(unsigned char)index] = (unsigned char)index; 000000013FCF2B11 movsx eax,byte ptr [rbp] 000000013FCF2B15 movsx rax,al 000000013FCF2B19 movzx eax,al 000000013FCF2B1C lea rdx,[arr] 000000013FCF2B23 movsx ecx,byte ptr [rbp] 000000013FCF2B27 movsx rcx,cl 000000013FCF2B2B movzx ecx,cl 000000013FCF2B2E imul rcx,rcx,2 000000013FCF2B32 add rdx,rcx 000000013FCF2B35 mov word ptr [rdx],ax } while(index++ < SCHAR_MAX); 000000013FCF2B38 movsx eax,byte ptr [rbp] 000000013FCF2B3C movsx rax,al 000000013FCF2B40 mov dword ptr [rbp+4],eax 000000013FCF2B43 movsx eax,byte ptr [rbp] 000000013FCF2B47 mov edx,1 000000013FCF2B4C add eax,edx 000000013FCF2B4E mov byte ptr [rbp],al 000000013FCF2B51 mov eax,dword ptr [rbp+4] 000000013FCF2B54 cmp eax,7Fh 000000013FCF2B57 jl main+0C9h (013FCF2B11h)
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This may be a case of the optimization process not removing the entire loop due to it being dead code. (IOW arr is not used after initialization). Try to fool the compiler into your using it:
unsigned short arr[256]; signed char index = SCHAR_MIN; do { arr[(unsigned char)index] = (unsigned short)index; } while(index++ < SCHAR_MAX); // dummy statement to use something in arr if(arr[99] == 0) std::cout << "this won't happen";
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In cases like this, it might be useful to have a #pragma that turns off/on dead code elimination. Though I'd place this at the bottom of the wish list.
Example of practical use is you have an array that traces progress of various sections of your (Release) code and this trace array is not used by any of your code (other than for writing progress updates). The array is use though in a post-mortem dump or debug session. Currently one must resort to inserting something apparently useless, as I did above. Note, at some point, compiler optimization may advance to a point where you otherwise useless statements are recognized as such and are eliminated, then this undoes your attempt at thwarting dead code elimination.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Markus,
Would you please upload a preprocessed source file, so that we can try to compile it with different options? Otherwise, please at lease show us a bigger code snippet or even better, the whole function.
Thanks.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page