forked from OSchip/llvm-project
[DAG] Move OR(AND(X,C1),AND(OR(X,Y),C2)) -> OR(AND(X,OR(C1,C2)),AND(Y,C2)) fold to SimplifyDemandedBits
This will fix the SystemZ v3i31 memcpy regression in D77804 (with the help of D129765 as well....). It should also allow us to /bend/ the oneuse limitation for cases where we can use demanded bits to safely peek though multiple uses of the AND ops.
This commit is contained in:
parent
559f07b872
commit
5f89d2bae9
|
@ -6888,27 +6888,6 @@ static SDValue visitORCommutative(SelectionDAG &DAG, SDValue N0, SDValue N1,
|
||||||
if (getBitwiseNotOperand(N00, N01,
|
if (getBitwiseNotOperand(N00, N01,
|
||||||
/* AllowUndefs */ false) == N1)
|
/* AllowUndefs */ false) == N1)
|
||||||
return DAG.getNode(ISD::OR, SDLoc(N), VT, N01, 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))
|
if (SDValue R = foldLogicOfShifts(N, N0, N1, DAG))
|
||||||
|
|
|
@ -1467,6 +1467,33 @@ bool TargetLowering::SimplifyDemandedBits(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (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;
|
Known |= Known2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue