From 5b7ea037698477691fdc3425ee5e550a421368dc Mon Sep 17 00:00:00 2001 From: Khushal Modi Date: Thu, 15 Aug 2024 12:11:57 -0700 Subject: [PATCH 1/2] Check for writing sign flag for skipping test condition in compare to zero --- src/coreclr/jit/emitxarch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index e3561bbff3797..e0ebca149e574 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -979,7 +979,7 @@ bool emitter::AreFlagsSetToZeroCmp(regNumber reg, emitAttr opSize, GenCondition // Certain instruction like and, or and xor modifies exactly same flags // as "test" instruction. // They reset OF and CF to 0 and modifies SF, ZF and PF. - if (DoesResetOverflowAndCarryFlags(lastIns)) + if (DoesResetOverflowAndCarryFlags(lastIns) && DoesWriteSignFlag(lastIns)) { return id->idOpSize() == opSize; } From e24d006bf4d555e0cacfa254024b54823b0bef63 Mon Sep 17 00:00:00 2001 From: Khushal Modi Date: Fri, 16 Aug 2024 14:15:46 -0700 Subject: [PATCH 2/2] Only skip test instruction in case Writes_PF, Writes ZF, WritesSF, ResetsCF and ResetsOF are true --- src/coreclr/jit/emitxarch.cpp | 19 ++++++++++++++++++- src/coreclr/jit/emitxarch.h | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index e0ebca149e574..2b98d14183aba 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -355,6 +355,22 @@ bool emitter::DoesWriteZeroFlag(instruction ins) return (flags & Writes_ZF) != 0; } +//------------------------------------------------------------------------ +// DoesWriteParityFlag: check if the instruction write the +// PF flag. +// +// Arguments: +// ins - instruction to test +// +// Return Value: +// true if instruction writes the PF flag, false otherwise. +// +bool emitter::DoesWriteParityFlag(instruction ins) +{ + insFlags flags = CodeGenInterface::instInfo[ins]; + return (flags & Writes_PF) != 0; +} + //------------------------------------------------------------------------ // DoesWriteSignFlag: check if the instruction writes the // SF flag. @@ -979,7 +995,8 @@ bool emitter::AreFlagsSetToZeroCmp(regNumber reg, emitAttr opSize, GenCondition // Certain instruction like and, or and xor modifies exactly same flags // as "test" instruction. // They reset OF and CF to 0 and modifies SF, ZF and PF. - if (DoesResetOverflowAndCarryFlags(lastIns) && DoesWriteSignFlag(lastIns)) + if (DoesResetOverflowAndCarryFlags(lastIns) && DoesWriteSignFlag(lastIns) && DoesWriteZeroFlag(lastIns) && + DoesWriteParityFlag(lastIns)) { return id->idOpSize() == opSize; } diff --git a/src/coreclr/jit/emitxarch.h b/src/coreclr/jit/emitxarch.h index d24a697d93c72..7ff6902613d59 100644 --- a/src/coreclr/jit/emitxarch.h +++ b/src/coreclr/jit/emitxarch.h @@ -484,6 +484,7 @@ bool IsThreeOperandAVXInstruction(instruction ins) const; static bool HasRegularWideForm(instruction ins); static bool HasRegularWideImmediateForm(instruction ins); static bool DoesWriteZeroFlag(instruction ins); +static bool DoesWriteParityFlag(instruction ins); static bool DoesWriteSignFlag(instruction ins); static bool DoesResetOverflowAndCarryFlags(instruction ins); bool IsFlagsAlwaysModified(instrDesc* id);