http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50583
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
CC| |jakub at gcc dot gnu.org
Resolution| |INVALID
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-09-30
18:49:29 UTC ---
(In reply to comment #3)
> movl (%rdi), %eax
> .L2:
> movl %eax, %edx
> andl $7, %edx
> lock cmpxchgl %edx, (%rdi)
> jne .L2
> movl %edx, %eax
> It is
>
> {
> tmp = *ptr;
> do
> {
> tmp1 = tmp OP value;
> }
> while (__sync_val_compare_and_swap (ptr, tmp, tmp1) != tmp);
> return tmp1;
> }
>
> If *ptr is changed between load and cmpxchg, we get an infinite loop.
No, you aren't translating the asm correctly back into C.
It is
tmp = *ptr;
do
tmp1 = tmp OP value; tmp2 = tmp;
while ((tmp = __sync_val_compare_and_swap (ptr, tmp2, tmp1) != tmp2);
return tmp1;
because cmpxchgl instruction loads the *ptr value from memory into %eax if the
instruction has been unsuccessful. So, tmp is loaded with the new value for
the next iteration.