[llvm] [InstCombine] Add commuted variants for (A ^ B) & ((B ^ C) ^ A) -> (A ^ B) & C (PR #96673)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 25 11:16:12 PDT 2024


https://github.com/AtariDreams created https://github.com/llvm/llvm-project/pull/96673

Because xor is communative and associative, we can match all variants using m_combineOr.

>From 1c83a0b37e80f8416432016b40d23e3cfb9494a7 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Tue, 25 Jun 2024 13:28:33 -0400
Subject: [PATCH] [InstCombine] Add commuted variants for (A ^ B) & ((B ^ C) ^
 A) -> (A ^ B) & ~C

Because xor is communative and associative, we can match all variants using m_combineOr.
---
 .../Transforms/InstCombine/InstCombineAndOrXor.cpp | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 19a12343748df..df7b60aa906b9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2584,7 +2584,10 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
 
     // (A ^ B) & ((B ^ C) ^ A) -> (A ^ B) & ~C
     if (match(Op0, m_Xor(m_Value(A), m_Value(B))) &&
-        match(Op1, m_Xor(m_Xor(m_Specific(B), m_Value(C)), m_Specific(A)))) {
+        match(Op1, m_CombineOr(m_c_Xor(m_c_Xor(m_Specific(A), m_Value(C)),
+                                       m_Specific(B)),
+                               m_c_Xor(m_c_Xor(m_Specific(B), m_Value(C)),
+                                       m_Specific(A))))) {
       Value *NotC = Op1->hasOneUse()
                         ? Builder.CreateNot(C)
                         : getFreelyInverted(C, C->hasOneUse(), &Builder);
@@ -2593,13 +2596,16 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
     }
 
     // ((A ^ C) ^ B) & (B ^ A) -> (B ^ A) & ~C
-    if (match(Op0, m_Xor(m_Xor(m_Value(A), m_Value(C)), m_Value(B))) &&
-        match(Op1, m_Xor(m_Specific(B), m_Specific(A)))) {
+    if (match(Op1, m_Xor(m_Value(A), m_Value(B))) &&
+        match(Op0, m_CombineOr(m_c_Xor(m_c_Xor(m_Specific(A), m_Value(C)),
+                                       m_Specific(B)),
+                               m_c_Xor(m_c_Xor(m_Specific(B), m_Value(C)),
+                                       m_Specific(A))))) {
       Value *NotC = Op0->hasOneUse()
                         ? Builder.CreateNot(C)
                         : getFreelyInverted(C, C->hasOneUse(), &Builder);
       if (NotC != nullptr)
-        return BinaryOperator::CreateAnd(Op1, Builder.CreateNot(C));
+        return BinaryOperator::CreateAnd(Op1, NotC);
     }
 
     // (A | B) & (~A ^ B) -> A & B



More information about the llvm-commits mailing list