[llvm] [InstCombine] Improve handling of `not` and free inversion. (PR #66787)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 18 02:12:28 PST 2023


================
@@ -2503,16 +2503,26 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
       return BinaryOperator::CreateAnd(Op1, B);
 
     // (A ^ B) & ((B ^ C) ^ A) -> (A ^ B) & ~C
-    if (match(Op0, m_Xor(m_Value(A), m_Value(B))))
-      if (match(Op1, m_Xor(m_Xor(m_Specific(B), m_Value(C)), m_Specific(A))))
-        if (Op1->hasOneUse() || isFreeToInvert(C, C->hasOneUse()))
-          return BinaryOperator::CreateAnd(Op0, Builder.CreateNot(C));
+    if (match(Op0, m_Xor(m_Value(A), m_Value(B)))) {
+      if (match(Op1, m_Xor(m_Xor(m_Specific(B), m_Value(C)), m_Specific(A)))) {
+        Value *NotC = Op1->hasOneUse()
+                          ? Builder.CreateNot(C)
+                          : getFreelyInverted(C, C->hasOneUse(), &Builder);
+        if (NotC != nullptr)
+          return BinaryOperator::CreateAnd(Op0, NotC);
+      }
+    }
 
     // ((A ^ C) ^ B) & (B ^ A) -> (B ^ A) & ~C
-    if (match(Op0, m_Xor(m_Xor(m_Value(A), m_Value(C)), m_Value(B))))
-      if (match(Op1, m_Xor(m_Specific(B), m_Specific(A))))
-        if (Op0->hasOneUse() || isFreeToInvert(C, C->hasOneUse()))
+    if (match(Op0, m_Xor(m_Xor(m_Value(A), m_Value(C)), m_Value(B)))) {
+      if (match(Op1, m_Xor(m_Specific(B), m_Specific(A)))) {
----------------
nikic wrote:

nit: Combine with `&&`?

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


More information about the llvm-commits mailing list