@@ -7206,6 +7206,32 @@ static SDValue foldLogicTreeOfShifts(SDNode *N, SDValue LeftHand,
72067206 return DAG.getNode(LogicOpcode, DL, VT, CombinedShifts, W);
72077207}
72087208
7209+ /// Fold "masked merge" expressions like `(m & x) | (~m & y)` into the
7210+ /// equivalent `((x ^ y) & m) ^ y)` pattern.
7211+ /// This is typically a better representation for targets without a fused
7212+ /// "and-not" operation.
7213+ static SDValue foldMaskedMerge(SDNode *Node, SelectionDAG &DAG,
7214+ const TargetLowering &TLI, const SDLoc &DL) {
7215+ // Note that masked-merge variants using XOR or ADD expressions are
7216+ // normalized to OR by InstCombine so we only check for OR.
7217+ assert(Node->getOpcode() == ISD::OR && "Must be called with ISD::OR node");
7218+
7219+ // If the target supports and-not, don't fold this.
7220+ if (TLI.hasAndNot(SDValue(Node, 0)))
7221+ return SDValue();
7222+
7223+ SDValue M, X, Y;
7224+ if (sd_match(Node,
7225+ m_Or(m_OneUse(m_And(m_OneUse(m_Not(m_Value(M))), m_Value(Y))),
7226+ m_OneUse(m_And(m_Deferred(M), m_Value(X)))))) {
7227+ EVT VT = M.getValueType();
7228+ SDValue Xor = DAG.getNode(ISD::XOR, DL, VT, X, Y);
7229+ SDValue And = DAG.getNode(ISD::AND, DL, VT, Xor, M);
7230+ return DAG.getNode(ISD::XOR, DL, VT, And, Y);
7231+ }
7232+ return SDValue();
7233+ }
7234+
72097235SDValue DAGCombiner::visitAND(SDNode *N) {
72107236 SDValue N0 = N->getOperand(0);
72117237 SDValue N1 = N->getOperand(1);
@@ -8136,32 +8162,6 @@ static SDValue visitORCommutative(SelectionDAG &DAG, SDValue N0, SDValue N1,
81368162 return SDValue();
81378163}
81388164
8139- /// Fold "masked merge" expressions like `(m & x) | (~m & y)` into the
8140- /// equivalent `((x ^ y) & m) ^ y)` pattern.
8141- /// This is typically a better representation for targets without a fused
8142- /// "and-not" operation.
8143- static SDValue foldMaskedMerge(SDNode *Node, SelectionDAG &DAG,
8144- const TargetLowering &TLI, const SDLoc &DL) {
8145- // Note that masked-merge variants using XOR or ADD expressions are
8146- // normalized to OR by InstCombine so we only check for OR.
8147- assert(Node->getOpcode() == ISD::OR && "Must be called with ISD::OR node");
8148-
8149- // If the target supports and-not, don't fold this.
8150- if (TLI.hasAndNot(SDValue(Node, 0)))
8151- return SDValue();
8152-
8153- SDValue M, X, Y;
8154- if (sd_match(Node,
8155- m_Or(m_OneUse(m_And(m_OneUse(m_Not(m_Value(M))), m_Value(Y))),
8156- m_OneUse(m_And(m_Deferred(M), m_Value(X)))))) {
8157- EVT VT = M.getValueType();
8158- SDValue Xor = DAG.getNode(ISD::XOR, DL, VT, X, Y);
8159- SDValue And = DAG.getNode(ISD::AND, DL, VT, Xor, M);
8160- return DAG.getNode(ISD::XOR, DL, VT, And, Y);
8161- }
8162- return SDValue();
8163- }
8164-
81658165SDValue DAGCombiner::visitOR(SDNode *N) {
81668166 SDValue N0 = N->getOperand(0);
81678167 SDValue N1 = N->getOperand(1);
0 commit comments