From 58109abe91e764be3cb8d699e2646ef13416fe3c Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 9 Sep 2016 21:59:37 +0000 Subject: [PATCH] [InstCombine] use m_APInt to allow icmp ult X, C folds for splat constant vectors llvm-svn: 281107 --- .../Transforms/InstCombine/InstCombineCompares.cpp | 21 +++++++++++++-------- llvm/test/Transforms/InstCombine/exact.ll | 9 +++------ llvm/test/Transforms/InstCombine/icmp-vec.ll | 11 ++++++++++- llvm/test/Transforms/InstCombine/icmp.ll | 1 - llvm/test/Transforms/InstCombine/pr17827.ll | 3 +-- 5 files changed, 27 insertions(+), 18 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index c8e0b33..e183b50 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3540,24 +3540,29 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { } break; } - case ICmpInst::ICMP_ULT: + case ICmpInst::ICMP_ULT: { if (Op0Max.ult(Op1Min)) // A true if max(A) < min(B) return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); if (Op0Min.uge(Op1Max)) // A false if min(A) >= max(B) return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); if (Op1Min == Op0Max) // A A != B if max(A) == min(B) return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1); - if (ConstantInt *CI = dyn_cast(Op1)) { - if (Op1Max == Op0Min+1) // A A == C-1 if min(A)+1 == C - return new ICmpInst(ICmpInst::ICMP_EQ, Op0, - Builder->getInt(CI->getValue()-1)); + const APInt *CmpC; + if (match(Op1, m_APInt(CmpC))) { + // A A == C-1 if min(A)+1 == C + if (Op1Max == Op0Min + 1) { + Constant *CMinus1 = ConstantInt::get(Op0->getType(), *CmpC - 1); + return new ICmpInst(ICmpInst::ICMP_EQ, Op0, CMinus1); + } // (x (x >s -1) -> true if sign bit clear - if (CI->isMinValue(true)) - return new ICmpInst(ICmpInst::ICMP_SGT, Op0, - Constant::getAllOnesValue(Op0->getType())); + if (CmpC->isMinSignedValue()) { + Constant *AllOnes = Constant::getAllOnesValue(Op0->getType()); + return new ICmpInst(ICmpInst::ICMP_SGT, Op0, AllOnes); + } } break; + } case ICmpInst::ICMP_UGT: { if (Op0Min.ugt(Op1Max)) // A >u B -> true if min(A) > max(B) return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType())); diff --git a/llvm/test/Transforms/InstCombine/exact.ll b/llvm/test/Transforms/InstCombine/exact.ll index cf10b70..3d1e1e4 100644 --- a/llvm/test/Transforms/InstCombine/exact.ll +++ b/llvm/test/Transforms/InstCombine/exact.ll @@ -175,10 +175,9 @@ define i1 @udiv_icmp2(i64 %X) { ret i1 %B } -; FIXME: missing vector fold for ult 1 -> eq 0 define <2 x i1> @udiv_icmp2_vec(<2 x i64> %X) { ; CHECK-LABEL: @udiv_icmp2_vec( -; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <2 x i64> %X, +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[TMP1]] ; %A = udiv exact <2 x i64> %X, @@ -196,10 +195,9 @@ define i1 @sdiv_icmp1(i64 %X) { ret i1 %B } -; FIXME: missing vector fold for ult 1 -> eq 0 define <2 x i1> @sdiv_icmp1_vec(<2 x i64> %X) { ; CHECK-LABEL: @sdiv_icmp1_vec( -; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <2 x i64> %X, +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[TMP1]] ; %A = sdiv exact <2 x i64> %X, @@ -257,10 +255,9 @@ define i1 @sdiv_icmp4(i64 %X) { ret i1 %B } -; FIXME: missing vector fold for ult 1 -> eq 0 define <2 x i1> @sdiv_icmp4_vec(<2 x i64> %X) { ; CHECK-LABEL: @sdiv_icmp4_vec( -; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <2 x i64> %X, +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[TMP1]] ; %A = sdiv exact <2 x i64> %X, diff --git a/llvm/test/Transforms/InstCombine/icmp-vec.ll b/llvm/test/Transforms/InstCombine/icmp-vec.ll index f831e2b..6b8073b 100644 --- a/llvm/test/Transforms/InstCombine/icmp-vec.ll +++ b/llvm/test/Transforms/InstCombine/icmp-vec.ll @@ -42,6 +42,15 @@ define <2 x i1> @ule(<2 x i8> %x) { ret <2 x i1> %cmp } +define <2 x i1> @ult_min_signed_value(<2 x i8> %x) { +; CHECK-LABEL: @ult_min_signed_value( +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> %x, +; CHECK-NEXT: ret <2 x i1> [[CMP]] +; + %cmp = icmp ult <2 x i8> %x, + ret <2 x i1> %cmp +} + ; Zeros are special: they're ConstantAggregateZero. define <2 x i1> @sge_zero(<2 x i8> %x) { @@ -72,7 +81,7 @@ define <2 x i1> @sle_zero(<2 x i8> %x) { define <2 x i1> @ule_zero(<2 x i8> %x) { ; CHECK-LABEL: @ule_zero( -; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> %x, +; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> %x, zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %cmp = icmp ule <2 x i8> %x, diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll index 5940715..62d1cbc 100644 --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -1377,7 +1377,6 @@ define i1 @icmp_mul_neq0(i32 %x) { ret i1 %cmp } -; FIXME: Vectors should fold the same way. define <2 x i1> @icmp_mul_neq0_vec(<2 x i32> %x) { ; CHECK-LABEL: @icmp_mul_neq0_vec( ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> %x, zeroinitializer diff --git a/llvm/test/Transforms/InstCombine/pr17827.ll b/llvm/test/Transforms/InstCombine/pr17827.ll index 67596f8..a3ed5e1 100644 --- a/llvm/test/Transforms/InstCombine/pr17827.ll +++ b/llvm/test/Transforms/InstCombine/pr17827.ll @@ -80,11 +80,10 @@ define i1 @test_shift_and_cmp_changed2(i8 %p) { ret i1 %cmp } -; FIXME: icmp ult X, 1 -> icmp eq X, 0 define <2 x i1> @test_shift_and_cmp_changed2_vec(<2 x i8> %p) { ; CHECK-LABEL: @test_shift_and_cmp_changed2_vec( ; CHECK-NEXT: [[ANDP:%.*]] = and <2 x i8> %p, -; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[ANDP]], +; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[ANDP]], zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %shlp = shl <2 x i8> %p, -- 2.7.4