Bug in cl for x64 (c compiler) - by Dmitry Volkinshtein

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 676417 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 6/22/2011 1:23:24 AM
Access Restriction Public


The following c program gives incorrect results when compiled with full optimization for x64 machine:
#include <stdio.h>

typedef struct {
    int flags;
    int n;
} bug_t;

bug_t _bug;
unsigned short _byteswap_ushort(unsigned short val); /* from <intrin.h> */
#pragma intrinsic(_byteswap_ushort)

int main(int argc, char *argv[])
    volatile bug_t *bug = (volatile bug_t *)&_bug;
    if (bug->flags & 0x200000)
	printf("bad %d\n", _byteswap_ushort(bug->n));
	printf("good %d\n", _byteswap_ushort(bug->n));
    return 0;

Thanks in advance,
Dmitry Volkinshtein
Sign in to post a comment.
Posted by Microsoft on 8/22/2011 at 8:04 PM
Thank you for reporting this issue. This issue has been resolved and the fix will be available in a future release.
Posted by Microsoft on 6/23/2011 at 12:10 PM
I did some more investigating and the problem actually lies in the creation of the BT instruction. The compiler is not changing the jcc instruction to use the CF after creating the BT instruction. This seems to only happen in the case where the rotate instruction sits between the BT and the JCC. You may be able to work around this by 1. writing code that the compiler won't change into BT or 2. write a custom version of _byteswap that doesn't use the ROR instruction. See the codegen from the x86 compiler for an example on how to implement #2.

ian Bearman
VC++ Code Generation and Optimization Team
Posted by Microsoft on 6/23/2011 at 11:46 AM
Dimtry, thanks for reporting this issue. I have verified that the compiler is modeling the rotate instructions incorrectly. The compiler may incorrectly move a rotate instruction between a compare/branch pair. This will be fixed in a future release of visual studio.

Disabling optimizations aroudn the rotate should allow you to work around the problem.

ian Bearman
VC++ Code Generation and Optimization Team
Posted by Dmitry Volkinshtein on 6/22/2011 at 4:32 AM
P.S. While I was working on a workaround, I found out that even without intrinsic _byteswap_ushort, there is a problem.
I wrote my inline byteswap:

static inline unsigned short _byteswap_ushort_fix(unsigned short val)
     return ((val<<8) | (val>>8));

The resulting assembly is still:
ror ax, 8
and the problem still exists

Dmitry Volkinshtein
Posted by MS-Moderator08 [Feedback Moderator] on 6/22/2011 at 2:34 AM
Thank you for reporting the issue.
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 MS-Moderator01 on 6/22/2011 at 1:50 AM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)