[llvm] [DAG] Convert foldMaskedMerge to SDPatternMatch to match (m & x) | (~m & y) (PR #143855)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 12 02:45:57 PDT 2025


================
@@ -8155,29 +8137,23 @@ static SDValue foldMaskedMerge(SDNode *Node, SelectionDAG &DAG,
   // Note that masked-merge variants using XOR or ADD expressions are
   // normalized to OR by InstCombine so we only check for OR.
   assert(Node->getOpcode() == ISD::OR && "Must be called with ISD::OR node");
-  SDValue N0 = Node->getOperand(0);
-  if (N0->getOpcode() != ISD::AND || !N0->hasOneUse())
-    return SDValue();
-  SDValue N1 = Node->getOperand(1);
-  if (N1->getOpcode() != ISD::AND || !N1->hasOneUse())
-    return SDValue();
 
   // If the target supports and-not, don't fold this.
   if (TLI.hasAndNot(SDValue(Node, 0)))
     return SDValue();
 
-  SDValue N00 = N0->getOperand(0);
-  SDValue N01 = N0->getOperand(1);
-  SDValue N10 = N1->getOperand(0);
-  SDValue N11 = N1->getOperand(1);
-  if (SDValue Result = foldMaskedMergeImpl(N00, N01, N10, N11, DL, DAG))
-    return Result;
-  if (SDValue Result = foldMaskedMergeImpl(N01, N00, N10, N11, DL, DAG))
-    return Result;
-  if (SDValue Result = foldMaskedMergeImpl(N10, N11, N00, N01, DL, DAG))
-    return Result;
-  if (SDValue Result = foldMaskedMergeImpl(N11, N10, N00, N01, DL, DAG))
-    return Result;
+  SDValue M, X, Y;
+  if (sd_match(Node, m_Or(m_OneUse(m_And(m_Value(M), m_Value(X))),
+                          m_OneUse(m_And(m_OneUse(m_Not(m_Deferred(M))),
+                                         m_Value(Y))))) ||
+      sd_match(Node,
+               m_Or(m_OneUse(m_And(m_OneUse(m_Not(m_Value(M))), m_Value(Y))),
+                    m_OneUse(m_And(m_Deferred(M), m_Value(X)))))) {
----------------
woruyu wrote:

I'm also confused! for this case:
```
define i8 @masked_merge2(i8 %a0, i8 %a1, i8 %a2) {
; CHECK-LABEL: masked_merge2:
; CHECK:       # %bb.0:
; CHECK-NEXT:    movl %esi, %eax
; CHECK-NEXT:    # kill: def $al killed $al killed $eax
; CHECK-NEXT:    retq
  %not = xor i8 %a0, -1
  %and0 = and i8 %not, %a1
  %and1 = and i8 %a1, %a0
  %or = or i8 %and0, %and1
  ret i8 %or
}
```
the first is false, the second is true.

https://github.com/llvm/llvm-project/pull/143855


More information about the llvm-commits mailing list