Incorrect shift left/right optimization - by Tom Lyons

Status : 

  Fixed<br /><br />
		This item has been fixed in the current or upcoming version of this product.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.

Sign in
to vote
ID 634455 Comments
Status Closed Workarounds
Type Bug Repros 1
Opened 1/3/2011 1:53:33 PM
Access Restriction Public


The following code, when executed as "bug.exe 1 2 3 4", prints "1" in VC10 with "-O1". Without optimization (and in VC7) it prints "5".

#include <stdio.h>

int main(int argc, char **argv)
  printf("%d\n", ((argc << 29) >> 31) & 5);

This is the incorrect generated code:

tag # dumpbin /DISASM bug.obj
Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

Dump of file bug.obj


  00000000: 8B 44 24 04        mov         eax,dword ptr [esp+4]
  00000004: C1 F8 02           sar         eax,2
  00000007: 83 E0 05           and         eax,5
  0000000A: 50                 push        eax
  0000000B: 68 00 00 00 00     push        offset ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
  00000010: E8 00 00 00 00     call        _printf
  00000015: 83 C4 08           add         esp,8
  00000018: 33 C0              xor         eax,eax
  0000001A: C3                 ret


          10 .debug$F
          68 .debug$S
          2F .drectve
           4 .rdata
          1B .text
Sign in to post a comment.
Posted by Microsoft on 1/7/2011 at 10:53 AM
Thanks for reporting this issue that you've found. We have a fix for this problem. Unfortunately, we're unable to include a fix for this in the upcoming service pack, but a fix will be included in a future release of Visual Studio.

In the meantime you can work around this optimization issue by disabling the optimizer for the function that is exhibiting the incorrect behavior. You can do this by putting the code in a seperate file and compiling without optimizations or use #pragma optimization. See this page: for more informaiton on using #pragma optimize.

VC++ Code Generation and Optimization Team
Posted by Microsoft on 1/7/2011 at 12:27 AM
Thanks for your feedback.
We are routing this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.
Posted by Tom Lyons on 1/5/2011 at 7:18 AM
Our system uses makefiles which run the compiler from the command line, but I just followed the same steps as
you outline to do it from the UI and the output is '1', as verified by the previous commenter. It is necessary that optimization be on in the project. I am using

Microsoft Visual Studio 2010
Version 10.0.30319.1 RTMRel

You can see from the included asm dump in the original report that the code will produce 1, and not 5. Here is the code without optimization, that actually does both shl/sar. These dumps were from .obj files using the /c compiler flag.

tag # dumpbin /DISASM bug.obj
Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.

Dump of file bug.obj


00000000: 55                 push        ebp
00000001: 8B EC             mov         ebp,esp
00000003: 8B 45 08         mov         eax,dword ptr [ebp+8]
00000006: C1 E0 1D         shl         eax,1Dh
00000009: C1 F8 1F         sar         eax,1Fh
0000000C: 83 E0 05         and         eax,5
0000000F: 50                 push        eax
00000010: 68 00 00 00 00     push        offset $SG2641
00000015: E8 00 00 00 00     call        _printf
0000001A: 83 C4 08         add         esp,8
0000001D: 33 C0             xor         eax,eax
0000001F: 5D                 pop         ebp
00000020: C3                 ret
Posted by Microsoft on 1/4/2011 at 1:51 AM
Thank you for reporting this issue. Unfortunately, we are unable to reproduce the issue with the steps you provided. We tried to repro with the following steps:

1. Create a CPP empty project and add a source file to it
2. Paste the sample code to the source file
3. Set Property Pages->Configuration properties->Debugging->Command Arguments as "1 2 3 4"
4. Build and Run, and it prints 5

Could you please provide us with the following information?

1. Help to point out the steps misunderstood or omitted.
2. Some screenshots to show this issue, and a vedio can be much better.

It would be greatly appreciated if you could provide us this information as quickly as possible.

Thank you,
Posted by Avery Lee on 1/3/2011 at 8:49 PM
The code isn't portable, but it's perfectly valid for an implementation that defines signed right shifts to sign extend as VC++ does. It is a bug, and apparently one in a new shift/and optimization.

I'm also seeing this bug with VS2010 SP1 beta, btw.
Posted by Mike Danes on 1/3/2011 at 2:43 PM
Fun one. According to the C++ standard right shifting a negative value is implementation dependent so this isn't a bug. But according to the VC++ docs ( right shifting should extend the sign.
Posted by Microsoft on 1/3/2011 at 2:23 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(