http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55966



--- Comment #1 from Andi Kleen <andi-gcc at firstfloor dot org> 2013-01-14 
19:06:02 UTC ---

Here's a test case. This requires the libstdc++ HLE patch from

http://gcc.gnu.org/ml/gcc-patches/2013-01/msg00673.html



g++ -std=gnu++0x



#include <atomic>



#define ACQ memory_order_acquire | __memory_order_hle_acquire

#define REL memory_order_release | __memory_order_hle_release



int main()

{

  using namespace std;

  atomic_ulong au = ATOMIC_VAR_INIT(0);



  if (!au.fetch_and(1, ACQ))

    au.fetch_and(-1, REL);



  unsigned lock = 0;

  __atomic_fetch_and(&lock, 1, __ATOMIC_HLE_ACQUIRE|__ATOMIC_ACQUIRE);



  return 0;

}



The first fetch_and generates incorrectly:



.L2:

        movq    %rax, %rcx

        movq    %rax, %rdx

        andl    $1, %ecx

        lock; cmpxchgq  %rcx, -24(%rsp)

        jne     .L2





The second generates correctly:



        lock; 

        .byte   0xf3

        andq    $-1, -24(%rsp)





The __atomic_fetch_and generates correctly:



     lock; 

        .byte   0xf2

        andl    $1, -28(%rsp)





The first fetch_and should generate the same code sequence.

Reply via email to