summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2016-08-19 15:40:44 +0000
committerSanjay Patel <spatel@rotateright.com>2016-08-19 15:40:44 +0000
commit57b12d3876af84f1f394ab5183ec9fdfe15f45a5 (patch)
treebaa82fd2c4927d96bb45b516cfedf4b72097fb58
parente1937bb524b7c6fd07f13a1ff42bc942fc05458e (diff)
downloadbcm5719-llvm-57b12d3876af84f1f394ab5183ec9fdfe15f45a5.tar.gz
bcm5719-llvm-57b12d3876af84f1f394ab5183ec9fdfe15f45a5.zip
[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. llvm-svn: 279263
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp15
-rw-r--r--llvm/test/Transforms/InstCombine/icmp.ll8
2 files changed, 16 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 8ad53170d74..41106cdb7c0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -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()));
diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index 7aae75bc459..4a731fb108a 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -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>
OpenPOWER on IntegriCloud