[Patch] x86 CMP/TEST/Jcc optimisations
Original Reporter info from Mantis: CuriousKit @CuriousKit
-
Reporter name: J. Gareth Moreton
Original Reporter info from Mantis: CuriousKit @CuriousKit
- Reporter name: J. Gareth Moreton
Description:
This patch evaluates "cmp $0,%reg" instructions in the knowledge that they'll be converted to "test %reg,%reg" instructions, and optimises the jump conditions that follow, since only ZF and SF contain any meaningful information at this point. Notably:
JAE, JNC, JNO -> JMP (always True)
JB, JC, JO -> Remove (always False)
JNA -> JE
(and similar for JBE and their complements - JE, JNE, JL, JLE, JG and JGE are not touched)
Similarly, SET instructions are also updated (for the 'always True' or 'always False' situations, they are converted to MOV instructions)
Additionally, cmp $1,r/m; jle @lbl -> cmp $0,r/m; jl @lbl, since these comparisons are equivalent and usually permits the CMP instruction to become a TEST instruction.
Steps to reproduce:
Apply patch and confirm correct compilation and no test regressions.
Additional information:
Though instructions like JNA are converted to JE, for example, it hasn't yet been observed to improve the jump chain shortcutting process. However, when removing jumps that never branch, it has been observed to produce new dead labels and thus shrink the code size, increase speed and permit new optimisations.
As a final note, a minor simplification was done for the "CmpJe2NegJo" optimisation. As in-code comments have noted, this optimisation will not happen with 64-bit operands because CMP cannot support the constant $8000000000000000, so if the operand size is S_Q, it immediately exits the subroutine to save time. (It also converts SETE to SETO now if such a statement follows instead of JE).
Mantis conversion info:
- Mantis ID: 36624
- OS: Microsoft Windows
- OS Build: 10 Professional
- Build: r44021
- Platform: i386 and x86_64
- Version: 3.3.1
- Fixed in version: 3.3.1
- Fixed in revision: 44029 (#a807e185)