SDValue Op0 = ArithOp->getOperand(0);
SDValue Op1 = ArithOp->getOperand(1);
EVT VT = ArithOp.getValueType();
- bool isAndn = isBitwiseNot(Op0) || isBitwiseNot(Op1);
- bool isLegalAndnType = VT == MVT::i32 || VT == MVT::i64;
- bool isProperAndn = isAndn && isLegalAndnType && Subtarget.hasBMI();
-
- // If we cannot select an ANDN instruction, check if we can replace
- // AND+IMM64 with a shift before giving up. This is possible for masks
- // like 0xFF000000 or 0x00FFFFFF and if we care only about the zero flag.
- if (!isProperAndn) {
- if (!ZeroCheck)
- break;
- // And with cosntant should be canonicalized unless we're dealing
- // with opaque constants.
- assert((!isa<ConstantSDNode>(Op0) ||
- (isa<ConstantSDNode>(Op1) &&
- (cast<ConstantSDNode>(Op0)->isOpaque() ||
- cast<ConstantSDNode>(Op1)->isOpaque()))) &&
- "AND node isn't canonicalized");
- auto *CN = dyn_cast<ConstantSDNode>(Op1);
- if (!CN)
- break;
+ // Check if we can replace AND+IMM64 with a shift before giving up. This
+ // is possible for masks/ like 0xFF000000 or 0x00FFFFFF and if we care
+ // only about the zero flag.
+ if (!ZeroCheck)
+ break;
- const APInt &Mask = CN->getAPIntValue();
- if (Mask.isSignedIntN(ShiftToAndMaxMaskWidth))
- break; // Prefer TEST instruction.
+ // And with constant should be canonicalized unless we're dealing
+ // with opaque constants.
+ assert((!isa<ConstantSDNode>(Op0) ||
+ (isa<ConstantSDNode>(Op1) &&
+ (cast<ConstantSDNode>(Op0)->isOpaque() ||
+ cast<ConstantSDNode>(Op1)->isOpaque()))) &&
+ "AND node isn't canonicalized");
+ auto *CN = dyn_cast<ConstantSDNode>(Op1);
+ if (!CN)
+ break;
- unsigned BitWidth = Mask.getBitWidth();
- unsigned LeadingOnes = Mask.countLeadingOnes();
- unsigned TrailingZeros = Mask.countTrailingZeros();
+ const APInt &Mask = CN->getAPIntValue();
+ if (Mask.isSignedIntN(ShiftToAndMaxMaskWidth))
+ break; // Prefer TEST instruction.
- if (LeadingOnes + TrailingZeros == BitWidth) {
- assert(TrailingZeros < VT.getSizeInBits() &&
- "Shift amount should be less than the type width");
- SDValue ShAmt = DAG.getConstant(TrailingZeros, dl, MVT::i8);
- Op = DAG.getNode(ISD::SRL, dl, VT, Op0, ShAmt);
- break;
- }
+ unsigned BitWidth = Mask.getBitWidth();
+ unsigned LeadingOnes = Mask.countLeadingOnes();
+ unsigned TrailingZeros = Mask.countTrailingZeros();
- unsigned LeadingZeros = Mask.countLeadingZeros();
- unsigned TrailingOnes = Mask.countTrailingOnes();
+ if (LeadingOnes + TrailingZeros == BitWidth) {
+ assert(TrailingZeros < VT.getSizeInBits() &&
+ "Shift amount should be less than the type width");
+ SDValue ShAmt = DAG.getConstant(TrailingZeros, dl, MVT::i8);
+ Op = DAG.getNode(ISD::SRL, dl, VT, Op0, ShAmt);
+ break;
+ }
- if (LeadingZeros + TrailingOnes == BitWidth) {
- assert(LeadingZeros < VT.getSizeInBits() &&
- "Shift amount should be less than the type width");
- SDValue ShAmt = DAG.getConstant(LeadingZeros, dl, MVT::i8);
- Op = DAG.getNode(ISD::SHL, dl, VT, Op0, ShAmt);
- break;
- }
+ unsigned LeadingZeros = Mask.countLeadingZeros();
+ unsigned TrailingOnes = Mask.countTrailingOnes();
+ if (LeadingZeros + TrailingOnes == BitWidth) {
+ assert(LeadingZeros < VT.getSizeInBits() &&
+ "Shift amount should be less than the type width");
+ SDValue ShAmt = DAG.getConstant(LeadingZeros, dl, MVT::i8);
+ Op = DAG.getNode(ISD::SHL, dl, VT, Op0, ShAmt);
break;
}
+
+ break;
}
LLVM_FALLTHROUGH;
case ISD::SUB:
def TEST64rr : BinOpRR_F<0x84, "test", Xi64, null_frag>;
} // isCommutable
- def TEST8mr : BinOpMR_F<0x84, "test", Xi8 , X86testpat>;
- def TEST16mr : BinOpMR_F<0x84, "test", Xi16, X86testpat>;
- def TEST32mr : BinOpMR_F<0x84, "test", Xi32, X86testpat>;
- def TEST64mr : BinOpMR_F<0x84, "test", Xi64, X86testpat>;
+ let hasSideEffects = 0, mayLoad = 1 in {
+ def TEST8mr : BinOpMR_F<0x84, "test", Xi8 , null_frag>;
+ def TEST16mr : BinOpMR_F<0x84, "test", Xi16, null_frag>;
+ def TEST32mr : BinOpMR_F<0x84, "test", Xi32, null_frag>;
+ def TEST64mr : BinOpMR_F<0x84, "test", Xi64, null_frag>;
+ }
def TEST8ri : BinOpRI_F<0xF6, "test", Xi8 , X86testpat, MRM0r>;
def TEST16ri : BinOpRI_F<0xF6, "test", Xi16, X86testpat, MRM0r>;