forked from OSchip/llvm-project
InstCombine: canonicalize sext-and --> select
sext-not-and --> select. Patch by Muhammad Tauqir Ahmad. llvm-svn: 173901
This commit is contained in:
parent
4dab709484
commit
513bd8a73c
|
@ -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;
|
return Changed ? &I : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,10 @@ define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
|
||||||
%j = or i32 %g, %i
|
%j = or i32 %g, %i
|
||||||
ret i32 %j
|
ret i32 %j
|
||||||
; CHECK: %e = icmp slt i32 %a, %b
|
; CHECK: %e = icmp slt i32 %a, %b
|
||||||
; CHECK: %j = select i1 %e, i32 %c, i32 %d
|
; CHECK-NEXT: %g = select i1 %e, i32 %c, i32 0
|
||||||
; CHECK: ret i32 %j
|
; 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 {
|
define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
|
||||||
%e = icmp slt i32 %a, %b
|
%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
|
%j = or i32 %i, %g
|
||||||
ret i32 %j
|
ret i32 %j
|
||||||
; CHECK: %e = icmp slt i32 %a, %b
|
; CHECK: %e = icmp slt i32 %a, %b
|
||||||
; CHECK: %j = select i1 %e, i32 %c, i32 %d
|
; CHECK-NEXT: %g = select i1 %e, i32 %c, i32 0
|
||||||
; CHECK: ret i32 %j
|
; 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 {
|
define i32 @goo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
|
||||||
|
@ -36,8 +40,10 @@ entry:
|
||||||
%3 = or i32 %1, %2
|
%3 = or i32 %1, %2
|
||||||
ret i32 %3
|
ret i32 %3
|
||||||
; CHECK: %0 = icmp slt i32 %a, %b
|
; CHECK: %0 = icmp slt i32 %a, %b
|
||||||
; CHECK: %1 = select i1 %0, i32 %c, i32 %d
|
; CHECK-NEXT: %1 = select i1 %0, i32 %c, i32 0
|
||||||
; CHECK: ret i32 %1
|
; 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 {
|
define i32 @poo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
|
||||||
entry:
|
entry:
|
||||||
|
@ -49,8 +55,10 @@ entry:
|
||||||
%3 = or i32 %1, %2
|
%3 = or i32 %1, %2
|
||||||
ret i32 %3
|
ret i32 %3
|
||||||
; CHECK: %0 = icmp slt i32 %a, %b
|
; CHECK: %0 = icmp slt i32 %a, %b
|
||||||
; CHECK: %1 = select i1 %0, i32 %c, i32 %d
|
; CHECK-NEXT: %1 = select i1 %0, i32 %c, i32 0
|
||||||
; CHECK: ret i32 %1
|
; 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 {
|
define i32 @par(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
|
||||||
|
@ -63,6 +71,8 @@ entry:
|
||||||
%3 = or i32 %1, %2
|
%3 = or i32 %1, %2
|
||||||
ret i32 %3
|
ret i32 %3
|
||||||
; CHECK: %0 = icmp slt i32 %a, %b
|
; CHECK: %0 = icmp slt i32 %a, %b
|
||||||
; CHECK: %1 = select i1 %0, i32 %c, i32 %d
|
; CHECK-NEXT: %1 = select i1 %0, i32 %c, i32 0
|
||||||
; CHECK: ret i32 %1
|
; CHECK-NEXT: %2 = select i1 %0, i32 0, i32 %d
|
||||||
|
; CHECK-NEXT: %3 = or i32 %1, %2
|
||||||
|
; CHECK-NEXT: ret i32 %3
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,9 +138,8 @@ define i32 @test16(i32 %b, i1 %c) {
|
||||||
; e = b & (a >> 31)
|
; e = b & (a >> 31)
|
||||||
%e = mul i32 %d, %b ; <i32> [#uses=1]
|
%e = mul i32 %d, %b ; <i32> [#uses=1]
|
||||||
ret i32 %e
|
ret i32 %e
|
||||||
; CHECK: [[TEST16:%.*]] = sext i1 %c to i32
|
; CHECK: [[TEST16:%.*]] = select i1 %c, i32 %b, i32 0
|
||||||
; CHECK-NEXT: %e = and i32 %1, %b
|
; CHECK-NEXT: ret i32 [[TEST16]]
|
||||||
; CHECK-NEXT: ret i32 %e
|
|
||||||
}
|
}
|
||||||
|
|
||||||
; X * Y (when Y is 0 or 1) --> x & (0-Y)
|
; X * Y (when Y is 0 or 1) --> x & (0-Y)
|
||||||
|
|
|
@ -64,7 +64,8 @@ entry:
|
||||||
|
|
||||||
; CHECK: @test5
|
; CHECK: @test5
|
||||||
; CHECK: sext <4 x i1> %cmp to <4 x i32>
|
; 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue