[llvm] [InstCombine] Reduce the expression `(a^c1)&(a^~c1)` to zero (PR #76637)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sat Dec 30 15:24:30 PST 2023


================
@@ -2553,6 +2553,13 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
     if (match(Op1, m_c_Or(m_Not(m_Value(A)), m_Value(B))) &&
         match(Op0, m_c_Xor(m_Specific(A), m_Specific(B))))
       return BinaryOperator::CreateAnd(Builder.CreateNot(A), B);
+
+    ConstantInt *C1, *C2;
+    // (A ^ C1) & (A ^ C2) -> -1, if and only if C1 is inverted value of C2.
+    if (match(Op0, m_c_Xor(m_Value(A), m_ConstantInt(C1))) &&
+        match(Op1, m_c_Xor(m_Specific(A), m_ConstantInt(C2))) &&
+        C1->getValue() == ~C2->getValue())
+      return replaceInstUsesWith(I, Constant::getNullValue(Op0->getType()));
----------------
dtcxzyw wrote:

```suggestion
    // (A ^ C) & (A ^ ~C) -> 0
    const APInt *C1, *C2;
    if (match(Op0, m_Xor(m_Value(A), m_APInt(C1))) &&
        match(Op1, m_Xor(m_Specific(A), m_APInt(C2))) &&
        (*C1 ^ *C2).isAllOnes())
      return replaceInstUsesWith(I, Constant::getNullValue(Op0->getType()));
```

1. Don't use m_ConstantInt because it only matches scalar integer constants.
2. Use `m_Xor` since we always put constants in RHS for commutable ops.
3. It would be easy to handle `(A ^ C) | (A ^ ~C) -> -1` as well. Alive2: https://alive2.llvm.org/ce/z/mWTvEp
4. Since it always folds the pattern into a constant, you should implement it in `simplifyAndInst`.


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


More information about the llvm-commits mailing list