Hyperthreading splits resources (including registers, branch prediction, TLB, etc.) between the threads. This split is static in Sandy Bridge and older and dynamic in Ivy Bridge and newer.
The article is oversimplified here to the point of being incorrect. The registers the compiler sees don't change (and there aren't 160 of them, I think there's a dozen or less), only the behind-the-scenes ones as the parent comment says.
So in a way "Compilers will allocate our local variables and function arguments to these registers" is correct.
For example, the compiler could order a sequence of load -> store copies as 4x load -> 4x store, or 4x (load -> store). They're equally fast on an OoOE CPU, so compilers might choose the latter so as to spill fewer registers elsewhere in the function.
How does that work? I thought each HT had its own registers - otherwise, wouldn't that add a lot of complication and overhead? And does that mean if I disable HT, a program can double the available registers? Wouldn't that need different machine code?