Home Dashboard Directory Help

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


 as Fixed Help for as Fixed

Sign in
to vote
Type: Bug
ID: 676417
Opened: 6/22/2011 1:23:24 AM
Access Restriction: Public
Moderator Decision: Sent to Engineering Team for consideration
User(s) can reproduce this bug


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)
Sign in to post a workaround.
File Name Submitted By Submitted On File Size  
test2.zip 6/22/2011 651 KB