From 5f89d2bae964e21d8b7e9226c594d15d1c2e8325 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Sat, 23 Jul 2022 13:11:07 +0100 Subject: [PATCH] [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. --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 21 --------------- .../CodeGen/SelectionDAG/TargetLowering.cpp | 27 +++++++++++++++++++ 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index ebc145b9b59c4..edb0756e8c3b5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -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)) diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 31ea506d306b1..8f71b9f49ad47 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -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; }