InstCombine: canonicalize sext-and --> select
authorNadav Rotem <nrotem@apple.com>
Wed, 30 Jan 2013 06:35:22 +0000 (06:35 +0000)
committerNadav Rotem <nrotem@apple.com>
Wed, 30 Jan 2013 06:35:22 +0000 (06:35 +0000)
                          sext-not-and --> select.

Patch by Muhammad Tauqir Ahmad.

llvm-svn: 173901

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/logical-select.ll
llvm/test/Transforms/InstCombine/mul.ll
llvm/test/Transforms/InstCombine/vector-casts.ll

index c1e60d4..bf065fe 100644 (file)
@@ -1245,6 +1245,34 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
       }
   }
 
+  {
+    Value *X = 0;
+    bool OpsSwapped = false;
+    // Canonicalize SExt or Not to the LHS
+    if (match(Op1, m_SExt(m_Value())) ||
+        match(Op1, m_Not(m_Value()))) {
+      std::swap(Op0, Op1);
+      OpsSwapped = true;
+    }
+
+    // Fold (and (sext bool to A), B) --> (select bool, B, 0)
+    if (match(Op0, m_SExt(m_Value(X))) &&
+        X->getType()->getScalarType()->isIntegerTy(1)) {
+      Value *Zero = Constant::getNullValue(Op1->getType());
+      return SelectInst::Create(X, Op1, Zero);
+    }
+
+    // Fold (and ~(sext bool to A), B) --> (select bool, 0, B)
+    if (match(Op0, m_Not(m_SExt(m_Value(X)))) &&
+        X->getType()->getScalarType()->isIntegerTy(1)) {
+      Value *Zero = Constant::getNullValue(Op0->getType());
+      return SelectInst::Create(X, Zero, Op1);
+    }
+
+    if (OpsSwapped)
+      std::swap(Op0, Op1);
+  }
+
   return Changed ? &I : 0;
 }
 
index bb59817..07a326b 100644 (file)
@@ -10,8 +10,10 @@ define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
   %j = or i32 %g, %i
   ret i32 %j
 ; CHECK: %e = icmp slt i32 %a, %b
-; CHECK: %j = select i1 %e, i32 %c, i32 %d
-; CHECK: ret i32 %j
+; CHECK-NEXT: %g = select i1 %e, i32 %c, i32 0
+; CHECK-NEXT: %i = select i1 %e, i32 0, i32 %d
+; CHECK-NEXT: %j = or i32 %g, %i
+; CHECK-NEXT: ret i32 %j
 }
 define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
   %e = icmp slt i32 %a, %b
@@ -22,8 +24,10 @@ define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
   %j = or i32 %i, %g
   ret i32 %j
 ; CHECK: %e = icmp slt i32 %a, %b
-; CHECK: %j = select i1 %e, i32 %c, i32 %d
-; CHECK: ret i32 %j
+; CHECK-NEXT: %g = select i1 %e, i32 %c, i32 0
+; CHECK-NEXT: %i = select i1 %e, i32 0, i32 %d
+; CHECK-NEXT: %j = or i32 %i, %g
+; CHECK-NEXT: ret i32 %j
 }
 
 define i32 @goo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
@@ -36,8 +40,10 @@ entry:
   %3 = or i32 %1, %2
   ret i32 %3
 ; CHECK: %0 = icmp slt i32 %a, %b
-; CHECK: %1 = select i1 %0, i32 %c, i32 %d
-; CHECK: ret i32 %1
+; CHECK-NEXT: %1 = select i1 %0, i32 %c, i32 0
+; CHECK-NEXT: %2 = select i1 %0, i32 0, i32 %d
+; CHECK-NEXT: %3 = or i32 %1, %2
+; CHECK-NEXT: ret i32 %3
 }
 define i32 @poo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
 entry:
@@ -49,8 +55,10 @@ entry:
   %3 = or i32 %1, %2
   ret i32 %3
 ; CHECK: %0 = icmp slt i32 %a, %b
-; CHECK: %1 = select i1 %0, i32 %c, i32 %d
-; CHECK: ret i32 %1
+; CHECK-NEXT: %1 = select i1 %0, i32 %c, i32 0
+; CHECK-NEXT: %2 = select i1 %0, i32 0, i32 %d
+; CHECK-NEXT: %3 = or i32 %1, %2
+; CHECK-NEXT: ret i32 %3
 }
 
 define i32 @par(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
@@ -63,6 +71,8 @@ entry:
   %3 = or i32 %1, %2
   ret i32 %3
 ; CHECK: %0 = icmp slt i32 %a, %b
-; CHECK: %1 = select i1 %0, i32 %c, i32 %d
-; CHECK: ret i32 %1
+; CHECK-NEXT: %1 = select i1 %0, i32 %c, i32 0
+; CHECK-NEXT: %2 = select i1 %0, i32 0, i32 %d
+; CHECK-NEXT: %3 = or i32 %1, %2
+; CHECK-NEXT: ret i32 %3
 }
index 34ce088..16213b8 100644 (file)
@@ -138,9 +138,8 @@ define i32 @test16(i32 %b, i1 %c) {
         ; e = b & (a >> 31)
         %e = mul i32 %d, %b             ; <i32> [#uses=1]
         ret i32 %e
-; CHECK: [[TEST16:%.*]] = sext i1 %c to i32
-; CHECK-NEXT: %e = and i32 %1, %b
-; CHECK-NEXT: ret i32 %e
+; CHECK: [[TEST16:%.*]] = select i1 %c, i32 %b, i32 0
+; CHECK-NEXT: ret i32 [[TEST16]]
 }
 
 ; X * Y (when Y is 0 or 1) --> x & (0-Y)
index 7bbf53c..2f2990b 100644 (file)
@@ -64,7 +64,8 @@ entry:
         
 ; CHECK: @test5
 ; CHECK:   sext <4 x i1> %cmp to <4 x i32>     
-; CHECK:   sext <4 x i1> %cmp4 to <4 x i32>    
+; The sext-and pair is canonicalized to a select.
+; CHECK:   select <4 x i1> %cmp4, <4 x i32>    %sext, <4 x i32> zeroinitializer
 }