Компиляторы стремятся размещать переменные в регистрах, избегая "дорогостоящих" операций обращения к памяти, однако, компилятор никогда не может быть уверен, адресуют ли две переменных различные области памяти или обращаются к одной и той же ячейке памяти.
Вот, например:
f(int *a, int *b)
{
int x;
x = *a + *b; // сложение содержимого двух ячеек
*b = 0x69; // изменение ячейки *b, адрес которой не известен компилятору
x += *a; // нет гарантии что запись в ячейку *b
не изменила ячейку *a
}