[PATCH] D32458: [InstSimplify] Handle (~A & ~B) | (~A ^ B) -> ~A ^ B

Phabricator via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 25 10:14:29 PDT 2017


This revision was automatically updated to reflect the committed changes.
Closed by commit rL301329: [InstSimplify] Handle (~A & ~B) | (~A ^ B) -> ~A ^ B (authored by ctopper).

Changed prior to commit:
  https://reviews.llvm.org/D32458?vs=96575&id=96591#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D32458

Files:
  llvm/trunk/lib/Analysis/InstructionSimplify.cpp
  llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll


Index: llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll
===================================================================
--- llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll
+++ llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll
@@ -521,3 +521,65 @@
   ret i32 %or
 }
 
+; (~A & ~B) | (~A ^ B) -> ~A ^ B
+
+define i32 @test45(i32 %a, i32 %b) {
+; CHECK-LABEL: @test45(
+; CHECK-NEXT:    [[NEGB:%.*]] = xor i32 [[B:%.*]], -1
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]]
+; CHECK-NEXT:    ret i32 [[XOR]]
+;
+  %nega = xor i32 %a, -1
+  %negb = xor i32 %b, -1
+  %and = and i32 %nega, %negb
+  %xor = xor i32 %a, %negb
+  %or = or i32 %and, %xor
+  ret i32 %or
+}
+
+define i32 @test45_commuted_and(i32 %a, i32 %b) {
+; CHECK-LABEL: @test45(
+; CHECK-NEXT:    [[NEGB:%.*]] = xor i32 [[B:%.*]], -1
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]]
+; CHECK-NEXT:    ret i32 [[XOR]]
+;
+  %nega = xor i32 %a, -1
+  %negb = xor i32 %b, -1
+  %and = and i32 %negb, %nega
+  %xor = xor i32 %a, %negb
+  %or = or i32 %and, %xor
+  ret i32 %or
+}
+
+; Commute operands of the 'or'.
+; (~A ^ B) | (~A & ~B) -> ~A ^ B
+
+define i32 @test46(i32 %a, i32 %b) {
+; CHECK-LABEL: @test46(
+; CHECK-NEXT:    [[NEGB:%.*]] = xor i32 [[B:%.*]], -1
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]]
+; CHECK-NEXT:    ret i32 [[XOR]]
+;
+  %nega = xor i32 %a, -1
+  %negb = xor i32 %b, -1
+  %and = and i32 %nega, %negb
+  %xor = xor i32 %a, %negb
+  %or = or i32 %xor, %and
+  ret i32 %or
+}
+
+; (~A & ~B) | (~A ^ B) -> ~A ^ B
+
+define i32 @test46_commuted_and(i32 %a, i32 %b) {
+; CHECK-LABEL: @test45(
+; CHECK-NEXT:    [[NEGB:%.*]] = xor i32 [[B:%.*]], -1
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]]
+; CHECK-NEXT:    ret i32 [[XOR]]
+;
+  %nega = xor i32 %a, -1
+  %negb = xor i32 %b, -1
+  %and = and i32 %negb, %nega
+  %xor = xor i32 %a, %negb
+  %or = or i32 %xor, %and
+  ret i32 %or
+}
Index: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
===================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp
@@ -1886,15 +1886,21 @@
 
   // (A & ~B) | (A ^ B) -> (A ^ B)
   // (~B & A) | (A ^ B) -> (A ^ B)
-  if (match(Op0, m_c_And(m_Value(A), m_Not(m_Value(B)))) &&
-      match(Op1, m_Xor(m_Specific(A), m_Specific(B))))
+  // (A & ~B) | (B ^ A) -> (B ^ A)
+  // (~B & A) | (B ^ A) -> (B ^ A)
+  if (match(Op1, m_Xor(m_Value(A), m_Value(B))) &&
+      (match(Op0, m_c_And(m_Specific(A), m_Not(m_Specific(B)))) ||
+       match(Op0, m_c_And(m_Not(m_Specific(A)), m_Specific(B)))))
     return Op1;
 
   // Commute the 'or' operands.
   // (A ^ B) | (A & ~B) -> (A ^ B)
   // (A ^ B) | (~B & A) -> (A ^ B)
-  if (match(Op1, m_c_And(m_Value(A), m_Not(m_Value(B)))) &&
-      match(Op0, m_Xor(m_Specific(A), m_Specific(B))))
+  // (B ^ A) | (A & ~B) -> (B ^ A)
+  // (B ^ A) | (~B & A) -> (B ^ A)
+  if (match(Op0, m_Xor(m_Value(A), m_Value(B))) &&
+      (match(Op1, m_c_And(m_Specific(A), m_Not(m_Specific(B)))) ||
+       match(Op1, m_c_And(m_Not(m_Specific(A)), m_Specific(B)))))
     return Op0;
 
   if (auto *ICILHS = dyn_cast<ICmpInst>(Op0)) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32458.96591.patch
Type: text/x-patch
Size: 3206 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170425/331601dc/attachment.bin>


More information about the llvm-commits mailing list