[llvm] r303004 - [InstSimplify] Add patterns for folding (A & B) | (~A ^ B) -> (~A ^ B) and its commuted variants.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Sun May 14 00:54:43 PDT 2017


Author: ctopper
Date: Sun May 14 02:54:43 2017
New Revision: 303004

URL: http://llvm.org/viewvc/llvm-project?rev=303004&view=rev
Log:
[InstSimplify] Add patterns for folding (A & B) | (~A ^ B) -> (~A ^ B) and its commuted variants.

We already had (A & ~B) | (A ^ B), but we missed the cases where the not was part of the xor.

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

Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=303004&r1=303003&r2=303004&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Sun May 14 02:54:43 2017
@@ -1870,6 +1870,24 @@ static Value *SimplifyOrInst(Value *Op0,
        match(Op1, m_c_And(m_Not(m_Specific(A)), m_Specific(B)))))
     return Op0;
 
+  // (A & B) | (~A ^ B) -> (~A ^ B)
+  // (B & A) | (~A ^ B) -> (~A ^ B)
+  // (A & B) | (B ^ ~A) -> (B ^ ~A)
+  // (B & A) | (B ^ ~A) -> (B ^ ~A)
+  if (match(Op0, m_And(m_Value(A), m_Value(B))) &&
+      (match(Op1, m_c_Xor(m_Specific(A), m_Not(m_Specific(B)))) ||
+       match(Op1, m_c_Xor(m_Not(m_Specific(A)), m_Specific(B)))))
+    return Op1;
+
+  // (~A ^ B) | (A & B) -> (~A ^ B)
+  // (~A ^ B) | (B & A) -> (~A ^ B)
+  // (B ^ ~A) | (A & B) -> (B ^ ~A)
+  // (B ^ ~A) | (B & A) -> (B ^ ~A)
+  if (match(Op1, m_And(m_Value(A), m_Value(B))) &&
+      (match(Op0, m_c_Xor(m_Specific(A), m_Not(m_Specific(B)))) ||
+       match(Op0, m_c_Xor(m_Not(m_Specific(A)), m_Specific(B)))))
+    return Op0;
+
   if (Value *V = simplifyAndOrOfICmps(Op0, Op1, false))
     return V;
 

Modified: llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll?rev=303004&r1=303003&r2=303004&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/AndOrXor.ll Sun May 14 02:54:43 2017
@@ -634,10 +634,8 @@ define i32 @test46_commuted_and(i32 %a,
 define i32 @test47(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test47(
 ; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A]], [[B:%.*]]
-; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[NEGA]], [[B]]
-; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR]], [[AND]]
-; CHECK-NEXT:    ret i32 [[OR]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]]
+; CHECK-NEXT:    ret i32 [[XOR]]
 ;
   %nega = xor i32 %a, -1
   %and = and i32 %a, %b
@@ -649,10 +647,8 @@ define i32 @test47(i32 %a, i32 %b) {
 define i32 @test48(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test48(
 ; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A]], [[B:%.*]]
-; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B]], [[NEGA]]
-; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR]], [[AND]]
-; CHECK-NEXT:    ret i32 [[OR]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]]
+; CHECK-NEXT:    ret i32 [[XOR]]
 ;
   %nega = xor i32 %a, -1
   %and = and i32 %a, %b
@@ -664,10 +660,8 @@ define i32 @test48(i32 %a, i32 %b) {
 define i32 @test49(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test49(
 ; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B:%.*]], [[A]]
-; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B]], [[NEGA]]
-; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR]], [[AND]]
-; CHECK-NEXT:    ret i32 [[OR]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]]
+; CHECK-NEXT:    ret i32 [[XOR]]
 ;
   %nega = xor i32 %a, -1
   %and = and i32 %b, %a
@@ -679,10 +673,8 @@ define i32 @test49(i32 %a, i32 %b) {
 define i32 @test50(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test50(
 ; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B:%.*]], [[A]]
-; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[NEGA]], [[B]]
-; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR]], [[AND]]
-; CHECK-NEXT:    ret i32 [[OR]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]]
+; CHECK-NEXT:    ret i32 [[XOR]]
 ;
   %nega = xor i32 %a, -1
   %and = and i32 %b, %a
@@ -694,10 +686,8 @@ define i32 @test50(i32 %a, i32 %b) {
 define i32 @test51(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test51(
 ; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A]], [[B:%.*]]
-; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[NEGA]], [[B]]
-; CHECK-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[XOR]]
-; CHECK-NEXT:    ret i32 [[OR]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]]
+; CHECK-NEXT:    ret i32 [[XOR]]
 ;
   %nega = xor i32 %a, -1
   %and = and i32 %a, %b
@@ -709,10 +699,8 @@ define i32 @test51(i32 %a, i32 %b) {
 define i32 @test52(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test52(
 ; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A]], [[B:%.*]]
-; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B]], [[NEGA]]
-; CHECK-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[XOR]]
-; CHECK-NEXT:    ret i32 [[OR]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]]
+; CHECK-NEXT:    ret i32 [[XOR]]
 ;
   %nega = xor i32 %a, -1
   %and = and i32 %a, %b
@@ -724,10 +712,8 @@ define i32 @test52(i32 %a, i32 %b) {
 define i32 @test53(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test53(
 ; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B:%.*]], [[A]]
-; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B]], [[NEGA]]
-; CHECK-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[XOR]]
-; CHECK-NEXT:    ret i32 [[OR]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]]
+; CHECK-NEXT:    ret i32 [[XOR]]
 ;
   %nega = xor i32 %a, -1
   %and = and i32 %b, %a
@@ -739,10 +725,8 @@ define i32 @test53(i32 %a, i32 %b) {
 define i32 @test54(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test54(
 ; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B:%.*]], [[A]]
-; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[NEGA]], [[B]]
-; CHECK-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[XOR]]
-; CHECK-NEXT:    ret i32 [[OR]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]]
+; CHECK-NEXT:    ret i32 [[XOR]]
 ;
   %nega = xor i32 %a, -1
   %and = and i32 %b, %a




More information about the llvm-commits mailing list