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>