Why would that be considered either a feature or a bug? I think it is
neither, just an arbitrary behavior.
Deciding which variables and temporaries should go in which registers is
a very hard problem. Compilers generally don't do it very well
(compared to skilled hand coding). But not doing that well is not a
"bug". At most it is "room for improvement".
As your example demonstrates, the decisions of which variables and
temporaries share registers can end up affecting the number of
instructions needed for the code:
(reg&0xFF) can be computed in one instruction equally well when the
result ends up in the same or different register than previously
contained reg.
(reg >> 8) can be computed in one instruction with the result in the
same register as previously contained reg.
So the choice of which temporary shares a register with the previous
value of reg affects the need for the extra move instruction. But it is
hard for a compiler to bring the right knowledge to the right place to
make this decision in the way that saves the move, vs. letting that
happen or not by accident.
It also appears that in one version the same register was chosen for the
new value of reg as for the old value. I think that is also just an
accident. Depending on flow of control outside what you showed, those
two values of reg are probably not the same variable from the viewpoint
of the compiler.
raok@xxxxxxx wrote:
reg = (reg >> 8) ^ table[reg & 0xFF];
It produced:
mov edx, eax
movzx eax, al
shr dx, 8
xor dx, WORD PTR [ebx+eax*2]
I was wondering why there was that extra mov on the first line. So I
ended up to write it all as:
reg = table[reg & 0xFF] ^ (reg >> 8);
And it produced:
movzx edx, al
shr ax, 8
xor ax, WORD PTR [ebx+edx*2]
I do not know if this is a feature or bug but which ever it is, it would
be nice to know.