Skip to content

Commit

Permalink
[DAG] Move OR(AND(X,C1),AND(OR(X,Y),C2)) -> OR(AND(X,OR(C1,C2)),AND(Y…
Browse files Browse the repository at this point in the history
…,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.
  • Loading branch information
RKSimon committed Jul 23, 2022
1 parent 559f07b commit 5f89d2b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 21 deletions.
21 changes: 0 additions & 21 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Expand Up @@ -6888,27 +6888,6 @@ static SDValue visitORCommutative(SelectionDAG &DAG, SDValue N0, SDValue N1,
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))
Expand Down
27 changes: 27 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Expand Up @@ -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;
break;
}
Expand Down

0 comments on commit 5f89d2b

Please sign in to comment.