> From a standards perspective, volatile accesses are more like a full fence - because the compiler can't move any volatile load/store instruction before/after another.

Nope. That's not true. Volatile accesses can't be reordered only relative to other volatile accesses. They do not affect ordering of plain non-volatile accesses in any way.
So if a program contains non-volatile accesses (which is usually a case), then volatiles do not act as fences.