@@ -139,8 +139,7 @@ GenTree* Lowering::LowerNode(GenTree* node)
139139 case GT_AND:
140140 case GT_OR:
141141 case GT_XOR:
142- ContainCheckBinary (node->AsOp ());
143- break ;
142+ return LowerBinaryArithmeticCommon (node->AsOp ());
144143
145144 case GT_MUL:
146145 case GT_MULHI:
@@ -5098,6 +5097,54 @@ GenTree* Lowering::LowerAdd(GenTreeOp* node)
50985097 return nullptr ;
50995098}
51005099
5100+ // ------------------------------------------------------------------------
5101+ // LowerBinaryArithmeticCommon: lowers the given binary arithmetic node.
5102+ //
5103+ // Recognizes opportunities for using target-independent "combined" nodes
5104+ // (currently AND_NOT on ARMArch). Calls the target-specific "LowerBinaryArithmetic"
5105+ // method, which checks for more nodes and containment.
5106+ //
5107+ // Arguments:
5108+ // node - the arithmetic node to lower
5109+ //
5110+ // Returns:
5111+ // The next node to lower.
5112+ //
5113+ GenTree* Lowering::LowerBinaryArithmeticCommon (GenTreeOp* node)
5114+ {
5115+ // TODO-CQ-XArch: support BMI2 "andn" in codegen and condition
5116+ // this logic on the support for the instruction set on XArch.
5117+ CLANG_FORMAT_COMMENT_ANCHOR;
5118+
5119+ #ifdef TARGET_ARMARCH
5120+ if (comp->opts .OptimizationEnabled () && node->OperIs (GT_AND))
5121+ {
5122+ GenTree* opNode = nullptr ;
5123+ GenTree* notNode = nullptr ;
5124+ if (node->gtGetOp1 ()->OperIs (GT_NOT))
5125+ {
5126+ notNode = node->gtGetOp1 ();
5127+ opNode = node->gtGetOp2 ();
5128+ }
5129+ else if (node->gtGetOp2 ()->OperIs (GT_NOT))
5130+ {
5131+ notNode = node->gtGetOp2 ();
5132+ opNode = node->gtGetOp1 ();
5133+ }
5134+
5135+ if (notNode != nullptr )
5136+ {
5137+ node->gtOp1 = opNode;
5138+ node->gtOp2 = notNode->AsUnOp ()->gtGetOp1 ();
5139+ node->ChangeOper (GT_AND_NOT);
5140+ BlockRange ().Remove (notNode);
5141+ }
5142+ }
5143+ #endif // TARGET_ARMARCH
5144+
5145+ return LowerBinaryArithmetic (node);
5146+ }
5147+
51015148// ------------------------------------------------------------------------
51025149// LowerUnsignedDivOrMod: Lowers a GT_UDIV/GT_UMOD node.
51035150//
0 commit comments