diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index c8bc3675fdbb69..b3dfa5bfecddda 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -8799,6 +8799,24 @@ GenTree* Compiler::fgOptimizeRelationalComparison(GenTreeOp* cmp) fgPushConstantsRight(cmp); + // Canonicalize + // '(A & pow2) == pow2' -> '(A & pow2) != 0' + // '(A & pow2) != pow2' -> '(A & pow2) == 0' + if (cmp->OperIs(GT_EQ, GT_NE) && cmp->gtGetOp1()->OperIs(GT_AND) && cmp->gtGetOp2()->IsIntegralConstUnsignedPow2()) + { + if (GenTree::Compare(cmp->gtGetOp1()->gtGetOp2(), cmp->gtGetOp2())) + { + cmp->SetOper(GenTree::ReverseRelop(cmp->OperGet()), GenTree::PRESERVE_VN); + cmp->gtOp2 = gtNewZeroConNode(cmp->gtGetOp2()->TypeGet()); + fgUpdateConstTreeValueNumber(cmp->gtGetOp2()); + + if (fgGlobalMorph) + { + fgMorphTreeDone(cmp->gtOp2); + } + } + } + GenTree* tree = cmp; if (tree->OperIsCmpCompare() && (tree->gtGetOp1()->OperIs(GT_CAST) || tree->gtGetOp2()->OperIs(GT_CAST)))