[llvm] r299822 - [InstCombine] Extend some OR combines to support vectors.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 8 23:12:42 PDT 2017


Author: ctopper
Date: Sun Apr  9 01:12:41 2017
New Revision: 299822

URL: http://llvm.org/viewvc/llvm-project?rev=299822&view=rev
Log:
[InstCombine] Extend some OR combines to support vectors.

This adds support for these combines for vectors
(X^C)|Y -> (X|Y)^C iff Y&C == 0
Y|(X^C) -> (X|Y)^C iff Y&C == 0

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/trunk/test/Transforms/InstCombine/and.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=299822&r1=299821&r2=299822&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Sun Apr  9 01:12:41 2017
@@ -2070,26 +2070,29 @@ Instruction *InstCombiner::visitOr(Binar
   if (Instruction *BSwap = MatchBSwap(I))
     return BSwap;
 
-  Value *A = nullptr, *B = nullptr;
-  ConstantInt *C1 = nullptr, *C2 = nullptr;
+  {
+    Value *A;
+    const APInt *C;
+    // (X^C)|Y -> (X|Y)^C iff Y&C == 0
+    if (match(Op0, m_OneUse(m_Xor(m_Value(A), m_APInt(C)))) &&
+        MaskedValueIsZero(Op1, *C, 0, &I)) {
+      Value *NOr = Builder->CreateOr(A, Op1);
+      NOr->takeName(Op0);
+      return BinaryOperator::CreateXor(NOr,
+                                       cast<Instruction>(Op0)->getOperand(1));
+    }
 
-  // (X^C)|Y -> (X|Y)^C iff Y&C == 0
-  if (Op0->hasOneUse() &&
-      match(Op0, m_Xor(m_Value(A), m_ConstantInt(C1))) &&
-      MaskedValueIsZero(Op1, C1->getValue(), 0, &I)) {
-    Value *NOr = Builder->CreateOr(A, Op1);
-    NOr->takeName(Op0);
-    return BinaryOperator::CreateXor(NOr, C1);
+    // Y|(X^C) -> (X|Y)^C iff Y&C == 0
+    if (match(Op1, m_OneUse(m_Xor(m_Value(A), m_APInt(C)))) &&
+        MaskedValueIsZero(Op0, *C, 0, &I)) {
+      Value *NOr = Builder->CreateOr(A, Op0);
+      NOr->takeName(Op0);
+      return BinaryOperator::CreateXor(NOr,
+                                       cast<Instruction>(Op1)->getOperand(1));
+    }
   }
 
-  // Y|(X^C) -> (X|Y)^C iff Y&C == 0
-  if (Op1->hasOneUse() &&
-      match(Op1, m_Xor(m_Value(A), m_ConstantInt(C1))) &&
-      MaskedValueIsZero(Op0, C1->getValue(), 0, &I)) {
-    Value *NOr = Builder->CreateOr(A, Op0);
-    NOr->takeName(Op0);
-    return BinaryOperator::CreateXor(NOr, C1);
-  }
+  Value *A, *B;
 
   // ((~A & B) | A) -> (A | B)
   if (match(Op0, m_c_And(m_Not(m_Specific(Op1)), m_Value(A))))
@@ -2121,8 +2124,8 @@ Instruction *InstCombiner::visitOr(Binar
   if (match(Op0, m_And(m_Value(A), m_Value(C))) &&
       match(Op1, m_And(m_Value(B), m_Value(D)))) {
     Value *V1 = nullptr, *V2 = nullptr;
-    C1 = dyn_cast<ConstantInt>(C);
-    C2 = dyn_cast<ConstantInt>(D);
+    ConstantInt *C1 = dyn_cast<ConstantInt>(C);
+    ConstantInt *C2 = dyn_cast<ConstantInt>(D);
     if (C1 && C2) {  // (A & C1)|(B & C2)
       if ((C1->getValue() & C2->getValue()) == 0) {
         // ((V | N) & C1) | (V & C2) --> (V|N) & (C1|C2)
@@ -2347,6 +2350,7 @@ Instruction *InstCombiner::visitOr(Binar
   // be simplified by a later pass either, so we try swapping the inner/outer
   // ORs in the hopes that we'll be able to simplify it this way.
   // (X|C) | V --> (X|V) | C
+  ConstantInt *C1;
   if (Op0->hasOneUse() && !isa<ConstantInt>(Op1) &&
       match(Op0, m_Or(m_Value(A), m_ConstantInt(C1)))) {
     Value *Inner = Builder->CreateOr(A, Op1);

Modified: llvm/trunk/test/Transforms/InstCombine/and.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/and.ll?rev=299822&r1=299821&r2=299822&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/and.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/and.ll Sun Apr  9 01:12:41 2017
@@ -431,10 +431,7 @@ define i32 @test33b(i32 %b) {
 
 define <2 x i32> @test33vec(<2 x i32> %b) {
 ; CHECK-LABEL: @test33vec(
-; CHECK-NEXT:    [[TMP_4_MASK:%.*]] = and <2 x i32> [[B:%.*]], <i32 1, i32 1>
-; CHECK-NEXT:    [[TMP_10:%.*]] = xor <2 x i32> [[TMP_4_MASK]], <i32 1, i32 1>
-; CHECK-NEXT:    [[TMP_12:%.*]] = and <2 x i32> [[B]], <i32 -2, i32 -2>
-; CHECK-NEXT:    [[TMP_13:%.*]] = or <2 x i32> [[TMP_12]], [[TMP_10]]
+; CHECK-NEXT:    [[TMP_13:%.*]] = xor <2 x i32> [[B:%.*]], <i32 1, i32 1>
 ; CHECK-NEXT:    ret <2 x i32> [[TMP_13]]
 ;
   %tmp.4.mask = and <2 x i32> %b, <i32 1, i32 1>
@@ -446,10 +443,7 @@ define <2 x i32> @test33vec(<2 x i32> %b
 
 define <2 x i32> @test33vecb(<2 x i32> %b) {
 ; CHECK-LABEL: @test33vecb(
-; CHECK-NEXT:    [[TMP_4_MASK:%.*]] = and <2 x i32> [[B:%.*]], <i32 1, i32 1>
-; CHECK-NEXT:    [[TMP_10:%.*]] = xor <2 x i32> [[TMP_4_MASK]], <i32 1, i32 1>
-; CHECK-NEXT:    [[TMP_12:%.*]] = and <2 x i32> [[B]], <i32 -2, i32 -2>
-; CHECK-NEXT:    [[TMP_13:%.*]] = or <2 x i32> [[TMP_10]], [[TMP_12]]
+; CHECK-NEXT:    [[TMP_13:%.*]] = xor <2 x i32> [[B:%.*]], <i32 1, i32 1>
 ; CHECK-NEXT:    ret <2 x i32> [[TMP_13]]
 ;
   %tmp.4.mask = and <2 x i32> %b, <i32 1, i32 1>




More information about the llvm-commits mailing list