Isn't it normal for compilers to just no-op functions that can be proved to have no side effects and no return values?
Yes, which is why the volatile qualifier exists: It makes modifying specific variables a side-effect, which then cannot be optimized away.
Yes, modifying is a form of access, but too is a read. Which means one can READ hardware register in a loop and expect it to change without compiler optimizing that out.