[InstCombine] use m_APInt to allow icmp X, C folds for splat constant vectors

Of course, we really need to refactor and fix all of the cmp predicates, 
but this one is interesting because without it, we later perform an 
information-losing transform of icmp (shl 1, Y), C, and we can't recover
the better fold.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@279263 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sanjay Patel 2016-08-19 15:40:44 +00:00
parent 3287fed753
commit ee783de739
2 changed files with 16 additions and 7 deletions

View File

@ -3622,25 +3622,30 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
Constant::getAllOnesValue(Op0->getType()));
}
break;
case ICmpInst::ICMP_UGT:
case ICmpInst::ICMP_UGT: {
if (Op0Min.ugt(Op1Max)) // A >u B -> true if min(A) > max(B)
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
if (Op0Max.ule(Op1Min)) // A >u B -> false if max(A) <= max(B)
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
if (Op1Max == Op0Min) // A >u B -> A != B if min(A) == max(B)
return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1);
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
if (Op1Min == Op0Max-1) // A >u C -> A == C+1 if max(a)-1 == C
const APInt *CmpC;
if (match(Op1, m_APInt(CmpC))) {
// A >u C -> A == C+1 if max(a)-1 == C
if (*CmpC == Op0Max - 1)
return new ICmpInst(ICmpInst::ICMP_EQ, Op0,
Builder->getInt(CI->getValue()+1));
ConstantInt::get(Op1->getType(), *CmpC + 1));
// (x >u 2147483647) -> (x <s 0) -> true if sign bit set
if (CI->isMaxValue(true))
if (CmpC->isMaxSignedValue())
return new ICmpInst(ICmpInst::ICMP_SLT, Op0,
Constant::getNullValue(Op0->getType()));
}
break;
}
case ICmpInst::ICMP_SLT:
if (Op0Max.slt(Op1Min)) // A <s B -> true if max(A) < min(C)
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));

View File

@ -1672,7 +1672,7 @@ define i1 @icmp_shl_1_V_uge_2147483648(i32 %V) {
define <2 x i1> @icmp_shl_1_V_uge_2147483648_vec(<2 x i32> %V) {
; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648_vec(
; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> <i32 1, i32 1>, %V
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[SHL]], <i32 2147483647, i32 2147483647>
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[SHL]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%shl = shl <2 x i32> <i32 1, i32 1>, %V
@ -2591,6 +2591,10 @@ define i1 @ugtMaxSignedVal(i8 %a) {
}
define <2 x i1> @ugtMaxSignedValVec(<2 x i8> %a) {
; CHECK-LABEL: @ugtMaxSignedValVec(
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> %a, zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%cmp = icmp ugt <2 x i8> %a, <i8 127, i8 127>
ret <2 x i1> %cmp
}
@ -2609,7 +2613,7 @@ define i1 @ugtKnownBits(i8 %a) {
define <2 x i1> @ugtKnownBitsVec(<2 x i8> %a) {
; CHECK-LABEL: @ugtKnownBitsVec(
; CHECK-NEXT: [[B:%.*]] = and <2 x i8> %a, <i8 17, i8 17>
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i8> [[B]], <i8 16, i8 16>
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[B]], <i8 17, i8 17>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%b = and <2 x i8> %a, <i8 17, i8 17>