@@ -7206,6 +7206,32 @@ static SDValue foldLogicTreeOfShifts(SDNode *N, SDValue LeftHand,
7206
7206
return DAG.getNode(LogicOpcode, DL, VT, CombinedShifts, W);
7207
7207
}
7208
7208
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
+
7209
7235
SDValue DAGCombiner::visitAND(SDNode *N) {
7210
7236
SDValue N0 = N->getOperand(0);
7211
7237
SDValue N1 = N->getOperand(1);
@@ -8136,32 +8162,6 @@ static SDValue visitORCommutative(SelectionDAG &DAG, SDValue N0, SDValue N1,
8136
8162
return SDValue();
8137
8163
}
8138
8164
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
-
8165
8165
SDValue DAGCombiner::visitOR(SDNode *N) {
8166
8166
SDValue N0 = N->getOperand(0);
8167
8167
SDValue N1 = N->getOperand(1);
0 commit comments