From 47ac9edd7ab7929f529c01484474a74a4a76d5c0 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Fri, 6 Sep 2024 11:00:47 -0400 Subject: [PATCH] RedundantFlagCalculationElimination: select testz this saves uops. Signed-off-by: Alyssa Rosenzweig --- .../RedundantFlagCalculationElimination.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/FEXCore/Source/Interface/IR/Passes/RedundantFlagCalculationElimination.cpp b/FEXCore/Source/Interface/IR/Passes/RedundantFlagCalculationElimination.cpp index a4b9e455b..f0b7a7d6b 100644 --- a/FEXCore/Source/Interface/IR/Passes/RedundantFlagCalculationElimination.cpp +++ b/FEXCore/Source/Interface/IR/Passes/RedundantFlagCalculationElimination.cpp @@ -523,14 +523,21 @@ bool DeadFlagCalculationEliminination::ProcessBlock(IREmitter* IREmit, IRListVie } else if (Info.Replacement) { IROp->Op = Info.Replacement; } - } else { - FlagsRead &= ~Info.Write; - - if (Info.ReplacementNoWrite && CodeNode->GetUses() == 0) { - IROp->Op = Info.ReplacementNoWrite; - } + } else if (Info.ReplacementNoWrite && CodeNode->GetUses() == 0) { + IROp->Op = Info.ReplacementNoWrite; } + // If we don't care about the sign or carry, we can optimize testnz. + // Carry is inverted between testz and testnz so we check that too. Note + // this flag is outside of the if, since the TestNZ might result from + // optimizing AndWithFlags, and we need to converge locally in a single + // iteration. + if (IROp->Op == OP_TESTNZ && IROp->Size < 4 && !(FlagsRead & (FLAG_N | FLAG_C))) { + IROp->Op = OP_TESTZ; + } + + FlagsRead &= ~Info.Write; + // If we eliminated the instruction, we eliminate its read too. This // check is required to ensure the pass converges locally in a single // iteration.