Implement long compare lowering for x86.
Comparisons between long-typed values on x86 require at least two and
at most three separate branches: one or two to compare the high 32
bits and one to compare the low 32 bits. In essence, each long
compare introduces two additional basic blocks into the flow graph,
but these blocks were not reified until code generation. Furthermore,
code generation of a long comparison used by a JTRUE was deferred
until the JTRUE itself without marking the inputs to the compare as
live at the JTRUE. Taken together, these representational issues
caused bugs like the one seen in the the following assembly:
33DB xor ebx, ebx
BE03000000 mov esi, 3
33FF xor edi, edi
8B75F0 mov esi, dword ptr [ebp-10H] ; these 2 are reloads inserted by LSRA
8B7DEC mov edi, dword ptr [ebp-14H] ; between the compare and the branch
3BDF cmp ebx, edi
72D6 jb SHORT G_M51005_IG03
7704 ja SHORT G_M51005_IG04
3BC6 cmp eax, esi
72D0 jb SHORT G_M51005_IG03
The reloads that LSRA has inserted have killed the registers assigned
to the inputs to the compare, thus causing the compare instructions
to read unexpected values (GH dotnet/coreclr#7038).
Although a number of alternatives were discussed, the best solution
seems to be to expose the control flow via the flow graph rather than
leaving it until code generation; this commit implements that approach.
Commit migrated from https://github.com/dotnet/coreclr/commit/
4dc7c44f3e466067b73f7f28c0b69a7878b4ca20