From d938e88e89bc01fd2ec73163159795cd86bdde10 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 4 Aug 2016 20:05:02 +0000 Subject: [PATCH] [InstCombine] use m_APInt to allow icmp eq (and X, C1), C2 folds for splat constant vectors llvm-svn: 277762 --- .../InstCombine/InstCombineCompares.cpp | 23 ++++++++----------- llvm/test/Transforms/InstCombine/and.ll | 8 ++----- llvm/test/Transforms/InstCombine/icmp.ll | 6 ++--- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 192dad0994cd..6c795db66698 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -176,12 +176,6 @@ static bool isSignTest(ICmpInst::Predicate &Pred, const ConstantInt *RHS) { return false; } -/// Return true if the constant is of the form 1+0+. This is the same as -/// lowones(~X). -static bool isHighOnes(const ConstantInt *CI) { - return (~CI->getValue() + 1).isPowerOf2(); -} - /// Given a signed integer type and a set of known zero and one bits, compute /// the maximum and minimum values that could have the specified known zero and /// known one bits, returning them in Min/Max. @@ -2288,11 +2282,11 @@ Instruction *InstCombiner::foldICmpEqualityWithConstant(ICmpInst &ICI) { } break; } - case Instruction::And: - // FIXME: Vectors are excluded by ConstantInt. - if (ConstantInt *BOC = dyn_cast(BOp1)) { + case Instruction::And: { + const APInt *BOC; + if (match(BOp1, m_APInt(BOC))) { // If we have ((X & C) == C), turn it into ((X & C) != 0). - if (RHS == BOC && RHSV->isPowerOf2()) + if (RHSV == BOC && RHSV->isPowerOf2()) return new ICmpInst(isICMP_NE ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE, BO, Constant::getNullValue(RHS->getType())); @@ -2301,7 +2295,7 @@ Instruction *InstCombiner::foldICmpEqualityWithConstant(ICmpInst &ICI) { break; // Replace (and X, (1 << size(X)-1) != 0) with x s< 0 - if (BOC->getValue().isSignBit()) { + if (BOC->isSignBit()) { Constant *Zero = Constant::getNullValue(BOp0->getType()); ICmpInst::Predicate Pred = isICMP_NE ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_SGE; @@ -2309,14 +2303,15 @@ Instruction *InstCombiner::foldICmpEqualityWithConstant(ICmpInst &ICI) { } // ((X & ~7) == 0) --> X < 8 - if (*RHSV == 0 && isHighOnes(BOC)) { - Constant *NegX = ConstantExpr::getNeg(BOC); + if (*RHSV == 0 && (~(*BOC) + 1).isPowerOf2()) { + Constant *NegBOC = ConstantExpr::getNeg(cast(BOp1)); ICmpInst::Predicate Pred = isICMP_NE ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT; - return new ICmpInst(Pred, BOp0, NegX); + return new ICmpInst(Pred, BOp0, NegBOC); } } break; + } case Instruction::Mul: if (*RHSV == 0 && BO->hasNoSignedWrap()) { // FIXME: Vectors are excluded by ConstantInt. diff --git a/llvm/test/Transforms/InstCombine/and.ll b/llvm/test/Transforms/InstCombine/and.ll index 9a6ae74cc7ec..5b48f3304959 100644 --- a/llvm/test/Transforms/InstCombine/and.ll +++ b/llvm/test/Transforms/InstCombine/and.ll @@ -196,11 +196,9 @@ define i1 @test18(i32 %A) { ret i1 %C } -; FIXME: Vectors should fold the same way. define <2 x i1> @test18_vec(<2 x i32> %A) { ; CHECK-LABEL: @test18_vec( -; CHECK-NEXT: [[B:%.*]] = and <2 x i32> %A, -; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[B]], zeroinitializer +; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i32> %A, ; CHECK-NEXT: ret <2 x i1> [[C]] ; %B = and <2 x i32> %A, @@ -218,11 +216,9 @@ define i1 @test18a(i8 %A) { ret i1 %C } -; FIXME: Vectors should fold the same way. define <2 x i1> @test18a_vec(<2 x i8> %A) { ; CHECK-LABEL: @test18a_vec( -; CHECK-NEXT: [[B:%.*]] = and <2 x i8> %A, -; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[B]], zeroinitializer +; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i8> %A, ; CHECK-NEXT: ret <2 x i1> [[C]] ; %B = and <2 x i8> %A, diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll index db84eba543e2..88cf0cdd9435 100644 --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -205,11 +205,12 @@ define i1 @test19(i32 %x) { } ; FIXME: Vectors should fold the same way. + define <2 x i1> @test19vec(<2 x i32> %x) { ; CHECK-LABEL: @test19vec( ; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> , %x ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[SHL]], -; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], +; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %shl = shl <2 x i32> , %x @@ -220,8 +221,7 @@ define <2 x i1> @test19vec(<2 x i32> %x) { define <2 x i1> @cmp_and_signbit_vec(<2 x i3> %x) { ; CHECK-LABEL: @cmp_and_signbit_vec( -; CHECK-NEXT: [[AND:%.*]] = and <2 x i3> %x, -; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i3> [[AND]], zeroinitializer +; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i3> %x, zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %and = and <2 x i3> %x,