From ae941b566988bd98411d0267b253e58a5ef883f7 Mon Sep 17 00:00:00 2001 From: Sychev Vadim Date: Mon, 21 Mar 2022 22:13:05 +0300 Subject: [PATCH] Add optimization "X & 1 == 1" to "X & 1" (#61412) (#62818) * Add optimization "X & 1 == 1" to "X & 1" (#61412) * Moved the optimization to the morph phase (#61412) * Done in post-order (#61412) * Moved the optimization into fgOptimizeEqualityComparisonWithConst (#61412) * Some corrections due the comments (#61412) * Fix of the picture (#61412) * Add optNarrowTree use (#61412) * Change narrowing to the type check (#61412) * Fix regressions (#61412) * Moved the optimization to the lowering phase (#61412) * Reverted Morph changes (#61412) * Moved the optimization into OptimizeConstCompare method (#61412) * Add GT_EQ check(#61412) --- src/coreclr/jit/lower.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index e03d50e8d2f..bd7c0b7b5e0 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -2925,6 +2925,25 @@ GenTree* Lowering::OptimizeConstCompare(GenTree* cmp) if (op2Value != 0) { + // Optimizes (X & 1) == 1 to (X & 1) + // The compiler requires jumps to have relop operands, so we do not fold that case. + LIR::Use cmpUse; + if ((op2Value == 1) && cmp->OperIs(GT_EQ)) + { + if (andOp2->IsIntegralConst(1) && (genActualType(op1) == cmp->TypeGet()) && + BlockRange().TryGetUse(cmp, &cmpUse) && !cmpUse.User()->OperIs(GT_JTRUE)) + { + GenTree* next = cmp->gtNext; + + cmpUse.ReplaceWith(op1); + + BlockRange().Remove(cmp->gtGetOp2()); + BlockRange().Remove(cmp); + + return next; + } + } + // // If we don't have a 0 compare we can get one by transforming ((x AND mask) EQ|NE mask) // into ((x AND mask) NE|EQ 0) when mask is a single bit. -- GitLab