[x86] Bug fix where JccMovJmpMov2CMovCMov made incorrect micro-optimisations (fixes #40122)
Summary
This merge request fixes a bug with the JccMovJmpMov2CMovCMov
optimisation where it tried to move MOV
instructions to before the CMP
instruction in order to improve optimisation and macrofusion. However, this caused problems if this caused 2 or more MOV
instructions to change order and one was dependent on the other (e.g. dereferencing a pointer whose value is then itself dereferenced).
System
- Processor architecture: i386, x86_64
What is the current bug behavior?
in some situations, like that described in #40122 (closed), CMOV optimisations write to an undefined location (usually a pointer that was used immediately prior).
What is the behavior after applying this patch?
CMOV optimisations should now be correct
Additional notes
- CMOV optimisations no longer change the order of
MOV
instructions. - The bug is difficult to reproduce consistently because the CMOV optimisation is not always made with memory operands and is only done under a very particular set of circumstances. The new test attempts to reproduce the problem consistently, but this isn't guaranteed due to values being copied to the stack.
- Some inefficiencies were created when fixing this bug, notably where
MOV
instructions appear afterCMP
instructions where the previous faulty optimisation would try to fix that (hence why theMOV
instructions were moved in the first place). To compensate,PostPeepholeOptCmp
andPostPeepholeOptTestOr
will now try to perform this task. This is not ideal though because it's not something that should be done in the post-peephole stage, and there's some slightly hacky code to look backwards to ensurePostPeepholeOptMov
is called on any translocatedMOV
instructions. A better solution would be to run Pass 2 multiple times (this is something I am also developing).
Edited by J. Gareth "Kit" Moreton