Skip to Main Content

DevOps, CI/CD and Automation

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Studio 12.5 miscompiles std::atomic<int>::fetch_add

kovalJul 31 2017 — edited Aug 3 2017

Studio 12.5 C++ compiler generates incorrect code for fetch_add method in std::atomic

The problem occurs at optimization level -xO3 and higher

#include <atomic>

std::atomic<int> counter = ATOMIC_VAR_INIT(0);

int main()

{

    if (counter.fetch_add(1, std::memory_order_release) == 0)

        counter.fetch_sub(1, std::memory_order_release);

    return counter;

}

The if generates following assembly:

{      514  } movl $1,%eax

{      514  } lock xaddl %eax,counter

{           } movl %eax,-12(%ebp) / sym=.CV0

{      514  } jne .L77000030.57

{      524  } .L77000028.58:

{      524  } movl $-1,%eax

{      524  } lock xaddl %eax,counter

{      396  } .L77000030.57:

{      396  } movl counter,%eax

The jump (514) suggests that the optimizer assumes xaddl setting flags for the original value (i.e. result of function fetch_add) which is wrong - xaddl sets the flags to represent result of addition, i.e. the new value

The bug causes QMutex class of Qt 5.9 to get into infinite loop, there is code which tests result of fetch_add against 0 like in my example.

Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Aug 31 2017
Added on Jul 31 2017
4 comments
363 views