@@ -24074,6 +24074,55 @@ static bool isTruncWithZeroHighBitsInput(SDValue V, SelectionDAG &DAG) {
2407424074 return DAG.MaskedValueIsZero(VOp0, APInt::getHighBitsSet(InBits,InBits-Bits));
2407524075}
2407624076
24077+ // Lower various (select (icmp CmpVal, 0), LHS, RHS) custom patterns.
24078+ static SDValue LowerSELECTWithCmpZero(SDValue CmpVal, SDValue LHS, SDValue RHS,
24079+ unsigned X86CC, const SDLoc &DL,
24080+ SelectionDAG &DAG,
24081+ const X86Subtarget &Subtarget) {
24082+ EVT CmpVT = CmpVal.getValueType();
24083+ EVT VT = LHS.getValueType();
24084+ if (!CmpVT.isScalarInteger() || !VT.isScalarInteger())
24085+ return SDValue();
24086+
24087+ if (!Subtarget.canUseCMOV() && X86CC == X86::COND_E &&
24088+ CmpVal.getOpcode() == ISD::AND && isOneConstant(CmpVal.getOperand(1))) {
24089+ SDValue Src1, Src2;
24090+ // true if RHS is XOR or OR operator and one of its operands
24091+ // is equal to LHS
24092+ // ( a , a op b) || ( b , a op b)
24093+ auto isOrXorPattern = [&]() {
24094+ if ((RHS.getOpcode() == ISD::XOR || RHS.getOpcode() == ISD::OR) &&
24095+ (RHS.getOperand(0) == LHS || RHS.getOperand(1) == LHS)) {
24096+ Src1 = RHS.getOperand(RHS.getOperand(0) == LHS ? 1 : 0);
24097+ Src2 = LHS;
24098+ return true;
24099+ }
24100+ return false;
24101+ };
24102+
24103+ if (isOrXorPattern()) {
24104+ SDValue Neg;
24105+ unsigned int CmpSz = CmpVT.getSizeInBits();
24106+ // we need mask of all zeros or ones with same size of the other
24107+ // operands.
24108+ if (CmpSz > VT.getSizeInBits())
24109+ Neg = DAG.getNode(ISD::TRUNCATE, DL, VT, CmpVal);
24110+ else if (CmpSz < VT.getSizeInBits())
24111+ Neg = DAG.getNode(
24112+ ISD::AND, DL, VT,
24113+ DAG.getNode(ISD::ANY_EXTEND, DL, VT, CmpVal.getOperand(0)),
24114+ DAG.getConstant(1, DL, VT));
24115+ else
24116+ Neg = CmpVal;
24117+ SDValue Mask = DAG.getNegative(Neg, DL, VT); // -(and (x, 0x1))
24118+ SDValue And = DAG.getNode(ISD::AND, DL, VT, Mask, Src1); // Mask & z
24119+ return DAG.getNode(RHS.getOpcode(), DL, VT, And, Src2); // And Op y
24120+ }
24121+ }
24122+
24123+ return SDValue();
24124+ }
24125+
2407724126SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
2407824127 bool AddTest = true;
2407924128 SDValue Cond = Op.getOperand(0);
@@ -24218,41 +24267,9 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
2421824267 DAG.getTargetConstant(X86::COND_B, DL, MVT::i8),
2421924268 Sub.getValue(1));
2422024269 return DAG.getNode(ISD::OR, DL, VT, SBB, Y);
24221- } else if (!Subtarget.canUseCMOV() && CondCode == X86::COND_E &&
24222- CmpOp0.getOpcode() == ISD::AND &&
24223- isOneConstant(CmpOp0.getOperand(1))) {
24224- SDValue Src1, Src2;
24225- // true if Op2 is XOR or OR operator and one of its operands
24226- // is equal to Op1
24227- // ( a , a op b) || ( b , a op b)
24228- auto isOrXorPattern = [&]() {
24229- if ((Op2.getOpcode() == ISD::XOR || Op2.getOpcode() == ISD::OR) &&
24230- (Op2.getOperand(0) == Op1 || Op2.getOperand(1) == Op1)) {
24231- Src1 =
24232- Op2.getOperand(0) == Op1 ? Op2.getOperand(1) : Op2.getOperand(0);
24233- Src2 = Op1;
24234- return true;
24235- }
24236- return false;
24237- };
24238-
24239- if (isOrXorPattern()) {
24240- SDValue Neg;
24241- unsigned int CmpSz = CmpOp0.getSimpleValueType().getSizeInBits();
24242- // we need mask of all zeros or ones with same size of the other
24243- // operands.
24244- if (CmpSz > VT.getSizeInBits())
24245- Neg = DAG.getNode(ISD::TRUNCATE, DL, VT, CmpOp0);
24246- else if (CmpSz < VT.getSizeInBits())
24247- Neg = DAG.getNode(ISD::AND, DL, VT,
24248- DAG.getNode(ISD::ANY_EXTEND, DL, VT, CmpOp0.getOperand(0)),
24249- DAG.getConstant(1, DL, VT));
24250- else
24251- Neg = CmpOp0;
24252- SDValue Mask = DAG.getNegative(Neg, DL, VT); // -(and (x, 0x1))
24253- SDValue And = DAG.getNode(ISD::AND, DL, VT, Mask, Src1); // Mask & z
24254- return DAG.getNode(Op2.getOpcode(), DL, VT, And, Src2); // And Op y
24255- }
24270+ } else if (SDValue R = LowerSELECTWithCmpZero(CmpOp0, Op1, Op2, CondCode,
24271+ DL, DAG, Subtarget)) {
24272+ return R;
2425624273 } else if ((VT == MVT::i32 || VT == MVT::i64) && isNullConstant(Op2) &&
2425724274 Cmp.getNode()->hasOneUse() && (CmpOp0 == Op1) &&
2425824275 ((CondCode == X86::COND_S) || // smin(x, 0)
0 commit comments