The one rule that compile-time and runtime memory re-ordering follows:
Never modify the behaviour of a single threaded program. - Memory re-ordering algorithms
However, if you are designing a multi-threaded program, you are out of luck. Memory re-ordering can mess with what you expect shared data to equal at any point in time.
Read the great tutorial on memory barriers at http://preshing.com/20120710/memory-barriers-are-like-source-control-operations/.