Implement long compare lowering for x86.
authorMike Danes <onemihaid@hotmail.com>
Thu, 8 Sep 2016 11:54:14 +0000 (14:54 +0300)
committerPat Gavlin <pagavlin@microsoft.com>
Wed, 14 Sep 2016 17:33:34 +0000 (10:33 -0700)
commitb0132b388d1b1f89cdcb7ef75ac3c052694e49f1
treeabf8367e66521ad1d165880ec129966d166c0154
parentb6b4d395fbf55366ba2fcf45eb7d0b9693663147
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
src/coreclr/src/jit/codegenlinear.h
src/coreclr/src/jit/codegenxarch.cpp
src/coreclr/src/jit/lower.cpp
src/coreclr/src/jit/lower.h