[PATCH] D94870: [InstSimplify] Handle commutativity for 'and' and 'outer or' for (~A & B) | ~(A | B) --> ~A

Dávid Bolvanský via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 16 09:32:16 PST 2021


xbolva00 created this revision.
xbolva00 added a reviewer: lebedev.ri.
Herald added a subscriber: hiraditya.
xbolva00 requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

https://reviews.llvm.org/D94870

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


Index: llvm/test/Transforms/InstSimplify/or.ll
===================================================================
--- llvm/test/Transforms/InstSimplify/or.ll
+++ llvm/test/Transforms/InstSimplify/or.ll
@@ -395,3 +395,57 @@
   %i5 = or i32 %i4, %i2
   ret i32 %i5
 }
+
+define i32 @and_or_not_or5(i32 %A, i32 %B) {
+; CHECK-LABEL: @and_or_not_or5(
+; CHECK-NEXT:    [[I:%.*]] = xor i32 [[A:%.*]], -1
+; CHECK-NEXT:    ret i32 [[I]]
+;
+  %i = xor i32 %A, -1
+  %i2 = and i32 %B, %i
+  %i3 = or i32 %B, %A
+  %i4 = xor i32 %i3, -1
+  %i5 = or i32 %i2, %i4
+  ret i32 %i5
+}
+
+define i32 @and_or_not_or6(i32 %A, i32 %B) {
+; CHECK-LABEL: @and_or_not_or6(
+; CHECK-NEXT:    [[I:%.*]] = xor i32 [[A:%.*]], -1
+; CHECK-NEXT:    ret i32 [[I]]
+;
+  %i = xor i32 %A, -1
+  %i2 = and i32 %i, %B
+  %i3 = or i32 %B, %A
+  %i4 = xor i32 %i3, -1
+  %i5 = or i32 %i4, %i2
+  ret i32 %i5
+}
+
+define i32 @and_or_not_or7(i32 %A, i32 %B) {
+; CHECK-LABEL: @and_or_not_or7(
+; CHECK-NEXT:    [[I:%.*]] = xor i32 [[A:%.*]], -1
+; CHECK-NEXT:    ret i32 [[I]]
+;
+  %i = xor i32 %A, -1
+  %i2 = and i32 %B, %i
+  %i3 = or i32 %B, %A
+  %i4 = xor i32 %i3, -1
+  %i5 = or i32 %i4, %i2
+  ret i32 %i5
+}
+
+define i32 @and_or_not_or8(i32 %A, i32 %B) {
+; CHECK-LABEL: @and_or_not_or8(
+; CHECK-NEXT:    [[I:%.*]] = xor i32 [[B:%.*]], -1
+; CHECK-NEXT:    ret i32 [[I]]
+;
+  %i = xor i32 %B, -1
+  %i2 = and i32 %A, %i
+  %i3 = or i32 %B, %A
+  %i4 = xor i32 %i3, -1
+  %i5 = or i32 %i4, %i2
+  ret i32 %i5
+}
+
+
Index: llvm/lib/Analysis/InstructionSimplify.cpp
===================================================================
--- llvm/lib/Analysis/InstructionSimplify.cpp
+++ llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2253,6 +2253,7 @@
        match(Op1, m_c_Xor(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)
   // (B ^ ~A) | (A & B) -> (B ^ ~A)
@@ -2266,9 +2267,22 @@
   // (~A & B) | ~(B | A) --> ~A
   // (B & ~A) | ~(A | B) --> ~A
   // (B & ~A) | ~(B | A) --> ~A
-  if (match(Op0, m_And(m_Not(m_Value(A)), m_Value(B))) &&
+  if (match(Op0, m_c_And(m_Not(m_Value(A)), m_Value(B))) &&
       match(Op1, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
-    return cast<BinaryOperator>(Op0)->getOperand(0);
+    return cast<BinaryOperator>(Op0)->getOperand(0) == B
+               ? cast<BinaryOperator>(Op0)->getOperand(1)
+               : cast<BinaryOperator>(Op0)->getOperand(0);
+
+  // Commute the 'or' operands.
+  // ~(A | B) | (~A & B) --> ~A
+  // ~(B | A) | (~A & B) --> ~A
+  // ~(A | B) | (B & ~A) --> ~A
+  // ~(B | A) | (B & ~A) --> ~A
+  if (match(Op1, m_c_And(m_Not(m_Value(A)), m_Value(B))) &&
+      match(Op0, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
+    return cast<BinaryOperator>(Op1)->getOperand(0) == B
+               ? cast<BinaryOperator>(Op1)->getOperand(1)
+               : cast<BinaryOperator>(Op1)->getOperand(0);
 
   if (Value *V = simplifyAndOrOfCmps(Q, Op0, Op1, false))
     return V;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D94870.317185.patch
Type: text/x-patch
Size: 3038 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210116/87a10827/attachment.bin>


More information about the llvm-commits mailing list