InstCombine: canonicalize sext-and --> select

sext-not-and --> select.

Patch by Muhammad Tauqir Ahmad.

llvm-svn: 173901
This commit is contained in:
Nadav Rotem 2013-01-30 06:35:22 +00:00
parent 4dab709484
commit 513bd8a73c
4 changed files with 52 additions and 14 deletions

View 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;
}

View 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
}

View 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)

View 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
}