+ if (unlikely(mod == RaW))
+ return *addr;
+
+ // We do not have acquired the orec, so we need to load a value and then
+ // validate that this was consistent.
+ // This needs to have acquire memory order (see validate()).
+ // Alternatively, we can put an acquire fence after the data load but this
+ // is probably less efficient.
+ // FIXME We would need an atomic load with acquire memory order here but
+ // we can't just forge an atomic load for nonatomic data because this
+ // might not work on all implementations of atomics. However, we need
+ // the acquire memory order and we can only establish this if we link
+ // it to the matching release using a reads-from relation between atomic
+ // loads. Also, the compiler is allowed to optimize nonatomic accesses
+ // differently than atomic accesses (e.g., if the load would be moved to
+ // after the fence, we potentially don't synchronize properly anymore).
+ // Instead of the following, just use an ordinary load followed by an
+ // acquire fence, and hope that this is good enough for now:
+ // V v = atomic_load_explicit((atomic<V>*)addr, memory_order_acquire);