Кстати, вот забавный пример UB с алиасингом: вообще, по одному указателю мы не имеем права делать type punning (например, одновременно считать его float* и int*), но если таки сделать это, то в одном случае компилятор может/разрешает сделать reinterpret, а в другом (если разорвать связь через volatile) — нет, и считает предыдущее кэшированное значение неизменившимся.
https://godbolt.org/z/-t6Nbf