Home Dashboard Directory Help

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


 as Fixed Help for as Fixed

Sign in
to vote
Type: Bug
ID: 770433
Opened: 11/7/2012 9:37:30 PM
Access Restriction: Public
User(s) can reproduce this bug


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 Microsoft 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 Microsoft 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)
Sign in to post a workaround.