[PATCH] D32474: [InstCombine] Add missing commute handling to (A | B) & (B ^ (~A)) -> (A & B)

Craig Topper via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 24 23:43:56 PDT 2017


craig.topper created this revision.

The matching here wasn't able to handle all the possible commutes. It always assumed the not would be on the left of the xor, but that's not guaranteed.


https://reviews.llvm.org/D32474

Files:
  lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
  test/Transforms/InstCombine/and.ll


Index: test/Transforms/InstCombine/and.ll
===================================================================
--- test/Transforms/InstCombine/and.ll
+++ test/Transforms/InstCombine/and.ll
@@ -617,10 +617,7 @@
 define i32 @test42(i32 %a, i32 %c, i32 %d) {
 ; CHECK-LABEL: @test42(
 ; CHECK-NEXT:    [[FORCE:%.*]] = mul i32 [[C:%.*]], [[D:%.*]]
-; CHECK-NEXT:    [[OR:%.*]] = or i32 [[FORCE]], [[A:%.*]]
-; CHECK-NEXT:    [[NOTA:%.*]] = xor i32 [[A]], -1
-; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[FORCE]], [[NOTA]]
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[XOR]], [[OR]]
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[FORCE]], [[A:%.*]]
 ; CHECK-NEXT:    ret i32 [[AND]]
 ;
   %force = mul i32 %c, %d ; forces the complexity sorting
@@ -634,10 +631,7 @@
 define i32 @test43(i32 %a, i32 %c, i32 %d) {
 ; CHECK-LABEL: @test43(
 ; CHECK-NEXT:    [[FORCE:%.*]] = mul i32 [[C:%.*]], [[D:%.*]]
-; CHECK-NEXT:    [[OR:%.*]] = or i32 [[FORCE]], [[A:%.*]]
-; CHECK-NEXT:    [[NOTA:%.*]] = xor i32 [[A]], -1
-; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[FORCE]], [[NOTA]]
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[OR]], [[XOR]]
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[FORCE]], [[A:%.*]]
 ; CHECK-NEXT:    ret i32 [[AND]]
 ;
   %force = mul i32 %c, %d ; forces the complexity sorting
Index: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1425,13 +1425,18 @@
           return BinaryOperator::CreateAnd(Op1, Builder->CreateNot(C));
 
     // (A | B) & ((~A) ^ B) -> (A & B)
-    if (match(Op0, m_Or(m_Value(A), m_Value(B))) &&
-        match(Op1, m_Xor(m_Not(m_Specific(A)), m_Specific(B))))
+    // (A | B) & (B ^ (~A)) -> (A & B)
+    // (B | A) & ((~A) ^ B) -> (A & B)
+    // (B | A) & (B ^ (~A)) -> (A & B)
+    if (match(Op1, m_c_Xor(m_Not(m_Value(A)), m_Value(B))) &&
+        match(Op0, m_c_Or(m_Specific(A), m_Specific(B))))
       return BinaryOperator::CreateAnd(A, B);
 
     // ((~A) ^ B) & (A | B) -> (A & B)
     // ((~A) ^ B) & (B | A) -> (A & B)
-    if (match(Op0, m_Xor(m_Not(m_Value(A)), m_Value(B))) &&
+    // (B ^ (~A)) & (A | B) -> (A & B)
+    // (B ^ (~A)) & (B | A) -> (A & B)
+    if (match(Op0, m_c_Xor(m_Not(m_Value(A)), m_Value(B))) &&
         match(Op1, m_c_Or(m_Specific(A), m_Specific(B))))
       return BinaryOperator::CreateAnd(A, B);
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32474.96507.patch
Type: text/x-patch
Size: 2443 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170425/7213eb81/attachment.bin>


More information about the llvm-commits mailing list