@@ -24074,6 +24074,55 @@ static bool isTruncWithZeroHighBitsInput(SDValue V, SelectionDAG &DAG) {
24074
24074
return DAG.MaskedValueIsZero(VOp0, APInt::getHighBitsSet(InBits,InBits-Bits));
24075
24075
}
24076
24076
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
+
24077
24126
SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
24078
24127
bool AddTest = true;
24079
24128
SDValue Cond = Op.getOperand(0);
@@ -24218,41 +24267,9 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
24218
24267
DAG.getTargetConstant(X86::COND_B, DL, MVT::i8),
24219
24268
Sub.getValue(1));
24220
24269
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;
24256
24273
} else if ((VT == MVT::i32 || VT == MVT::i64) && isNullConstant(Op2) &&
24257
24274
Cmp.getNode()->hasOneUse() && (CmpOp0 == Op1) &&
24258
24275
((CondCode == X86::COND_S) || // smin(x, 0)
0 commit comments