if (getBitwiseNotOperand(N00, N01,
/* AllowUndefs */ false) == N1)
return DAG.getNode(ISD::OR, SDLoc(N), VT, N01, N1);
-
- // (or (and X, C1), (and (or X, Y), C2)) -> (or (and X, C1|C2), (and Y, C2))
- if (N1.getOpcode() == ISD::AND) {
- SDValue N10 = N1.getOperand(0);
- if (N10.getOpcode() == ISD::OR) {
- SDValue N11 = N1.getOperand(1);
- SDValue N100 = N10.getOperand(0);
- SDValue N101 = N10.getOperand(1);
- if (((N00 == N100) || (N00 == N101)) && N0->hasOneUse() &&
- N1->hasOneUse()) {
- SDLoc DL(N);
- if (SDValue C12 =
- DAG.FoldConstantArithmetic(ISD::OR, DL, VT, {N01, N11})) {
- SDValue Y = (N00 == N100 ? N101 : N100);
- return DAG.getNode(ISD::OR, DL, VT,
- DAG.getNode(ISD::AND, DL, VT, N00, C12),
- DAG.getNode(ISD::AND, DL, VT, Y, N11));
- }
- }
- }
- }
}
if (SDValue R = foldLogicOfShifts(N, N0, N1, DAG))
}
}
+ // (or (and X, C1), (and (or X, Y), C2)) -> (or (and X, C1|C2), (and Y, C2))
+ // TODO: Use SimplifyMultipleUseDemandedBits to peek through masks.
+ if (Op0.getOpcode() == ISD::AND && Op1.getOpcode() == ISD::AND &&
+ Op0->hasOneUse() && Op1->hasOneUse()) {
+ // Attempt to match all commutations - m_c_Or would've been useful!
+ for (int I = 0; I != 2; ++I) {
+ SDValue X = Op.getOperand(I).getOperand(0);
+ SDValue C1 = Op.getOperand(I).getOperand(1);
+ SDValue Alt = Op.getOperand(1 - I).getOperand(0);
+ SDValue C2 = Op.getOperand(1 - I).getOperand(1);
+ if (Alt.getOpcode() == ISD::OR) {
+ for (int J = 0; J != 2; ++J) {
+ if (X == Alt.getOperand(J)) {
+ SDValue Y = Alt.getOperand(1 - J);
+ if (SDValue C12 = TLO.DAG.FoldConstantArithmetic(ISD::OR, dl, VT,
+ {C1, C2})) {
+ SDValue MaskX = TLO.DAG.getNode(ISD::AND, dl, VT, X, C12);
+ SDValue MaskY = TLO.DAG.getNode(ISD::AND, dl, VT, Y, C2);
+ return TLO.CombineTo(
+ Op, TLO.DAG.getNode(ISD::OR, dl, VT, MaskX, MaskY));
+ }
+ }
+ }
+ }
+ }
+ }
+
Known |= Known2;
break;
}