By the way in general it is not right to think of variables as being allocated anywhere, neither in memory nor in registers. Variable are not the "thing" that is allocated, and any given variable may end being in zero or more places at the same time, if you insist on looking at it like that. It's not a completely useless mental model, which is probably why it persists, but that's as a [lie-to-children](https://en.wikipedia.org/wiki/Lie-to-children). If a variable is assigned to various times (in the static sense: not so much several times in a loop, but several times in straight line code), those different "versions" of the variable may well end up in different places. SSA considers those different "versions" of the variable to be different variables altogether. Furthermore, even one "version" of a variable can be split into multiple live ranges - that's not just theoretical, there can be multiple good reasons to split it and allocated the pieces to different places. For example, there are often restrictions on which set of register can be used for some instructions, such as on x64 divisions and "legacy" shift-by-variable instructions. For example, if we consider this code with a division and shift-by-variable:
int test(int x, int y)
{
x = x / y;
return y << x;
}
[MSVC compiles it like this, for x64](https://godbolt.org/z/T8dGWMzhc) (why doesn't this link linkify?)
0 x$ = 8
1 y$ = 16
2 int test(int,int) PROC ; test
3 mov r8d, edx
4 mov eax, ecx
5 cdq
6 idiv r8d
7 mov ecx, eax
8 shl r8d, cl
9 mov eax, r8d
10 ret 0
11 int test(int,int) ENDP ; test
On lines 0 and 1 MSVC helpfully defined stack offsets for x and y, which aren't used, they never end up being on the stack. `x` is passed in via `ecx`, and `y` via `edx`. `x` begins in `ecx`, then is copied to `eax` (line 4) because `idiv` takes the dividend in `edx:eax`, the division leaves it in `eax` (only because the code happens to assign the result of `x / y` back to `x` - to be clear, the output would be in `eax` either way, but `eax` could have represented some other variable otherwise), the original un-divided value of `x` is still in `ecx` at this point (after the division on line 6 but before the mov on line 7) but we need the new value to be in `ecx`, because `shl` needs the shift count to be in `cl` which is the