From 83601e52b862d262ebaca2aaf6111bc4ed1544ca Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 21 Jun 2018 17:51:44 +0000 Subject: [PATCH] [InstCombine] use constant pattern matchers with icmp+sext The previous code worked with vectors, but it failed when the vector constants contained undef elements. The matchers handle those cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335262 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineCasts.cpp | 23 ++++++++----------- test/Transforms/InstCombine/vec_sext.ll | 11 ++++----- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp index aa86dddf04d..42828eaeb2b 100644 --- a/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1191,22 +1191,19 @@ Instruction *InstCombiner::transformSExtICmp(ICmpInst *ICI, Instruction &CI) { if (!Op1->getType()->isIntOrIntVectorTy()) return nullptr; - if (Constant *Op1C = dyn_cast(Op1)) { + if ((Pred == ICmpInst::ICMP_SLT && match(Op1, m_ZeroInt())) || + (Pred == ICmpInst::ICMP_SGT && match(Op1, m_AllOnes()))) { // (x ashr x, 31 -> all ones if negative // (x >s -1) ? -1 : 0 -> not (ashr x, 31) -> all ones if positive - if ((Pred == ICmpInst::ICMP_SLT && Op1C->isNullValue()) || - (Pred == ICmpInst::ICMP_SGT && Op1C->isAllOnesValue())) { + Value *Sh = ConstantInt::get(Op0->getType(), + Op0->getType()->getScalarSizeInBits() - 1); + Value *In = Builder.CreateAShr(Op0, Sh, Op0->getName() + ".lobit"); + if (In->getType() != CI.getType()) + In = Builder.CreateIntCast(In, CI.getType(), true /*SExt*/); - Value *Sh = ConstantInt::get(Op0->getType(), - Op0->getType()->getScalarSizeInBits()-1); - Value *In = Builder.CreateAShr(Op0, Sh, Op0->getName() + ".lobit"); - if (In->getType() != CI.getType()) - In = Builder.CreateIntCast(In, CI.getType(), true /*SExt*/); - - if (Pred == ICmpInst::ICMP_SGT) - In = Builder.CreateNot(In, In->getName() + ".not"); - return replaceInstUsesWith(CI, In); - } + if (Pred == ICmpInst::ICMP_SGT) + In = Builder.CreateNot(In, In->getName() + ".not"); + return replaceInstUsesWith(CI, In); } if (ConstantInt *Op1C = dyn_cast(Op1)) { diff --git a/test/Transforms/InstCombine/vec_sext.ll b/test/Transforms/InstCombine/vec_sext.ll index f6f0f792c65..ea76115fc44 100644 --- a/test/Transforms/InstCombine/vec_sext.ll +++ b/test/Transforms/InstCombine/vec_sext.ll @@ -47,9 +47,8 @@ define <4 x i32> @test1(<4 x i32> %a, <4 x i32> %b) { define <2 x i32> @is_negative_undef_elt(<2 x i32> %a) { ; CHECK-LABEL: @is_negative_undef_elt( -; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[A:%.*]], -; CHECK-NEXT: [[SEXT:%.*]] = sext <2 x i1> [[CMP]] to <2 x i32> -; CHECK-NEXT: ret <2 x i32> [[SEXT]] +; CHECK-NEXT: [[A_LOBIT:%.*]] = ashr <2 x i32> [[A:%.*]], +; CHECK-NEXT: ret <2 x i32> [[A_LOBIT]] ; %cmp = icmp slt <2 x i32> %a, %sext = sext <2 x i1> %cmp to <2 x i32> @@ -59,9 +58,9 @@ define <2 x i32> @is_negative_undef_elt(<2 x i32> %a) { define <2 x i32> @is_positive_undef_elt(<2 x i32> %a) { ; CHECK-LABEL: @is_positive_undef_elt( -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[A:%.*]], -; CHECK-NEXT: [[SEXT:%.*]] = sext <2 x i1> [[CMP]] to <2 x i32> -; CHECK-NEXT: ret <2 x i32> [[SEXT]] +; CHECK-NEXT: [[A_LOBIT:%.*]] = ashr <2 x i32> [[A:%.*]], +; CHECK-NEXT: [[A_LOBIT_NOT:%.*]] = xor <2 x i32> [[A_LOBIT]], +; CHECK-NEXT: ret <2 x i32> [[A_LOBIT_NOT]] ; %cmp = icmp sgt <2 x i32> %a, %sext = sext <2 x i1> %cmp to <2 x i32>