Because that is the way memory consistency works. OpenCL C, and indeed C itself, do not require that an arbitrary write to memory is visible until certain guarantees are met. In the case of C11 and C++11 these are the atomics, although marking a variable as volatile is usually interpreted that way too (with some caveats). What that means is that if you think you are writing to a memory address because the compiler has no requirement to actually make that visible, and because making memory visible to other work items or (worse) other threads is high overhead, it is at liberty to optimize the write away and keep the data in a register until the point at which it must become visible.
The compiler can be quite aggressive in doing this. You could try replacing your reads and writes with atomic operations. You could use an atomic compare and set in a loop:
while(atomic_cmpxchg(&location, 0, 1)!=1){...}
That will force it to be accessing memory each time.
I may be misinterpreting your post, though, given that you talk about barriers and barriers should enforce visibility. Maybe you could show us the code?