From f315654cc5849a9b674155d8898cad7cbd95e741 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 18 Aug 2016 20:28:54 +0000 Subject: [PATCH] [InstCombine] use m_APInt to allow icmp (trunc X, Y), C folds for splat constant vectors This is a sibling of: https://reviews.llvm.org/rL278859 https://reviews.llvm.org/rL278935 https://reviews.llvm.org/rL278945 https://reviews.llvm.org/rL279066 https://reviews.llvm.org/rL279077 https://reviews.llvm.org/rL279101 llvm-svn: 279133 --- lib/Transforms/InstCombine/InstCombineCompares.cpp | 13 ++++--------- test/Transforms/InstCombine/cast.ll | 7 +++---- test/Transforms/InstCombine/compare-signs.ll | 8 +------- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index 261c9eedf85..83064aacda8 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1538,14 +1538,9 @@ Instruction *InstCombiner::foldICmpCstShlConst(ICmpInst &I, Value *Op, Value *A, Instruction *InstCombiner::foldICmpTruncConstant(ICmpInst &Cmp, Instruction *Trunc, const APInt *C) { - // FIXME: This check restricts all folds under here to scalar types. - ConstantInt *RHS = dyn_cast(Cmp.getOperand(1)); - if (!RHS) - return nullptr; - ICmpInst::Predicate Pred = Cmp.getPredicate(); Value *X = Trunc->getOperand(0); - if (RHS->isOne() && C->getBitWidth() > 1) { + if (*C == 1 && C->getBitWidth() > 1) { // icmp slt trunc(signum(V)) 1 --> icmp slt V, 1 Value *V = nullptr; if (Pred == ICmpInst::ICMP_SLT && match(X, m_Signum(m_Value(V)))) @@ -1556,8 +1551,8 @@ Instruction *InstCombiner::foldICmpTruncConstant(ICmpInst &Cmp, if (Cmp.isEquality() && Trunc->hasOneUse()) { // Simplify icmp eq (trunc x to i8), 42 -> icmp eq x, 42|highbits if all // of the high bits truncated out of x are known. - unsigned DstBits = Trunc->getType()->getPrimitiveSizeInBits(), - SrcBits = X->getType()->getPrimitiveSizeInBits(); + unsigned DstBits = Trunc->getType()->getScalarSizeInBits(), + SrcBits = X->getType()->getScalarSizeInBits(); APInt KnownZero(SrcBits, 0), KnownOne(SrcBits, 0); computeKnownBits(X, KnownZero, KnownOne, 0, &Cmp); @@ -1566,7 +1561,7 @@ Instruction *InstCombiner::foldICmpTruncConstant(ICmpInst &Cmp, // Pull in the high bits from known-ones set. APInt NewRHS = C->zext(SrcBits); NewRHS |= KnownOne & APInt::getHighBitsSet(SrcBits, SrcBits - DstBits); - return new ICmpInst(Pred, X, Builder->getInt(NewRHS)); + return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), NewRHS)); } } diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll index 8a89bb2dd26..9837ca9eefb 100644 --- a/test/Transforms/InstCombine/cast.ll +++ b/test/Transforms/InstCombine/cast.ll @@ -356,7 +356,7 @@ define i1 @test31(i64 %A) { ret i1 %D } -; FIXME: Vectors should fold too...or not? +; FIXME: Vectors should fold too...or not? ; Does this depend on the whether the source/dest types of the trunc are legal in the data layout? define <2 x i1> @test31vec(<2 x i64> %A) { ; CHECK-LABEL: @test31vec( @@ -414,12 +414,11 @@ define i1 @test36(i32 %a) { ret i1 %d } -; FIXME: Vectors should fold too. +; FIXME: The trunc is removed, but the icmp+lshr fold is missing. define <2 x i1> @test36vec(<2 x i32> %a) { ; CHECK-LABEL: @test36vec( ; CHECK-NEXT: [[B:%.*]] = lshr <2 x i32> %a, -; CHECK-NEXT: [[C:%.*]] = trunc <2 x i32> [[B]] to <2 x i8> -; CHECK-NEXT: [[D:%.*]] = icmp eq <2 x i8> [[C]], zeroinitializer +; CHECK-NEXT: [[D:%.*]] = icmp eq <2 x i32> [[B]], zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[D]] ; %b = lshr <2 x i32> %a, diff --git a/test/Transforms/InstCombine/compare-signs.ll b/test/Transforms/InstCombine/compare-signs.ll index 7eb62fe7ad4..78ca1403063 100644 --- a/test/Transforms/InstCombine/compare-signs.ll +++ b/test/Transforms/InstCombine/compare-signs.ll @@ -107,15 +107,9 @@ define i1 @test4c(i64 %a) { ret i1 %c } -; FIXME: Vectors should fold too. define <2 x i1> @test4c_vec(<2 x i64> %a) { ; CHECK-LABEL: @test4c_vec( -; CHECK-NEXT: [[L:%.*]] = ashr <2 x i64> %a, -; CHECK-NEXT: [[NA:%.*]] = sub <2 x i64> zeroinitializer, %a -; CHECK-NEXT: [[R:%.*]] = lshr <2 x i64> [[NA]], -; CHECK-NEXT: [[SIGNUM:%.*]] = or <2 x i64> [[L]], [[R]] -; CHECK-NEXT: [[SIGNUM_TRUNC:%.*]] = trunc <2 x i64> [[SIGNUM]] to <2 x i32> -; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> [[SIGNUM_TRUNC]], +; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i64> %a, ; CHECK-NEXT: ret <2 x i1> [[C]] ; %l = ashr <2 x i64> %a,