https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116415

--- Comment #4 from Peter Bergner <bergner at gcc dot gnu.org> ---
Here's a C testcase that shows the same problem:

bergner@ltcden2-lp1:BUG$ cat bug.c 
#include <stdio.h>
#include <stdint.h>

typedef union {
  struct {
    uint64_t a;
    uint64_t b;
  } t;
  __uint128_t raw_data;
} Value;
Value value;

static inline void
foo (const uint64_t delta1, const uint64_t delta2)
{
  Value cur;
  cur.raw_data = value.raw_data;
  for (;;) {
    Value next;
    next.t.a = cur.t.a+delta1;
    next.t.b = cur.t.b+delta2;
    if (__atomic_compare_exchange(&value.raw_data, &cur.raw_data,
&next.raw_data, 0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE)) break;
  }
}

int
main (void)
{
  foo (1, 2);
  printf ("%lu %lu\n", value.t.a, value.t.b);
  return 0;
}
bergner@ltcden2-lp1:BUG$ gcc -O2 -mcpu=power8 -mno-optimize-swaps bug.c 
bergner@ltcden2-lp1:BUG$ ./a.out 
1 2
bergner@ltcden2-lp1:BUG$ gcc -O2 -mcpu=power8 -moptimize-swaps bug.c 
bergner@ltcden2-lp1:BUG$ ./a.out 
2 1

Reply via email to