[llvm] Optimized Constant Xor And And Not Operation (PR #161784)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 7 09:58:17 PDT 2025


================
@@ -7463,6 +7498,67 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
   if (SDValue NewSel = foldBinOpIntoSelect(N))
     return NewSel;
 
+  // Optimize (Constant XOR a) & b & ~c -> (Constant XOR a) & (b & ~c)
+  // This allows the andn operation to be done in parallel with the xor
+  if (TLI.hasAndNot(N1) || TLI.hasAndNot(N0)) {
+    // Look for pattern: AND(AND(XOR(Constant, a), b), NOT(c))
+    // Transform to: AND(XOR(Constant, a), AND(b, NOT(c)))
+    
+    // Handle both operand orders: N0=AND, N1=NOT and N0=NOT, N1=AND
+    SDValue AndOp, NotOp;
+    if (N0.getOpcode() == ISD::AND && 
+        N1.getOpcode() == ISD::XOR && 
+        DAG.isConstantIntBuildVectorOrConstantInt(N1.getOperand(1)) &&
+        isAllOnesConstant(N1.getOperand(1))) {
+      AndOp = N0;
+      NotOp = N1;
+    } else if (N1.getOpcode() == ISD::AND &&
+               N0.getOpcode() == ISD::XOR && 
+               DAG.isConstantIntBuildVectorOrConstantInt(N0.getOperand(1)) &&
+               isAllOnesConstant(N0.getOperand(1))) {
+      AndOp = N1;
+      NotOp = N0;
+    } else {
+      // Pattern doesn't match, continue to next optimization
+    }
----------------
RKSimon wrote:

All the commutative matching can be avoided is this is converted to a sd_match pattern:
```
if (sd_match(N, m_And(m_And(), m_Not()))) {
}
```
Same for below.

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


More information about the llvm-commits mailing list