Wrong ARM code with /O2 optimizations - by Mārtiņš Možeiko

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 770433 Comments
Status Closed Workarounds
Type Bug Repros 1
Opened 11/7/2012 9:37:30 PM
Access Restriction Public


Following C++ code fragment generates incorrect ARM machine code.

static unsigned long long Foo(unsigned long long a0)
    return (15849689698036411425ULL * a0 << 28) + 7806753552930010092LL;

static unsigned long long Bar(unsigned long long a0, unsigned long long a1)
    return 13321957801405570171ULL * a0 + 3349182078252791521LL * a1 + 4322231949668103995LL;

static void FooBar(unsigned long long a0, unsigned long long& a1)
    volatile unsigned long long temp1 = 8157439093432398537;
    unsigned long long temp2 = Foo(temp1);
    a1 = Bar(a0, temp2);

void bug1()
    volatile unsigned long long a0 = 8624364270469118943;
    unsigned long long a1;
    FooBar(a0, a1);
    printf("%I64u", a1);
Sign in to post a comment.
Posted by Deon [MSFT] on 4/29/2014 at 12:31 PM
Thank you for reporting this issue. This issue has been fixed in Visual Studio 2013. You can install a trial version of Visual Studio 2013 with the fix from: http://go.microsoft.com/?linkid=9832436
Posted by astraujums on 2/27/2014 at 1:49 PM
This bug (or a similar one) is still present in Visual Studio 2013 Express, Update 1.

The following code gives wrong results when compiled with C++ for WinRT on ARM in Release mode:
    static void bug(const unsigned long long a0, unsigned long long& a1, unsigned long long& a2)
        unsigned long long temp1;
        unsigned long long temp2;
        unsigned long long temp3;
        temp1 = 11794403323049885669ULL * a0 + 15402883231688721694ULL;
        temp2 = (27311507379LL * temp1 << 25) + 5844321175777245670LL;
        a1 = 15854288716671590517ULL * a0 + 937334214303480469LL * temp2 + 9531644236239493757ULL;
        temp3 = (224592229 * temp1 << 37) + 6813113282821120822LL;
        a2 = 11264856103282134509ULL * temp1 + 7415422625528488723LL * temp3;

    static void Test()
        unsigned long long arg1 = 0;
        unsigned long long t0 = 15854238716671580517ULL;
        bug(t0, arg1, t0);
        unsigned long* t0_arr = reinterpret_cast<unsigned long*>(&t0);
        printf("t0 = %08x%08x\n", t0_arr[1], t0_arr[0]);

The correct output is:
t0 = 0aabae838a6f032d

The received output is:
t0 = 3d162ec28a6f032d
Posted by Microsoft on 11/8/2012 at 5:41 PM
Thanks for your feedback.

We are rerouting this issue to the appropriate group within the Microsoft Visual Studio Connect Support Team for triage and resolution. These specialized experts will follow-up with your issue.
Posted by Macy [MSFT] on 11/7/2012 at 9:51 PM
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)