fetch_add with acq_rel memory order

Is it possible for 2 distinct threads to receive the same x_old value of 0?

It is not possible because the operation is atomic. It either happens in full, or not happen at all.

Ordering is concerned with preceding/following loads/stores and since you do not have any, ordering is irrelevant here. In other words, x.fetch_add(1, std::memory_order_relaxed); has the same effect here.

On current x86 is it the same lock xadd instruction regardless of memory_order, lock prefix provides both atomicity and ordering. For memory_order_relaxed the ordering part of lock is unnecessary.