diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 8a49943f52bfb..c8b3fd05a8db3 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -884,13 +884,13 @@ Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) { if (match(Op0, m_Not(m_Value(X)))) return BinaryOperator::CreateSub(InstCombiner::SubOne(Op1C), X); - // (iN X s>> (N - 1)) + 1 --> (~X) u>> (N - 1) + // (iN X s>> (N - 1)) + 1 --> zext (X > -1) const APInt *C; - if (match(Op0, m_OneUse(m_AShr(m_Value(X), m_APIntAllowUndef(C)))) && - *C == (Ty->getScalarSizeInBits() - 1) && match(Op1, m_One())) { - Value *NotX = Builder.CreateNot(X, X->getName() + ".not"); - return BinaryOperator::CreateLShr(NotX, ConstantInt::get(Ty, *C)); - } + unsigned BitWidth = Ty->getScalarSizeInBits(); + if (match(Op0, m_OneUse(m_AShr(m_Value(X), + m_SpecificIntAllowUndef(BitWidth - 1)))) && + match(Op1, m_One())) + return new ZExtInst(Builder.CreateIsNotNeg(X, "isnotneg"), Ty); if (!match(Op1, m_APInt(C))) return nullptr; diff --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll index 58d97c971db7e..486078cb9b054 100644 --- a/llvm/test/Transforms/InstCombine/add.ll +++ b/llvm/test/Transforms/InstCombine/add.ll @@ -1900,8 +1900,8 @@ define i8 @not_mul_use2(i8 %x) { define i8 @full_ashr_inc(i8 %x) { ; CHECK-LABEL: @full_ashr_inc( -; CHECK-NEXT: [[X_NOT:%.*]] = xor i8 [[X:%.*]], -1 -; CHECK-NEXT: [[R:%.*]] = lshr i8 [[X_NOT]], 7 +; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1 +; CHECK-NEXT: [[R:%.*]] = zext i1 [[ISNOTNEG]] to i8 ; CHECK-NEXT: ret i8 [[R]] ; %a = ashr i8 %x, 7 @@ -1911,8 +1911,8 @@ define i8 @full_ashr_inc(i8 %x) { define <2 x i6> @full_ashr_inc_vec(<2 x i6> %x) { ; CHECK-LABEL: @full_ashr_inc_vec( -; CHECK-NEXT: [[X_NOT:%.*]] = xor <2 x i6> [[X:%.*]], -; CHECK-NEXT: [[R:%.*]] = lshr <2 x i6> [[X_NOT]], +; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt <2 x i6> [[X:%.*]], +; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[ISNOTNEG]] to <2 x i6> ; CHECK-NEXT: ret <2 x i6> [[R]] ; %a = ashr <2 x i6> %x, diff --git a/llvm/test/Transforms/InstCombine/high-bit-signmask.ll b/llvm/test/Transforms/InstCombine/high-bit-signmask.ll index a202c43fbb5c4..86865556b6a56 100644 --- a/llvm/test/Transforms/InstCombine/high-bit-signmask.ll +++ b/llvm/test/Transforms/InstCombine/high-bit-signmask.ll @@ -116,8 +116,8 @@ define i64 @n9(i64 %x) { define i64 @n10(i64 %x) { ; CHECK-LABEL: @n10( -; CHECK-NEXT: [[X_NOT:%.*]] = xor i64 [[X:%.*]], -1 -; CHECK-NEXT: [[R:%.*]] = lshr i64 [[X_NOT]], 63 +; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i64 [[X:%.*]], -1 +; CHECK-NEXT: [[R:%.*]] = zext i1 [[ISNOTNEG]] to i64 ; CHECK-NEXT: ret i64 [[R]] ; %t0 = lshr i64 %x, 63