Well "volatile" is a memory variable's attribute, not referenced to chips registers. That are always read because are external to the CPU, and then, to the compiler control.
The "volatile" qualifier is used when a variable is accessed from more than one thread of execution, from interrupt routines, and whatever concurrent instruction flow outside of current context.
Immagine reading a memory variable holding ticks count, or concurrent access flags (that on OS level are accessed with specific machine instructions as test and set that take one cycle also locking the bus), in this case the compiler seeing that you read that variable many times can be tempted, for optimization reasons, to read it one time than cache the value. The result is that in all parts of your program you have the same value while the variable is continuosly changing.
This is also the reason for which you can solve an optimization bug problem, qualifying a variable as "volatile" the compiler don't try to 'cache' the value (i.e. in a register triggering the bug) and each time you use it the value is freshly read.