@@ -24086,36 +24086,38 @@ static SDValue LowerSELECTWithCmpZero(SDValue CmpVal, SDValue LHS, SDValue RHS,
2408624086
2408724087 if (X86CC == X86::COND_E && CmpVal.getOpcode() == ISD::AND &&
2408824088 isOneConstant(CmpVal.getOperand(1))) {
24089- auto SplatLSB = [&]() {
24089+ auto SplatLSB = [&](EVT SplatVT ) {
2409024090 // we need mask of all zeros or ones with same size of the other
2409124091 // operands.
2409224092 SDValue Neg = CmpVal;
24093- if (CmpVT.bitsGT(VT ))
24094- Neg = DAG.getNode(ISD::TRUNCATE, DL, VT , CmpVal);
24095- else if (CmpVT.bitsLT(VT ))
24093+ if (CmpVT.bitsGT(SplatVT ))
24094+ Neg = DAG.getNode(ISD::TRUNCATE, DL, SplatVT , CmpVal);
24095+ else if (CmpVT.bitsLT(SplatVT ))
2409624096 Neg = DAG.getNode(
24097- ISD::AND, DL, VT ,
24098- DAG.getNode(ISD::ANY_EXTEND, DL, VT , CmpVal.getOperand(0)),
24099- DAG.getConstant(1, DL, VT ));
24100- return DAG.getNegative(Neg, DL, VT ); // -(and (x, 0x1))
24097+ ISD::AND, DL, SplatVT ,
24098+ DAG.getNode(ISD::ANY_EXTEND, DL, SplatVT , CmpVal.getOperand(0)),
24099+ DAG.getConstant(1, DL, SplatVT ));
24100+ return DAG.getNegative(Neg, DL, SplatVT ); // -(and (x, 0x1))
2410124101 };
2410224102
2410324103 // SELECT (AND(X,1) == 0), 0, -1 -> NEG(AND(X,1))
2410424104 if (isNullConstant(LHS) && isAllOnesConstant(RHS))
24105- return SplatLSB();
24105+ return SplatLSB(VT );
2410624106
2410724107 // SELECT (AND(X,1) == 0), C1, C2 -> XOR(C1,AND(NEG(AND(X,1)),XOR(C1,C2))
2410824108 if (!Subtarget.canUseCMOV() && isa<ConstantSDNode>(LHS) &&
2410924109 isa<ConstantSDNode>(RHS)) {
24110- SDValue Mask = SplatLSB();
24110+ SDValue Mask = SplatLSB(VT );
2411124111 SDValue Diff = DAG.getNode(ISD::XOR, DL, VT, LHS, RHS);
2411224112 SDValue Flip = DAG.getNode(ISD::AND, DL, VT, Mask, Diff);
2411324113 return DAG.getNode(ISD::XOR, DL, VT, LHS, Flip);
2411424114 }
2411524115
2411624116 SDValue Src1, Src2;
24117- auto isIdentityPattern = [&]() {
24117+ auto isIdentityPatternZero = [&]() {
2411824118 switch (RHS.getOpcode()) {
24119+ default:
24120+ break;
2411924121 case ISD::OR:
2412024122 case ISD::XOR:
2412124123 case ISD::ADD:
@@ -24125,6 +24127,9 @@ static SDValue LowerSELECTWithCmpZero(SDValue CmpVal, SDValue LHS, SDValue RHS,
2412524127 return true;
2412624128 }
2412724129 break;
24130+ case ISD::SHL:
24131+ case ISD::SRA:
24132+ case ISD::SRL:
2412824133 case ISD::SUB:
2412924134 if (RHS.getOperand(0) == LHS) {
2413024135 Src1 = RHS.getOperand(1);
@@ -24136,15 +24141,40 @@ static SDValue LowerSELECTWithCmpZero(SDValue CmpVal, SDValue LHS, SDValue RHS,
2413624141 return false;
2413724142 };
2413824143
24144+ auto isIdentityPatternOnes = [&]() {
24145+ switch (LHS.getOpcode()) {
24146+ default:
24147+ break;
24148+ case ISD::AND:
24149+ if (LHS.getOperand(0) == RHS || LHS.getOperand(1) == RHS) {
24150+ Src1 = LHS.getOperand(LHS.getOperand(0) == RHS ? 1 : 0);
24151+ Src2 = RHS;
24152+ return true;
24153+ }
24154+ break;
24155+ }
24156+ return false;
24157+ };
24158+
2413924159 // Convert 'identity' patterns (iff X is 0 or 1):
2414024160 // SELECT (AND(X,1) == 0), Y, (OR Y, Z) -> (OR Y, (AND NEG(AND(X,1)), Z))
2414124161 // SELECT (AND(X,1) == 0), Y, (XOR Y, Z) -> (XOR Y, (AND NEG(AND(X,1)), Z))
2414224162 // SELECT (AND(X,1) == 0), Y, (ADD Y, Z) -> (ADD Y, (AND NEG(AND(X,1)), Z))
2414324163 // SELECT (AND(X,1) == 0), Y, (SUB Y, Z) -> (SUB Y, (AND NEG(AND(X,1)), Z))
24144- if (!Subtarget.canUseCMOV() && isIdentityPattern()) {
24145- SDValue Mask = SplatLSB();
24146- SDValue And = DAG.getNode(ISD::AND, DL, VT, Mask, Src1); // Mask & z
24147- return DAG.getNode(RHS.getOpcode(), DL, VT, Src2, And); // y Op And
24164+ // SELECT (AND(X,1) == 0), Y, (SHL Y, Z) -> (SHL Y, (AND NEG(AND(X,1)), Z))
24165+ // SELECT (AND(X,1) == 0), Y, (SRA Y, Z) -> (SRA Y, (AND NEG(AND(X,1)), Z))
24166+ // SELECT (AND(X,1) == 0), Y, (SRL Y, Z) -> (SRL Y, (AND NEG(AND(X,1)), Z))
24167+ if (!Subtarget.canUseCMOV() && isIdentityPatternZero()) {
24168+ SDValue Mask = SplatLSB(Src1.getValueType());
24169+ SDValue And = DAG.getNode(ISD::AND, DL, Src1.getValueType(), Mask,
24170+ Src1); // Mask & z
24171+ return DAG.getNode(RHS.getOpcode(), DL, VT, Src2, And); // y Op And
24172+ }
24173+ // SELECT (AND(X,1) == 0), (AND Y, Z), Y -> (AND Y, (OR NEG(AND(X, 1)), Z))
24174+ if (!Subtarget.canUseCMOV() && isIdentityPatternOnes()) {
24175+ SDValue Mask = SplatLSB(VT);
24176+ SDValue Or = DAG.getNode(ISD::OR, DL, VT, Mask, Src1); // Mask | z
24177+ return DAG.getNode(LHS.getOpcode(), DL, VT, Src2, Or); // y Op Or
2414824178 }
2414924179 }
2415024180
0 commit comments