diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 43d359acabc806d..6c5918507b6e2c9 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1027,8 +1027,11 @@ Instruction *InstCombinerImpl::transformZExtICmp(ICmpInst *Cmp, ZExtInst &Zext) // If Op1C some other power of two, convert: KnownBits Known = computeKnownBits(Cmp->getOperand(0), 0, &Zext); + // Exactly 1 possible 1? But not the high-bit because that is + // canonicalized to this form. APInt KnownZeroMask(~Known.Zero); - if (KnownZeroMask.isPowerOf2()) { // Exactly 1 possible 1? + if (KnownZeroMask.isPowerOf2() && + (Zext.getType()->getScalarSizeInBits() != KnownZeroMask.logBase2() + 1)) { bool isNE = Cmp->getPredicate() == ICmpInst::ICMP_NE; uint32_t ShAmt = KnownZeroMask.logBase2(); Value *In = Cmp->getOperand(0); diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index 1fce5179af6a750..9ac1fd7731bf1aa 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -1091,10 +1091,17 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); Type *Ty = I.getType(); + Value *X; const APInt *C; + unsigned BitWidth = Ty->getScalarSizeInBits(); + + // (iN (~X) u>> (N - 1)) --> zext (X > -1) + if (match(Op0, m_OneUse(m_Not(m_Value(X)))) && + match(Op1, m_SpecificIntAllowUndef(BitWidth - 1))) + return new ZExtInst(Builder.CreateIsNotNeg(X, "isnotneg"), Ty); + if (match(Op1, m_APInt(C))) { unsigned ShAmtC = C->getZExtValue(); - unsigned BitWidth = Ty->getScalarSizeInBits(); auto *II = dyn_cast(Op0); if (II && isPowerOf2_32(BitWidth) && Log2_32(BitWidth) == ShAmtC && (II->getIntrinsicID() == Intrinsic::ctlz || @@ -1320,7 +1327,6 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) { } // Transform (x << y) >> y to x & (-1 >> y) - Value *X; if (match(Op0, m_OneUse(m_Shl(m_Value(X), m_Specific(Op1))))) { Constant *AllOnes = ConstantInt::getAllOnesValue(Ty); Value *Mask = Builder.CreateLShr(AllOnes, Op1); diff --git a/llvm/test/Transforms/InstCombine/and-xor-merge.ll b/llvm/test/Transforms/InstCombine/and-xor-merge.ll index 57d3f202c07a207..baf3248e29804d6 100644 --- a/llvm/test/Transforms/InstCombine/and-xor-merge.ll +++ b/llvm/test/Transforms/InstCombine/and-xor-merge.ll @@ -28,9 +28,9 @@ define i32 @test2(i32 %x, i32 %y, i32 %z) { define i32 @PR38781(i32 %a, i32 %b) { ; CHECK-LABEL: @PR38781( -; CHECK-NEXT: [[B_LOBIT_NOT1_DEMORGAN:%.*]] = or i32 [[B:%.*]], [[A:%.*]] -; CHECK-NEXT: [[B_LOBIT_NOT1:%.*]] = xor i32 [[B_LOBIT_NOT1_DEMORGAN]], -1 -; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[B_LOBIT_NOT1]], 31 +; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B:%.*]], [[A:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], -1 +; CHECK-NEXT: [[AND:%.*]] = zext i1 [[TMP2]] to i32 ; CHECK-NEXT: ret i32 [[AND]] ; %a.lobit = lshr i32 %a, 31 diff --git a/llvm/test/Transforms/InstCombine/icmp-mul-zext.ll b/llvm/test/Transforms/InstCombine/icmp-mul-zext.ll index 27d812a25b2a647..581f9452929fc34 100644 --- a/llvm/test/Transforms/InstCombine/icmp-mul-zext.ll +++ b/llvm/test/Transforms/InstCombine/icmp-mul-zext.ll @@ -19,10 +19,10 @@ define i32 @sterix(i32, i8, i64) { ; CHECK-NEXT: [[AND:%.*]] = and i64 [[MUL3]], [[TMP2]] ; CHECK-NEXT: [[CONV4:%.*]] = trunc i64 [[AND]] to i32 ; CHECK-NEXT: [[TOBOOL7_NOT:%.*]] = icmp eq i32 [[CONV4]], 0 -; CHECK-NEXT: [[PHITMP:%.*]] = zext i1 [[TOBOOL7_NOT]] to i32 +; CHECK-NEXT: [[PHI_CAST:%.*]] = zext i1 [[TOBOOL7_NOT]] to i32 ; CHECK-NEXT: br label [[LOR_END]] ; CHECK: lor.end: -; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[PHITMP]], [[LOR_RHS]] ] +; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[PHI_CAST]], [[LOR_RHS]] ] ; CHECK-NEXT: ret i32 [[TMP4]] ; entry: diff --git a/llvm/test/Transforms/InstCombine/lshr.ll b/llvm/test/Transforms/InstCombine/lshr.ll index 715c58c3d8b6308..2d58c53e108a0e3 100644 --- a/llvm/test/Transforms/InstCombine/lshr.ll +++ b/llvm/test/Transforms/InstCombine/lshr.ll @@ -947,8 +947,8 @@ define i32 @not_narrow_bswap(i24 %x) { define i8 @not_signbit(i8 %x) { ; CHECK-LABEL: @not_signbit( -; CHECK-NEXT: [[A:%.*]] = xor i8 [[X:%.*]], -1 -; CHECK-NEXT: [[R:%.*]] = lshr i8 [[A]], 7 +; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1 +; CHECK-NEXT: [[R:%.*]] = zext i1 [[ISNOTNEG]] to i8 ; CHECK-NEXT: ret i8 [[R]] ; %a = xor i8 %x, -1 @@ -958,8 +958,8 @@ define i8 @not_signbit(i8 %x) { define <2 x i6> @not_signbit_vec(<2 x i6> %x) { ; CHECK-LABEL: @not_signbit_vec( -; CHECK-NEXT: [[A:%.*]] = xor <2 x i6> [[X:%.*]], -; CHECK-NEXT: [[R:%.*]] = lshr <2 x i6> [[A]], +; 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 = xor <2 x i6> %x, @@ -969,8 +969,8 @@ define <2 x i6> @not_signbit_vec(<2 x i6> %x) { define i8 @not_signbit_alt_xor(i8 %x) { ; CHECK-LABEL: @not_signbit_alt_xor( -; CHECK-NEXT: [[A:%.*]] = xor i8 [[X:%.*]], -1 -; CHECK-NEXT: [[R:%.*]] = lshr i8 [[A]], 7 +; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1 +; CHECK-NEXT: [[R:%.*]] = zext i1 [[ISNOTNEG]] to i8 ; CHECK-NEXT: ret i8 [[R]] ; %a = xor i8 %x, -2 @@ -1004,9 +1004,8 @@ define i32 @not_signbit_use(i32 %x) { define i32 @not_signbit_zext(i16 %x) { ; CHECK-LABEL: @not_signbit_zext( -; CHECK-NEXT: [[A:%.*]] = xor i16 [[X:%.*]], -1 -; CHECK-NEXT: [[R:%.*]] = lshr i16 [[A]], 15 -; CHECK-NEXT: [[R2:%.*]] = zext i16 [[R]] to i32 +; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i16 [[X:%.*]], -1 +; CHECK-NEXT: [[R2:%.*]] = zext i1 [[ISNOTNEG]] to i32 ; CHECK-NEXT: ret i32 [[R2]] ; %a = xor i16 %x, -1 @@ -1017,9 +1016,8 @@ define i32 @not_signbit_zext(i16 %x) { define i8 @not_signbit_trunc(i16 %x) { ; CHECK-LABEL: @not_signbit_trunc( -; CHECK-NEXT: [[A:%.*]] = xor i16 [[X:%.*]], -1 -; CHECK-NEXT: [[R:%.*]] = lshr i16 [[A]], 15 -; CHECK-NEXT: [[R2:%.*]] = trunc i16 [[R]] to i8 +; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i16 [[X:%.*]], -1 +; CHECK-NEXT: [[R2:%.*]] = zext i1 [[ISNOTNEG]] to i8 ; CHECK-NEXT: ret i8 [[R2]] ; %a = xor i16 %x, -1 diff --git a/llvm/test/Transforms/InstCombine/negated-bitmask.ll b/llvm/test/Transforms/InstCombine/negated-bitmask.ll index fdd8e7e5b262a88..e1d3a030297b2d7 100644 --- a/llvm/test/Transforms/InstCombine/negated-bitmask.ll +++ b/llvm/test/Transforms/InstCombine/negated-bitmask.ll @@ -233,9 +233,8 @@ define i8 @neg_signbit_use2(i5 %x) { define i32 @neg_not_signbit1(i8 %x) { ; CHECK-LABEL: @neg_not_signbit1( -; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X:%.*]], -1 -; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], 7 -; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i32 +; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1 +; CHECK-NEXT: [[R:%.*]] = zext i1 [[ISNOTNEG]] to i32 ; CHECK-NEXT: ret i32 [[R]] ; %s = lshr i8 %x, 7 diff --git a/llvm/test/Transforms/InstCombine/xor.ll b/llvm/test/Transforms/InstCombine/xor.ll index 7ad8d79edd4ba83..bb956c03c612e3e 100644 --- a/llvm/test/Transforms/InstCombine/xor.ll +++ b/llvm/test/Transforms/InstCombine/xor.ll @@ -1061,8 +1061,8 @@ define i8 @not_lshr(i8 %x) { define <2 x i8> @not_lshr_vec(<2 x i8> %x) { ; CHECK-LABEL: @not_lshr_vec( -; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i8> [[X:%.*]], -; CHECK-NEXT: [[R:%.*]] = lshr <2 x i8> [[TMP1]], +; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[ISNOTNEG]] to <2 x i8> ; CHECK-NEXT: ret <2 x i8> [[R]] ; %a = lshr <2 x i8> %x, diff --git a/llvm/test/Transforms/InstCombine/zext.ll b/llvm/test/Transforms/InstCombine/zext.ll index 43e50ed1ed15b9c..430685eb73ef55c 100644 --- a/llvm/test/Transforms/InstCombine/zext.ll +++ b/llvm/test/Transforms/InstCombine/zext.ll @@ -501,10 +501,10 @@ define i8 @notneg_zext_narrower_use(i32 %x) { define i8 @disguised_signbit_clear_test(i64 %x) { ; CHECK-LABEL: @disguised_signbit_clear_test( -; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i8 -; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[TMP1]], -1 -; CHECK-NEXT: [[TMP3:%.*]] = lshr i8 [[TMP2]], 7 -; CHECK-NEXT: ret i8 [[TMP3]] +; CHECK-NEXT: [[A1:%.*]] = and i64 [[X:%.*]], 128 +; CHECK-NEXT: [[T4:%.*]] = icmp eq i64 [[A1]], 0 +; CHECK-NEXT: [[T6:%.*]] = zext i1 [[T4]] to i8 +; CHECK-NEXT: ret i8 [[T6]] ; %a1 = and i64 %x, 128 %t4 = icmp eq i64 %a1, 0