Reordering with atomic

#include <atomic>
using namespace std;
atomic_ullong a_4;
int16_t g_69;
int16_t g_83;
uint64_t func_2 (uint64_t);
int16_t func_9 (int64_t);
void
func_1 () {
  func_2 (0);
}
uint64_t
func_2 (uint64_t) {
  if (func_9 (a_4.load () ), 1)
    func_9 (1);
  return 0;
}
int16_t
func_9 (int64_t p_10) {
  if (p_10) {
    a_4.load ();
    a_4.load ();
    g_83 = g_69;
  }
  return 0;
}
int
main (int, char *[]) {
  func_1 ();
}

The reference trace for main is:

      a_4   0  8       ALoad
      a_4   0  8       ALoad
      a_4   0  8       ALoad
RaW*  g_69  0  2       Load
WaW*  g_83  0  2       Store
The trace generated by gcc --param allow-store-data-races=0 -O3 is:
      a_4   0  8       ALoad
      g_69  0  2       Load
      a_4   0  8       ALoad
      a_4   0  8       ALoad
      g_83  0  2       Store
This reordering cannot be observed by a context. However a gcc invariant is never reorder with an atomic access.

Current status: reported.


back