@@ -24086,36 +24086,38 @@ static SDValue LowerSELECTWithCmpZero(SDValue CmpVal, SDValue LHS, SDValue RHS,
24086
24086
24087
24087
if (X86CC == X86::COND_E && CmpVal.getOpcode() == ISD::AND &&
24088
24088
isOneConstant(CmpVal.getOperand(1))) {
24089
- auto SplatLSB = [&]() {
24089
+ auto SplatLSB = [&](EVT SplatVT ) {
24090
24090
// we need mask of all zeros or ones with same size of the other
24091
24091
// operands.
24092
24092
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 ))
24096
24096
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))
24101
24101
};
24102
24102
24103
24103
// SELECT (AND(X,1) == 0), 0, -1 -> NEG(AND(X,1))
24104
24104
if (isNullConstant(LHS) && isAllOnesConstant(RHS))
24105
- return SplatLSB();
24105
+ return SplatLSB(VT );
24106
24106
24107
24107
// SELECT (AND(X,1) == 0), C1, C2 -> XOR(C1,AND(NEG(AND(X,1)),XOR(C1,C2))
24108
24108
if (!Subtarget.canUseCMOV() && isa<ConstantSDNode>(LHS) &&
24109
24109
isa<ConstantSDNode>(RHS)) {
24110
- SDValue Mask = SplatLSB();
24110
+ SDValue Mask = SplatLSB(VT );
24111
24111
SDValue Diff = DAG.getNode(ISD::XOR, DL, VT, LHS, RHS);
24112
24112
SDValue Flip = DAG.getNode(ISD::AND, DL, VT, Mask, Diff);
24113
24113
return DAG.getNode(ISD::XOR, DL, VT, LHS, Flip);
24114
24114
}
24115
24115
24116
24116
SDValue Src1, Src2;
24117
- auto isIdentityPattern = [&]() {
24117
+ auto isIdentityPatternZero = [&]() {
24118
24118
switch (RHS.getOpcode()) {
24119
+ default:
24120
+ break;
24119
24121
case ISD::OR:
24120
24122
case ISD::XOR:
24121
24123
case ISD::ADD:
@@ -24125,6 +24127,9 @@ static SDValue LowerSELECTWithCmpZero(SDValue CmpVal, SDValue LHS, SDValue RHS,
24125
24127
return true;
24126
24128
}
24127
24129
break;
24130
+ case ISD::SHL:
24131
+ case ISD::SRA:
24132
+ case ISD::SRL:
24128
24133
case ISD::SUB:
24129
24134
if (RHS.getOperand(0) == LHS) {
24130
24135
Src1 = RHS.getOperand(1);
@@ -24136,15 +24141,40 @@ static SDValue LowerSELECTWithCmpZero(SDValue CmpVal, SDValue LHS, SDValue RHS,
24136
24141
return false;
24137
24142
};
24138
24143
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
+
24139
24159
// Convert 'identity' patterns (iff X is 0 or 1):
24140
24160
// SELECT (AND(X,1) == 0), Y, (OR Y, Z) -> (OR Y, (AND NEG(AND(X,1)), Z))
24141
24161
// SELECT (AND(X,1) == 0), Y, (XOR Y, Z) -> (XOR Y, (AND NEG(AND(X,1)), Z))
24142
24162
// SELECT (AND(X,1) == 0), Y, (ADD Y, Z) -> (ADD Y, (AND NEG(AND(X,1)), Z))
24143
24163
// 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
24148
24178
}
24149
24179
}
24150
24180
0 commit comments