From 643d21a62c9e4d0f26e471f9a1d94878a5171c01 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 21 Aug 2016 17:10:07 +0000 Subject: [PATCH] [InstCombine] use m_APInt to allow icmp (shl X, Y), C folds for splat constant vectors, part 4 This concludes the fixes for icmp+shl in this series: https://reviews.llvm.org/rL279339 https://reviews.llvm.org/rL279398 https://reviews.llvm.org/rL279399 llvm-svn: 279401 --- .../Transforms/InstCombine/InstCombineCompares.cpp | 23 ++++++++++------------ llvm/test/Transforms/InstCombine/icmp.ll | 5 ++--- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index b36eadf..c32821c 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2042,23 +2042,20 @@ Instruction *InstCombiner::foldICmpShlConstant(ICmpInst &Cmp, Instruction *Shl, And, Constant::getNullValue(And->getType())); } - // FIXME: This check restricts all folds under here to scalar types. - ConstantInt *RHS = dyn_cast(Cmp.getOperand(1)); - if (!RHS) - return nullptr; - - // Transform (icmp pred iM (shl iM %v, N), CI) - // -> (icmp pred i(M-N) (trunc %v iM to i(M-N)), (trunc (CI>>N)) - // Transform the shl to a trunc if (trunc (CI>>N)) has no loss and M-N. - // This enables to get rid of the shift in favor of a trunc which can be + // Transform (icmp pred iM (shl iM %v, N), C) + // -> (icmp pred i(M-N) (trunc %v iM to i(M-N)), (trunc (C>>N)) + // Transform the shl to a trunc if (trunc (C>>N)) has no loss and M-N. + // This enables us to get rid of the shift in favor of a trunc which can be // free on the target. It has the additional benefit of comparing to a // smaller constant, which will be target friendly. unsigned Amt = ShiftAmt->getLimitedValue(TypeBits - 1); if (Shl->hasOneUse() && Amt != 0 && C->countTrailingZeros() >= Amt) { - Type *NTy = IntegerType::get(Cmp.getContext(), TypeBits - Amt); - Constant *NCI = ConstantExpr::getTrunc( - ConstantExpr::getAShr(RHS, ConstantInt::get(RHS->getType(), Amt)), NTy); - return new ICmpInst(Pred, Builder->CreateTrunc(X, NTy), NCI); + Type *TruncTy = IntegerType::get(Cmp.getContext(), TypeBits - Amt); + if (X->getType()->isVectorTy()) + TruncTy = VectorType::get(TruncTy, X->getType()->getVectorNumElements()); + Constant *NewC = + ConstantInt::get(TruncTy, C->ashr(*ShiftAmt).trunc(TypeBits - Amt)); + return new ICmpInst(Pred, Builder->CreateTrunc(X, TruncTy), NewC); } return nullptr; diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll index f8f28d6..884ddbb 100644 --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -1105,11 +1105,10 @@ define i1 @icmp_shl16(i32 %x) { ret i1 %cmp } -; FIXME: Vectors should fold the same way. define <2 x i1> @icmp_shl16_vec(<2 x i32> %x) { ; CHECK-LABEL: @icmp_shl16_vec( -; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> %x, -; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[SHL]], +; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> %x to <2 x i16> +; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i16> [[TMP1]], ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %shl = shl <2 x i32> %x, -- 2.7.4