summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNadav Rotem <nrotem@apple.com>2013-01-30 06:35:22 +0000
committerNadav Rotem <nrotem@apple.com>2013-01-30 06:35:22 +0000
commitcc687faba373e6aa3cefe594bd9f3212e18617eb (patch)
treea53df8faf4e5c5121303786d1805606a54407be2
parent581126e4a1daf5e7e6203bf81769f96bea25e601 (diff)
downloadllvm-cc687faba373e6aa3cefe594bd9f3212e18617eb.tar.gz
llvm-cc687faba373e6aa3cefe594bd9f3212e18617eb.tar.bz2
llvm-cc687faba373e6aa3cefe594bd9f3212e18617eb.tar.xz
InstCombine: canonicalize sext-and --> select
sext-not-and --> select. Patch by Muhammad Tauqir Ahmad. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173901 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/InstCombine/InstCombineAndOrXor.cpp28
-rw-r--r--test/Transforms/InstCombine/logical-select.ll30
-rw-r--r--test/Transforms/InstCombine/mul.ll5
-rw-r--r--test/Transforms/InstCombine/vector-casts.ll3
4 files changed, 52 insertions, 14 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index c1e60d4c42..bf065fe817 100644
--- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -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;
}
diff --git a/test/Transforms/InstCombine/logical-select.ll b/test/Transforms/InstCombine/logical-select.ll
index bb59817a4f..07a326b47f 100644
--- a/test/Transforms/InstCombine/logical-select.ll
+++ b/test/Transforms/InstCombine/logical-select.ll
@@ -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
}
diff --git a/test/Transforms/InstCombine/mul.ll b/test/Transforms/InstCombine/mul.ll
index 34ce088e29..16213b8628 100644
--- a/test/Transforms/InstCombine/mul.ll
+++ b/test/Transforms/InstCombine/mul.ll
@@ -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)
diff --git a/test/Transforms/InstCombine/vector-casts.ll b/test/Transforms/InstCombine/vector-casts.ll
index 7bbf53c270..2f2990b7b0 100644
--- a/test/Transforms/InstCombine/vector-casts.ll
+++ b/test/Transforms/InstCombine/vector-casts.ll
@@ -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
}