There’s no guarantees about whether any non-volatile operation happens or not: if removing it doesn’t change the semantics of a correct program, the compiler is allowed to remove it (of course, in general, it is halting-problem hard to deduce that removing something doesn’t change behaviour, but compilers do deduce some cases). E.g. zeroing memory before freeing it can be removed, because the compiler assumes that that memory won’t be read before being reinitialised: doing so would be undefined behaviour*. Getting a guarantee about this is part of what volatility is, so, if you really need it, for now you’ll have to use the unstable API to truly be sure it won’t be removed.
(* I believe it’s a little more subtle than this, but I also believe this captures the intent.)